From 06a80173e62651008b2f10b536590d72a3eafb07 Mon Sep 17 00:00:00 2001 From: Gaelle Braud Date: Tue, 9 Apr 2024 16:57:51 +0200 Subject: [PATCH] group call (ui to fix) + create call ui from callCreated signal --- Linphone/core/App.cpp | 19 +++++- Linphone/core/App.hpp | 2 + .../core/conference/ConferenceInfoCore.cpp | 55 +++++++++++++++--- .../core/conference/ConferenceInfoCore.hpp | 1 + .../core/conference/ConferenceInfoList.cpp | 4 ++ Linphone/main.cpp | 11 ++-- .../model/conference/ConferenceInfoModel.cpp | 8 ++- .../model/conference/ConferenceInfoModel.hpp | 1 + .../conference/ConferenceSchedulerModel.cpp | 8 +++ .../conference/ConferenceSchedulerModel.hpp | 1 + Linphone/model/tool/ToolModel.cpp | 19 +++--- Linphone/model/tool/ToolModel.hpp | 5 +- Linphone/tool/Utils.cpp | 35 ++++------- Linphone/tool/Utils.hpp | 8 +-- Linphone/view/App/CallsWindow.qml | 10 ++-- Linphone/view/App/Layout/MainLayout.qml | 4 +- Linphone/view/Item/Call/CallContactsLists.qml | 5 +- Linphone/view/Item/Contact/ContactsList.qml | 5 +- Linphone/view/Item/Meeting/MeetingList.qml | 4 +- Linphone/view/Item/TextInput.qml | 0 .../view/Layout/Contact/ContactLayout.qml | 6 +- .../Layout/Meeting/AddParticipantsLayout.qml | 58 +++++++++++++++---- Linphone/view/Page/Main/CallPage.qml | 51 ++++++++++++++-- Linphone/view/Page/Main/ContactPage.qml | 3 +- Linphone/view/Page/Main/MeetingPage.qml | 7 ++- Linphone/view/Prototype/CallPrototype.qml | 7 +-- 26 files changed, 246 insertions(+), 91 deletions(-) delete mode 100644 Linphone/view/Item/TextInput.qml diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index 6dba9174..b4c9b660 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -90,6 +90,23 @@ App::App(int &argc, char *argv[]) App::~App() { } +void App::setSelf(QSharedPointer(me)) { + mCoreModelConnection = QSharedPointer>( + new SafeConnection(me, CoreModel::getInstance()), &QObject::deleteLater); + mCoreModelConnection->makeConnectToModel(&CoreModel::callCreated, + [this](const std::shared_ptr &call) { + auto callCore = CallCore::create(call); + mCoreModelConnection->invokeToCore([this, callCore] { + auto callGui = new CallGui(callCore); + auto win = getCallsWindow(QVariant::fromValue(callGui)); + Utils::smartShowWindow(win); + qDebug() << "App : call created" << callGui; + // callGui.value ()->getCore()->lSetCameraEnabled(true); + }); + }); +} + App *App::getInstance() { return dynamic_cast(QApplication::instance()); } @@ -148,7 +165,7 @@ void App::init() { Qt::QueuedConnection); mEngine->load(url); }); - coreModel.reset(); + // coreModel.reset(); }, Qt::SingleShotConnection); // Console Commands diff --git a/Linphone/core/App.hpp b/Linphone/core/App.hpp index 53ef8c0a..2fcd3654 100644 --- a/Linphone/core/App.hpp +++ b/Linphone/core/App.hpp @@ -36,6 +36,7 @@ class App : public SingleApplication, public AbstractObject { public: App(int &argc, char *argv[]); ~App(); + void setSelf(QSharedPointer(me)); static App *getInstance(); Notifier *getNotifier() const; @@ -121,6 +122,7 @@ private: QQuickWindow *mMainWindow = nullptr; QQuickWindow *mCallsWindow = nullptr; QSharedPointer mSettings; + QSharedPointer> mCoreModelConnection; DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/conference/ConferenceInfoCore.cpp b/Linphone/core/conference/ConferenceInfoCore.cpp index 462011a5..e9c06026 100644 --- a/Linphone/core/conference/ConferenceInfoCore.cpp +++ b/Linphone/core/conference/ConferenceInfoCore.cpp @@ -44,6 +44,14 @@ ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr mTimeZoneModel = QSharedPointer(new TimeZoneModel( QTimeZone::systemTimeZone())); // Always return system timezone because this info is not stored in database. + connect(this, &ConferenceInfoCore::dateTimeChanged, [this] { + setDuration(mDateTime.secsTo(mEndDateTime) / 60.0); + setIsScheduled(mDateTime != QDateTime::currentDateTime()); + }); + connect(this, &ConferenceInfoCore::endDateTimeChanged, + [this] { setDuration(mDateTime.secsTo(mEndDateTime) / 60.0); }); + connect(this, &ConferenceInfoCore::durationChanged, [this] { setEndDateTime(mDateTime.addSecs(mDuration * 60)); }); + if (conferenceInfo) { mustBeInLinphoneThread(getClassName()); mConferenceInfoModel = Utils::makeQObject_ptr(conferenceInfo); @@ -85,8 +93,8 @@ ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr } mConferenceInfoState = LinphoneEnums::fromLinphone(conferenceInfo->getState()); } else { - mDateTime = QDateTime::currentDateTime(); - mEndDateTime = QDateTime::currentDateTime().addSecs(3600); + mDateTime = QDateTime(); + mEndDateTime = mDateTime; App::postModelSync([this]() { auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); if (defaultAccount) { @@ -100,11 +108,6 @@ ConferenceInfoCore::ConferenceInfoCore(std::shared_ptr } }); } - - connect(this, &ConferenceInfoCore::dateTimeChanged, [this] { setDuration(mDateTime.secsTo(mEndDateTime) / 60.0); }); - connect(this, &ConferenceInfoCore::endDateTimeChanged, - [this] { setDuration(mDateTime.secsTo(mEndDateTime) / 60.0); }); - connect(this, &ConferenceInfoCore::durationChanged, [this] { setEndDateTime(mDateTime.addSecs(mDuration * 60)); }); } ConferenceInfoCore::ConferenceInfoCore(const ConferenceInfoCore &conferenceInfoCore) { @@ -185,10 +188,18 @@ void ConferenceInfoCore::setSelf(QSharedPointer me) { mConfInfoModelConnection->makeConnectToModel( &ConferenceInfoModel::schedulerStateChanged, [this](linphone::ConferenceScheduler::State state) { auto confInfoState = mConferenceInfoModel->getState(); + QString uri; + if (state == linphone::ConferenceScheduler::State::Ready) + uri = mConferenceInfoModel->getConferenceScheduler()->getUri(); mConfInfoModelConnection->invokeToCore([this, state = LinphoneEnums::fromLinphone(state), - infoState = LinphoneEnums::fromLinphone(confInfoState)] { + infoState = LinphoneEnums::fromLinphone(confInfoState), + uri] { + qDebug() << "scheduler state changed" << state; setConferenceSchedulerState(state); setConferenceInfoState(infoState); + if (state == LinphoneEnums::ConferenceSchedulerState::Ready) { + setUri(uri); + } }); }); mConfInfoModelConnection->makeConnectToModel( @@ -199,6 +210,12 @@ void ConferenceInfoCore::setSelf(QSharedPointer me) { } else { // Create mCoreModelConnection = QSharedPointer>( new SafeConnection(me, CoreModel::getInstance()), &QObject::deleteLater); + mCoreModelConnection->makeConnectToModel( + &CoreModel::conferenceInfoReceived, + [this](const std::shared_ptr &core, + const std::shared_ptr &conferenceInfo) { + qDebug() << "CONF INFO RECEIVED =================="; + }); } } } @@ -359,6 +376,25 @@ void ConferenceInfoCore::addParticipant(const QString &address) { emit participantsChanged(); } +void ConferenceInfoCore::addParticipants(const QStringList &addresses) { + bool addressAdded = false; + for (auto &address : addresses) { + auto found = std::find_if(mParticipants.begin(), mParticipants.end(), [address](QVariant participant) { + return participant.toMap()["address"].toString() == address; + }); + if (found == mParticipants.end()) { + QVariantMap participant; + auto displayNameObj = Utils::getDisplayName(address); + participant["displayName"] = displayNameObj ? displayNameObj->getValue() : ""; + participant["address"] = address; + participant["role"] = (int)LinphoneEnums::ParticipantRole::Listener; + mParticipants.append(participant); + addressAdded = true; + } + } + if (addressAdded) emit participantsChanged(); +} + void ConferenceInfoCore::removeParticipant(const QString &address) { for (int i = 0; i < mParticipants.size(); ++i) { auto map = mParticipants[i].toMap(); @@ -435,6 +471,9 @@ LinphoneEnums::ConferenceSchedulerState ConferenceInfoCore::getConferenceSchedul // Datetime is in Custom (Locale/UTC/System). Convert into UTC for conference info void ConferenceInfoCore::setIsScheduled(const bool &on) { + if (!on) setDateTime(QDateTime()); + else mDateTime = QDateTime::currentDateTime(); + qDebug() << "set d ate time valid" << mDateTime.isValid(); if (mIsScheduled != on) { mIsScheduled = on; emit isScheduledChanged(); diff --git a/Linphone/core/conference/ConferenceInfoCore.hpp b/Linphone/core/conference/ConferenceInfoCore.hpp index 7e6fa073..a1a900d0 100644 --- a/Linphone/core/conference/ConferenceInfoCore.hpp +++ b/Linphone/core/conference/ConferenceInfoCore.hpp @@ -112,6 +112,7 @@ public: void setConferenceSchedulerState(LinphoneEnums::ConferenceSchedulerState state); Q_INVOKABLE void addParticipant(const QString &address); + Q_INVOKABLE void addParticipants(const QStringList &addresses); Q_INVOKABLE void removeParticipant(const QString &address); Q_INVOKABLE void removeParticipant(const int &index); Q_INVOKABLE QString getParticipantAddressAt(const int &index); diff --git a/Linphone/core/conference/ConferenceInfoList.cpp b/Linphone/core/conference/ConferenceInfoList.cpp index aa3ccf96..a9583545 100644 --- a/Linphone/core/conference/ConferenceInfoList.cpp +++ b/Linphone/core/conference/ConferenceInfoList.cpp @@ -94,6 +94,10 @@ void ConferenceInfoList::setSelf(QSharedPointer me) { qDebug() << "list: conf state changed"; lUpdate(); }); + mCoreModelConnection->makeConnectToModel( + &CoreModel::callCreated, [this](const std::shared_ptr &call) { + qDebug() << "call created" << Utils::coreStringToAppString(call->getRemoteAddress()->asString()); + }); mCoreModelConnection->makeConnectToModel( &CoreModel::conferenceInfoReceived, [this](const std::shared_ptr &core, diff --git a/Linphone/main.cpp b/Linphone/main.cpp index c10cd743..f20aaf65 100644 --- a/Linphone/main.cpp +++ b/Linphone/main.cpp @@ -28,14 +28,15 @@ int main(int argc, char *argv[]) { // Disable QML cache. Avoid malformed cache. qputenv("QML_DISABLE_DISK_CACHE", "true"); - App app(argc, argv); + auto app = QSharedPointer::create(argc, argv); + app->setSelf(app); QTranslator translator; const QStringList uiLanguages = QLocale::system().uiLanguages(); for (const QString &locale : uiLanguages) { const QString baseName = "Linphone_" + QLocale(locale).name(); if (translator.load(":/i18n/" + baseName)) { - app.installTranslator(&translator); + app->installTranslator(&translator); break; } } @@ -47,9 +48,11 @@ int main(int argc, char *argv[]) { int result = 0; do { - result = app.exec(); + result = app->exec(); } while (result == (int)App::StatusCode::gRestartCode); qWarning() << "[Main] Exiting app with the code : " << result; - app.clean(); + app->clean(); + app = nullptr; + return result; } diff --git a/Linphone/model/conference/ConferenceInfoModel.cpp b/Linphone/model/conference/ConferenceInfoModel.cpp index 4f56edf1..d160c739 100644 --- a/Linphone/model/conference/ConferenceInfoModel.cpp +++ b/Linphone/model/conference/ConferenceInfoModel.cpp @@ -100,12 +100,18 @@ QString ConferenceInfoModel::getDescription() const { return Utils::coreStringToAppString(mConferenceInfo->getSubject()); } +QString ConferenceInfoModel::getUri() const { + if (auto uriAddr = mConferenceInfo->getUri()) { + return Utils::coreStringToAppString(uriAddr->asString()); + } else return QString(); +} + std::list> ConferenceInfoModel::getParticipantInfos() const { return mConferenceInfo->getParticipantInfos(); } void ConferenceInfoModel::setDateTime(const QDateTime &date) { - mConferenceInfo->setDateTime(date.toMSecsSinceEpoch() / 1000); // toMSecsSinceEpoch() is UTC + mConferenceInfo->setDateTime(date.isValid() ? date.toMSecsSinceEpoch() / 1000 : -1); // toMSecsSinceEpoch() is UTC emit dateTimeChanged(date); } diff --git a/Linphone/model/conference/ConferenceInfoModel.hpp b/Linphone/model/conference/ConferenceInfoModel.hpp index 766f4708..ab8670e0 100644 --- a/Linphone/model/conference/ConferenceInfoModel.hpp +++ b/Linphone/model/conference/ConferenceInfoModel.hpp @@ -46,6 +46,7 @@ public: QString getOrganizerName() const; QString getOrganizerAddress() const; QString getDescription() const; + QString getUri() const; std::list> getParticipantInfos() const; void setDateTime(const QDateTime &date); diff --git a/Linphone/model/conference/ConferenceSchedulerModel.cpp b/Linphone/model/conference/ConferenceSchedulerModel.cpp index a5baa661..1ca2cdd4 100644 --- a/Linphone/model/conference/ConferenceSchedulerModel.cpp +++ b/Linphone/model/conference/ConferenceSchedulerModel.cpp @@ -23,6 +23,7 @@ #include #include "model/core/CoreModel.hpp" +#include "tool/Utils.hpp" DEFINE_ABSTRACT_OBJECT(ConferenceSchedulerModel) @@ -39,6 +40,13 @@ ConferenceSchedulerModel::~ConferenceSchedulerModel() { mustBeInLinphoneThread("~" + getClassName()); } +QString ConferenceSchedulerModel::getUri() { + auto uriAddr = mMonitor->getInfo() ? mMonitor->getInfo()->getUri() : nullptr; + if (uriAddr) { + return Utils::coreStringToAppString(uriAddr->asString()); + } else return QString(); +} + void ConferenceSchedulerModel::setInfo(const std::shared_ptr &confInfo) { mMonitor->setInfo(confInfo); } diff --git a/Linphone/model/conference/ConferenceSchedulerModel.hpp b/Linphone/model/conference/ConferenceSchedulerModel.hpp index a765fe87..4723f912 100644 --- a/Linphone/model/conference/ConferenceSchedulerModel.hpp +++ b/Linphone/model/conference/ConferenceSchedulerModel.hpp @@ -38,6 +38,7 @@ public: QObject *parent = nullptr); ~ConferenceSchedulerModel(); + QString getUri(); void setInfo(const std::shared_ptr &confInfo); void cancelConference(const std::shared_ptr &confInfo); diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp index af77c585..0c9976a8 100644 --- a/Linphone/model/tool/ToolModel.cpp +++ b/Linphone/model/tool/ToolModel.cpp @@ -93,11 +93,12 @@ QString ToolModel::getDisplayName(QString address) { return displayName.isEmpty() ? address : displayName; } -QSharedPointer ToolModel::createCall(const QString &sipAddress, - const QVariantMap &options, - const QString &prepareTransfertAddress, - const QHash &headers, - linphone::MediaEncryption mediaEncryption) { +bool ToolModel::createCall(const QString &sipAddress, + const QVariantMap &options, + const QString &prepareTransfertAddress, + const QHash &headers, + linphone::MediaEncryption mediaEncryption, + QString *errorMessage) { bool waitRegistrationForCall = true; // getSettingsModel()->getWaitRegistrationForCall() std::shared_ptr core = CoreModel::getInstance()->getCore(); bool cameraEnabled = options.contains("cameraEnabled") ? options["cameraEnabled"].toBool() : false; @@ -106,7 +107,11 @@ QSharedPointer ToolModel::createCall(const QString &sipAddress, if (!address) { qCritical() << "[" + QString(gClassName) + "] The calling address is not an interpretable SIP address: " << sipAddress; - return nullptr; + if (errorMessage) { + *errorMessage = tr("The calling address is not an interpretable SIP address : "); + errorMessage->append(sipAddress); + } + return false; } std::shared_ptr params = core->createCallParams(nullptr); @@ -133,7 +138,7 @@ QSharedPointer ToolModel::createCall(const QString &sipAddress, if (core->getDefaultAccount()) params->setAccount(core->getDefaultAccount()); auto call = core->inviteAddressWithParams(address, params); call->enableCamera(cameraEnabled); - return call ? CallCore::create(call) : nullptr; + return call != nullptr; /* TODO transfer diff --git a/Linphone/model/tool/ToolModel.hpp b/Linphone/model/tool/ToolModel.hpp index 68cc7222..b33d08b1 100644 --- a/Linphone/model/tool/ToolModel.hpp +++ b/Linphone/model/tool/ToolModel.hpp @@ -46,11 +46,12 @@ public: static QString getDisplayName(const std::shared_ptr &address); static QString getDisplayName(QString address); - static QSharedPointer createCall(const QString &sipAddress, + static bool createCall(const QString &sipAddress, const QVariantMap &options = {}, const QString &prepareTransfertAddress = "", const QHash &headers = {}, - linphone::MediaEncryption = linphone::MediaEncryption::None); + linphone::MediaEncryption = linphone::MediaEncryption::None, + QString *errorMessage = nullptr); private: DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index f4b1b0a2..56dfa9a3 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -94,32 +94,19 @@ QString Utils::getInitials(const QString &username) { return QLocale().toUpper(initials.join("")); } -VariantObject *Utils::createCall(QString sipAddress, - QVariantMap options, - QString prepareTransfertAddress, - QHash headers) { - VariantObject *data = new VariantObject(QVariant()); // Scope : GUI - if (!data) return nullptr; - data->makeRequest([sipAddress, options, prepareTransfertAddress, headers]() { - auto call = ToolModel::createCall(sipAddress, options, prepareTransfertAddress, headers); - if (call) { - auto callGui = QVariant::fromValue(new CallGui(call)); - App::postCoreSync([callGui]() { - auto app = App::getInstance(); - auto window = app->getCallsWindow(callGui); - smartShowWindow(window); - qDebug() << "Utils : call created" << callGui; - // callGui.value()->getCore()->lSetCameraEnabled(true); - }); - return callGui; - } else { - qDebug() << "Utils : failed to create call"; - return QVariant(); +void Utils::createCall(const QString &sipAddress, + QVariantMap options, + const QString &prepareTransfertAddress, + const QHash &headers) { + App::postModelAsync([sipAddress, options, prepareTransfertAddress, headers]() { + QString errorMessage; + bool success = ToolModel::createCall(sipAddress, options, prepareTransfertAddress, headers, + linphone::MediaEncryption::None, &errorMessage); + if (!success) { + if (errorMessage.isEmpty()) errorMessage = tr("L'appel n'a pas pu être créé"); + showInformationPopup("Erreur", errorMessage, false); } }); - data->requestValue(); - - return data; } void Utils::setupConference(ConferenceInfoGui *confGui) { diff --git a/Linphone/tool/Utils.hpp b/Linphone/tool/Utils.hpp index 56a3db23..9298b73b 100644 --- a/Linphone/tool/Utils.hpp +++ b/Linphone/tool/Utils.hpp @@ -58,10 +58,10 @@ public: Q_INVOKABLE static QString getFamilyNameFromFullName(const QString &fullName); Q_INVOKABLE static QString getInitials(const QString &username); // Support UTF32 - Q_INVOKABLE static VariantObject *createCall(QString sipAddress, - QVariantMap options = {}, - QString prepareTransfertAddress = "", - QHash headers = {}); + Q_INVOKABLE static void createCall(const QString &sipAddress, + QVariantMap options = {}, + const QString &prepareTransfertAddress = "", + const QHash &headers = {}); Q_INVOKABLE static void openCallsWindow(CallGui *call); Q_INVOKABLE static void setupConference(ConferenceInfoGui *confGui); Q_INVOKABLE static void setCallsWindowCall(CallGui *call); diff --git a/Linphone/view/App/CallsWindow.qml b/Linphone/view/App/CallsWindow.qml index 9430ecab..3a5253ea 100644 --- a/Linphone/view/App/CallsWindow.qml +++ b/Linphone/view/App/CallsWindow.qml @@ -32,12 +32,11 @@ Window { && (!conferenceInfo || conference) ) middleItemStackView.replace(inCallItem) } - property var callObj function joinConference(options) { if (!conferenceInfo || conferenceInfo.core.uri.length === 0) UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence n'a pas pu démarrer en raison d'une erreur d'uri."), mainWindow) else { - callObj = UtilsCpp.createCall(conferenceInfo.core.uri, options) + UtilsCpp.createCall(conferenceInfo.core.uri, options) } } @@ -462,14 +461,13 @@ Window { Layout.fillWidth: true Layout.preferredHeight: numPad.height Layout.topMargin: 10 * DefaultStyle.dp - property var callObj NumericPad { id: numPad width: parent.width visible: parent.visible closeButtonVisible: false onLaunchCall: { - callObj = UtilsCpp.createCall(dialerTextInput.text + "@sip.linphone.org") + UtilsCpp.createCall(dialerTextInput.text + "@sip.linphone.org") } } } @@ -754,6 +752,10 @@ Window { } participantsStack.selectedParticipants = selectedParticipants } + onValidateRequested: { + conferenceInfoGui.core.resetParticipants(contactList.selectedContacts) + returnRequested() + } Connections { target: participantsStack onCurrentItemChanged: { diff --git a/Linphone/view/App/Layout/MainLayout.qml b/Linphone/view/App/Layout/MainLayout.qml index 16c41a7e..e38cbac0 100644 --- a/Linphone/view/App/Layout/MainLayout.qml +++ b/Linphone/view/App/Layout/MainLayout.qml @@ -232,7 +232,7 @@ Item { source: AppIcons.phone } onClicked: { - mainItem.callObj = UtilsCpp.createCall(sipAddr.text) + UtilsCpp.createCall(sipAddr.text) } } Button { @@ -245,7 +245,7 @@ Item { height: 24 * DefaultStyle.dp source: AppIcons.videoCamera } - onClicked: mainItem.callObj = UtilsCpp.createCall(sipAddr.text, {'cameraEnabled':true}) + onClicked: UtilsCpp.createCall(sipAddr.text, {'cameraEnabled':true}) } } Button { diff --git a/Linphone/view/Item/Call/CallContactsLists.qml b/Linphone/view/Item/Call/CallContactsLists.qml index e547f4b3..f284e790 100644 --- a/Linphone/view/Item/Call/CallContactsLists.qml +++ b/Linphone/view/Item/Call/CallContactsLists.qml @@ -14,6 +14,7 @@ Item { property color searchBarColor: DefaultStyle.grey_100 property color searchBarBorderColor: "transparent" signal callButtonPressed(string address) + signal groupCallCreationRequested() clip: true Popup { @@ -198,6 +199,7 @@ Item { Layout.preferredHeight: 24 * DefaultStyle.dp } } + onClicked: mainItem.groupCallCreationRequested() } // RowLayout { @@ -333,9 +335,8 @@ Item { NumericPad { id: numPad width: parent.width - property var callObj onLaunchCall: { - callObj = UtilsCpp.createCall(searchBar.text + "@sip.linphone.org") + UtilsCpp.createCall(searchBar.text + "@sip.linphone.org") // TODO : auto completion instead of sip linphone } } diff --git a/Linphone/view/Item/Contact/ContactsList.qml b/Linphone/view/Item/Contact/ContactsList.qml index a0a247ce..89b3c560 100644 --- a/Linphone/view/Item/Contact/ContactsList.qml +++ b/Linphone/view/Item/Contact/ContactsList.qml @@ -144,7 +144,6 @@ ListView { anchors.rightMargin: 10 * DefaultStyle.dp anchors.verticalCenter: parent.verticalCenter RowLayout{ - property var callObj visible: mainItem.actionLayoutVisible spacing: 10 * DefaultStyle.dp Button { @@ -157,7 +156,7 @@ ListView { height: 24 * DefaultStyle.dp source: AppIcons.phone } - onClicked: callObj = UtilsCpp.createCall(modelData.core.defaultAddress) + onClicked: UtilsCpp.createCall(modelData.core.defaultAddress) } Button { Layout.preferredWidth: 24 * DefaultStyle.dp @@ -169,7 +168,7 @@ ListView { height: 24 * DefaultStyle.dp source: AppIcons.videoCamera } - onClicked: callObj = UtilsCpp.createCall(modelData.core.defaultAddress, {'cameraEnabled':true}) + onClicked: UtilsCpp.createCall(modelData.core.defaultAddress, {'cameraEnabled':true}) } } PopupButton { diff --git a/Linphone/view/Item/Meeting/MeetingList.qml b/Linphone/view/Item/Meeting/MeetingList.qml index 50914fe3..cea0e488 100644 --- a/Linphone/view/Item/Meeting/MeetingList.qml +++ b/Linphone/view/Item/Meeting/MeetingList.qml @@ -102,14 +102,14 @@ ListView { radius: height/2 property var isCurrentDay: UtilsCpp.isCurrentDay(dateTime) - color: !isCurrentDay ? DefaultStyle.main1_500_main : "transparent" + color: isCurrentDay ? DefaultStyle.main1_500_main : "transparent" Component.onCompleted: if(isCurrentDay) mainItem.currentIndex = index Text { id: dayNumText anchors.centerIn: parent verticalAlignment: Text.AlignVCenter text: UtilsCpp.toDateDayString(dateTime) - color: !dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500main + color: dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500main wrapMode: Text.NoWrap font { pixelSize: 20 * DefaultStyle.dp diff --git a/Linphone/view/Item/TextInput.qml b/Linphone/view/Item/TextInput.qml deleted file mode 100644 index e69de29b..00000000 diff --git a/Linphone/view/Layout/Contact/ContactLayout.qml b/Linphone/view/Layout/Contact/ContactLayout.qml index 41544931..f975f3d6 100644 --- a/Linphone/view/Layout/Contact/ContactLayout.qml +++ b/Linphone/view/Layout/Contact/ContactLayout.qml @@ -126,10 +126,9 @@ ColumnLayout { button.icon.height: 24 * DefaultStyle.dp button.icon.source: AppIcons.phone label: qsTr("Appel") - property var callObj button.onClicked: { var addr = UtilsCpp.generateLinphoneSipAddress(mainItem.contactAddress) - callObj = UtilsCpp.createCall(addr) + UtilsCpp.createCall(addr) } } LabelButton { @@ -151,10 +150,9 @@ ColumnLayout { button.icon.height: 24 * DefaultStyle.dp button.icon.source: AppIcons.videoCamera label: qsTr("Appel Video") - property var callObj button.onClicked: { var addr = UtilsCpp.generateLinphoneSipAddress(mainItem.contactAddress) - callObj = UtilsCpp.createCall(addr) + UtilsCpp.createCall(addr) console.log("[CallPage.qml] TODO : enable video") } } diff --git a/Linphone/view/Layout/Meeting/AddParticipantsLayout.qml b/Linphone/view/Layout/Meeting/AddParticipantsLayout.qml index 2e0dde16..84ce7b11 100644 --- a/Linphone/view/Layout/Meeting/AddParticipantsLayout.qml +++ b/Linphone/view/Layout/Meeting/AddParticipantsLayout.qml @@ -7,6 +7,7 @@ import UtilsCpp 1.0 ColumnLayout { id: mainItem + spacing: 10 * DefaultStyle.dp property string title property string validateButtonText property string placeHolderText: qsTr("Rechercher des contacts") @@ -15,7 +16,10 @@ ColumnLayout { property int selectedParticipantsCount: selectedParticipants.length property alias titleLayout: titleLayout property ConferenceInfoGui conferenceInfoGui + property bool nameGroupCall: false + readonly property string groupName: groupCallName.text signal returnRequested() + signal validateRequested() // Layout.preferredWidth: 362 * DefaultStyle.dp function clearSelectedParticipants() { @@ -35,15 +39,28 @@ ColumnLayout { icon.height: 24 * DefaultStyle.dp onClicked: mainItem.returnRequested() } - Text { - text: mainItem.title - color: mainItem.titleColor - maximumLineCount: 1 - font { - pixelSize: 18 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp + ColumnLayout { + spacing: 0 + Text { + text: mainItem.title + color: mainItem.titleColor + maximumLineCount: 1 + font { + pixelSize: 18 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp + } + Layout.fillWidth: true + } + Text { + text: qsTr("%1 participant%2 sélectionné").arg(mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount > 1 ? "s" : "") + color: DefaultStyle.main2_500main + maximumLineCount: 1 + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp + } + Layout.fillWidth: true } - Layout.fillWidth: true } Button { Layout.preferredWidth: 70 * DefaultStyle.dp @@ -55,11 +72,32 @@ ColumnLayout { text: mainItem.validateButtonText textSize: 13 * DefaultStyle.dp onClicked: { - mainItem.conferenceInfoGui.core.resetParticipants(contactList.selectedContacts) - mainItem.returnRequested() + mainItem.validateRequested() } } } + ColumnLayout { + visible: mainItem.nameGroupCall + spacing: 0 + RowLayout { + Text { + font.pixelSize: 13 * DefaultStyle.dp + font.weight: 700 * DefaultStyle.dp + text: qsTr("Nom du groupe") + } + Item{Layout.fillWidth: true} + Text { + font.pixelSize: 12 * DefaultStyle.dp + font.weight: 300 * DefaultStyle.dp + text: qsTr("Requis") + } + } + TextField { + id: groupCallName + Layout.fillWidth: true + Layout.preferredHeight: 49 * DefaultStyle.dp + } + } ListView { id: participantList Layout.fillWidth: true diff --git a/Linphone/view/Page/Main/CallPage.qml b/Linphone/view/Page/Main/CallPage.qml index 86c7a6f0..47647f8c 100644 --- a/Linphone/view/Page/Main/CallPage.qml +++ b/Linphone/view/Page/Main/CallPage.qml @@ -12,9 +12,20 @@ AbstractMainPage { newItemIconSource: AppIcons.newCall property var selectedRowHistoryGui - signal listViewUpdated() + property ConferenceInfoGui confInfoGui + + Connections { + enabled: confInfoGui + target: confInfoGui ? confInfoGui.core : null + onConferenceSchedulerStateChanged: { + if (confInfoGui.core.schedulerState === LinphoneEnums.ConferenceSchedulerState.Ready) { + listStackView.pop() + } + } + } + onSelectedRowHistoryGuiChanged: { if (selectedRowHistoryGui) rightPanelStackView.replace(contactDetailComp, Control.StackView.Immediate) else rightPanelStackView.replace(emptySelection, Control.StackView.Immediate) @@ -53,6 +64,7 @@ AbstractMainPage { property int leftMargin: 45 * DefaultStyle.dp property int rightMargin: 39 * DefaultStyle.dp } + Component { id: historyListItem @@ -260,7 +272,6 @@ AbstractMainPage { Button { Layout.rightMargin: 5 * DefaultStyle.dp padding: 0 - property var callObj background: Item { visible: false } @@ -271,7 +282,7 @@ AbstractMainPage { icon.height: 24 * DefaultStyle.dp onClicked: { var addr = UtilsCpp.generateLinphoneSipAddress(modelData.core.remoteAddress) - callObj = UtilsCpp.createCall(addr) + UtilsCpp.createCall(addr) } } } @@ -319,6 +330,7 @@ AbstractMainPage { active: true policy: Control.ScrollBar.AlwaysOn //Control.ScrollBar.AsNeeded Layout.fillHeight: true + Layout.rightMargin: 8 * DefaultStyle.dp Rectangle{// TODO: change colors of scrollbar! anchors.fill: parent color: 'red' @@ -364,15 +376,44 @@ AbstractMainPage { Layout.fillHeight: true groupCallVisible: true searchBarColor: DefaultStyle.grey_100 - property var callObj onCallButtonPressed: (address) => { - callObj = UtilsCpp.createCall(UtilsCpp.generateLinphoneSipAddress(address)) + UtilsCpp.createCall(UtilsCpp.generateLinphoneSipAddress(address)) // var window = UtilsCpp.getCallsWindow() } + onGroupCallCreationRequested: { + console.log("groupe call requetsed") + listStackView.push(groupCallItem) + } } } } + Component { + id: groupCallItem + // RowLayout { + AddParticipantsLayout { + Control.StackView.onActivated: mainItem.confInfoGui = Qt.createQmlObject('import Linphone + ConferenceInfoGui{ + }', mainItem) + Layout.leftMargin: 21 * DefaultStyle.dp + title: qsTr("Appel de groupe") + titleColor: DefaultStyle.main1_500_main + nameGroupCall: true + validateButtonText: qsTr("Lancer") + onReturnRequested: listStackView.pop() + onValidateRequested: { + if (groupName.length === 0) { + UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Un nom doit être donné à l'appel de groupe"), false) + } else { + mainItem.confInfoGui.core.subject = groupName + mainItem.confInfoGui.core.isScheduled = false + mainItem.confInfoGui.core.addParticipants(selectedParticipants) + mainItem.confInfoGui.core.save() + } + } + } + // } + } } Component{ diff --git a/Linphone/view/Page/Main/ContactPage.qml b/Linphone/view/Page/Main/ContactPage.qml index 77a29eb8..797161a3 100644 --- a/Linphone/view/Page/Main/ContactPage.qml +++ b/Linphone/view/Page/Main/ContactPage.qml @@ -331,14 +331,13 @@ AbstractMainPage { background: Item{} Layout.preferredWidth: 24 * DefaultStyle.dp Layout.preferredHeight: 24 * DefaultStyle.dp - property var callObj icon.source: AppIcons.phone width: 24 * DefaultStyle.dp height: 24 * DefaultStyle.dp icon.width: 24 * DefaultStyle.dp icon.height: 24 * DefaultStyle.dp onClicked: { - callObj = UtilsCpp.createCall(modelData.address) + UtilsCpp.createCall(modelData.address) } } } diff --git a/Linphone/view/Page/Main/MeetingPage.qml b/Linphone/view/Page/Main/MeetingPage.qml index 4b266580..76abd1c5 100644 --- a/Linphone/view/Page/Main/MeetingPage.qml +++ b/Linphone/view/Page/Main/MeetingPage.qml @@ -275,6 +275,10 @@ AbstractMainPage { onReturnRequested: { container.pop() } + onValidateRequested: { + conferenceInfoGui.core.resetParticipants(addParticipantLayout.selectedParticipants) + returnRequested() + } } } Component { @@ -379,9 +383,8 @@ AbstractMainPage { inversedColors: true color: DefaultStyle.main2_600 background: Item{} - property var callObj onClicked: { - callObj = UtilsCpp.createCall(mainItem.selectedConference.core.uri) + UtilsCpp.createCall(mainItem.selectedConference.core.uri) } } Button { diff --git a/Linphone/view/Prototype/CallPrototype.qml b/Linphone/view/Prototype/CallPrototype.qml index cc70c140..c2e38d5c 100644 --- a/Linphone/view/Prototype/CallPrototype.qml +++ b/Linphone/view/Prototype/CallPrototype.qml @@ -5,13 +5,12 @@ import Linphone import UtilsCpp 1.0 // Snippet -Window{ +Window { id: mainItem height: 400 width: 800 onWidthChanged: console.log(width) - property var callVarObject - property var call: callVarObject ? callVarObject.value : null + property var call property var callState: call && call.core.state onCallStateChanged: { console.log("State:" +callState) @@ -138,7 +137,7 @@ Window{ onClicked: { var address = usernameToCall.text + "@sip.linphone.org" console.log("Calling "+address) - mainItem.callVarObject = UtilsCpp.createCall(address) + UtilsCpp.createCall(address) proto.component1 = comp } }