From 3debdf4bb53686cda39d0f9ca71996a0c12ba29b Mon Sep 17 00:00:00 2001 From: Gaelle Braud Date: Sat, 7 Sep 2024 12:01:32 +0200 Subject: [PATCH] FIXES: fix account list singleton fix magic search list thread connection fix allow calling a connected account fix magic search flags fix crash on close settings destruction magic search thread meeeting fix time zone rename settingscore remove settings from notifier fix zrtp appearance received call remove deprecated function; TODO : send invitations when sdk updated --- Linphone/core/App.cpp | 46 ++-- Linphone/core/App.hpp | 9 +- Linphone/core/account/AccountList.cpp | 2 + Linphone/core/account/AccountList.hpp | 1 + Linphone/core/account/AccountProxy.cpp | 21 +- Linphone/core/account/AccountProxy.hpp | 4 +- Linphone/core/call/CallList.cpp | 1 + Linphone/core/call/CallProxy.cpp | 21 +- Linphone/core/call/CallProxy.hpp | 3 +- .../core/conference/ConferenceInfoCore.cpp | 1 + .../core/conference/ConferenceInfoCore.hpp | 1 + Linphone/core/notifier/Notifier.cpp | 8 +- Linphone/core/notifier/Notifier.hpp | 3 +- .../core/participant/ParticipantProxy.cpp | 24 -- .../core/participant/ParticipantProxy.hpp | 2 - Linphone/core/search/MagicSearchList.cpp | 118 ++++----- Linphone/core/search/MagicSearchList.hpp | 5 +- Linphone/core/search/MagicSearchProxy.cpp | 24 +- Linphone/core/search/MagicSearchProxy.hpp | 2 + Linphone/core/setting/SettingsCore.cpp | 138 +++++------ Linphone/core/setting/SettingsCore.hpp | 16 +- Linphone/core/timezone/TimeZoneList.cpp | 25 +- Linphone/core/timezone/TimeZoneList.hpp | 1 + Linphone/model/call/CallModel.hpp | 2 +- .../model/conference/ConferenceInfoModel.cpp | 3 +- Linphone/model/tool/ToolModel.cpp | 7 - Linphone/view/App/CallsWindow.qml | 11 +- Linphone/view/App/Layout/MainLayout.qml | 7 +- Linphone/view/App/Main.qml | 5 +- Linphone/view/Item/Account/Accounts.qml | 5 +- Linphone/view/Item/Call/CallContactsLists.qml | 5 +- Linphone/view/Item/Call/WaitingRoom.qml | 3 +- Linphone/view/Item/ComboBox.qml | 8 +- Linphone/view/Item/Contact/ContactEdition.qml | 2 +- Linphone/view/Item/Contact/ContactsList.qml | 229 +++++++++--------- Linphone/view/Item/Contact/Sticker.qml | 2 +- Linphone/view/Item/Dialog.qml | 4 +- .../Notification/NotificationReceivedCall.qml | 2 +- Linphone/view/Item/NumericPad.qml | 18 +- .../view/Layout/Call/ActiveSpeakerLayout.qml | 5 +- Linphone/view/Layout/Call/GridLayout.qml | 4 +- .../view/Page/Main/AccountSettingsPage.qml | 3 +- Linphone/view/Page/Main/CallPage.qml | 3 +- Linphone/view/Page/Main/MeetingPage.qml | 12 +- Linphone/view/Prototype/AccountsPrototype.qml | 3 +- Linphone/view/Prototype/CallPrototype.qml | 13 +- external/linphone-sdk | 2 +- 47 files changed, 458 insertions(+), 376 deletions(-) diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index cbbd1b4a1..6f3f070ac 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -38,7 +38,6 @@ #include "core/account/AccountCore.hpp" #include "core/account/AccountDeviceGui.hpp" #include "core/account/AccountDeviceProxy.hpp" -#include "core/account/AccountProxy.hpp" #include "core/address-books/LdapGui.hpp" #include "core/address-books/LdapProxy.hpp" #include "core/call-history/CallHistoryProxy.hpp" @@ -415,10 +414,11 @@ void App::initCore() { mLinphoneThread->getThreadId(), [this]() mutable { CoreModel::getInstance()->start(); - auto settings = Settings::create(); - QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings]() mutable { + auto settings = SettingsCore::create(); + QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings] { // QML mEngine = new QQmlApplicationEngine(this); + assert(mEngine); // Provide `+custom` folders for custom components and `5.9` for old components. QStringList selectors("custom"); const QVersionNumber &version = QLibraryInfo::version(); @@ -460,9 +460,11 @@ void App::initCore() { mEngine->addImageProvider(WindowIconProvider::ProviderId, new WindowIconProvider()); // Enable notifications. - mNotifier = new Notifier(mEngine, settings); + mNotifier = new Notifier(mEngine); mSettings = settings; - settings.reset(); + mEngine->setObjectOwnership(mSettings.get(), QQmlEngine::CppOwnership); + mAccountList = AccountList::create(); + mCallList = CallList::create(); const QUrl url(u"qrc:/Linphone/view/App/Main.qml"_qs); QObject::connect( @@ -479,7 +481,7 @@ void App::initCore() { } }, Qt::QueuedConnection); - QObject::connect(mSettings.get(), &Settings::autoStartChanged, [this]() { + QObject::connect(mSettings.get(), &SettingsCore::autoStartChanged, [this]() { mustBeInMainThread(log().arg(Q_FUNC_INFO)); setAutoStart(mSettings->getAutoStart()); }); @@ -515,9 +517,15 @@ void App::initCppInterfaces() { "EnumsToStringCpp", 1, 0, "EnumsToStringCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * { return new EnumsToString(engine); }); - qmlRegisterSingletonType( + qmlRegisterSingletonType( "SettingsCpp", 1, 0, "SettingsCpp", [this](QQmlEngine *engine, QJSEngine *) -> QObject * { return mSettings.get(); }); + qmlRegisterSingletonType( + "LinphoneAccountsCpp", 1, 0, "LinphoneAccountsCpp", + [this](QQmlEngine *engine, QJSEngine *) -> QObject * { return mAccountList.get(); }); + qmlRegisterSingletonType( + "LinphoneCallsCpp", 1, 0, "LinphoneCallsCpp", + [this](QQmlEngine *engine, QJSEngine *) -> QObject * { return mCallList.get(); }); qmlRegisterType(Constants::MainQmlUri, 1, 0, "PhoneNumberProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "VariantObject"); @@ -530,15 +538,15 @@ void App::initCppInterfaces() { qmlRegisterType(Constants::MainQmlUri, 1, 0, "PhoneNumberProxy"); qmlRegisterUncreatableType(Constants::MainQmlUri, 1, 0, "PhoneNumber", QLatin1String("Uncreatable")); - qmlRegisterType(Constants::MainQmlUri, 1, 0, "AccountProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "AccountGui"); + qmlRegisterType(Constants::MainQmlUri, 1, 0, "AccountProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "AccountDeviceProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "AccountDeviceGui"); qmlRegisterUncreatableType(Constants::MainQmlUri, 1, 0, "AccountCore", QLatin1String("Uncreatable")); qmlRegisterUncreatableType(Constants::MainQmlUri, 1, 0, "CallCore", QLatin1String("Uncreatable")); - qmlRegisterType(Constants::MainQmlUri, 1, 0, "CallProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "CallHistoryProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "CallGui"); + qmlRegisterType(Constants::MainQmlUri, 1, 0, "CallProxy"); qmlRegisterUncreatableType(Constants::MainQmlUri, 1, 0, "ConferenceCore", QLatin1String("Uncreatable")); qmlRegisterType(Constants::MainQmlUri, 1, 0, "ConferenceGui"); @@ -573,14 +581,10 @@ void App::initCppInterfaces() { //------------------------------------------------------------ void App::clean() { - if (mSettings) mSettings.reset(); - // Wait 500ms to let time for log te be stored. - // mNotifier destroyed in mEngine deletion as it is its parent delete mEngine; mEngine = nullptr; - // if (mSettings) { - // mSettings.reset(); - // } + // Wait 500ms to let time for log te be stored. + // mNotifier destroyed in mEngine deletion as it is its parent qApp->processEvents(QEventLoop::AllEvents, 500); if (mLinphoneThread) { mLinphoneThread->exit(); @@ -725,6 +729,18 @@ void App::setMainWindow(QQuickWindow *data) { } } +QSharedPointer App::getAccountList() const { + return mAccountList; +} + +QSharedPointer App::getCallList() const { + return mCallList; +} + +QSharedPointer App::getSettings() const { + return mSettings; +} + #ifdef Q_OS_LINUX QString App::getApplicationPath() const { const QString binPath(QCoreApplication::applicationFilePath()); diff --git a/Linphone/core/App.hpp b/Linphone/core/App.hpp index 44d925474..c05ea101f 100644 --- a/Linphone/core/App.hpp +++ b/Linphone/core/App.hpp @@ -22,6 +22,8 @@ #include #include +#include "core/account/AccountProxy.hpp" +#include "core/call/CallProxy.hpp" #include "core/setting/SettingsCore.hpp" #include "core/singleapplication/singleapplication.h" #include "model/cli/CliModel.hpp" @@ -114,6 +116,9 @@ public: QQuickWindow *getMainWindow() const; void setMainWindow(QQuickWindow *data); + QSharedPointer getAccountList() const; + QSharedPointer getCallList() const; + QSharedPointer getSettings() const; #ifdef Q_OS_LINUX Q_INVOKABLE void exportDesktopFile(); @@ -142,7 +147,9 @@ private: Notifier *mNotifier = nullptr; QQuickWindow *mMainWindow = nullptr; QQuickWindow *mCallsWindow = nullptr; - QSharedPointer mSettings; + QSharedPointer mSettings; + QSharedPointer mAccountList; + QSharedPointer mCallList; QSharedPointer> mCoreModelConnection; QSharedPointer> mCliModelConnection; bool mAutoStart = false; diff --git a/Linphone/core/account/AccountList.cpp b/Linphone/core/account/AccountList.cpp index 6eebccb76..ab58fb102 100644 --- a/Linphone/core/account/AccountList.cpp +++ b/Linphone/core/account/AccountList.cpp @@ -38,6 +38,7 @@ QSharedPointer AccountList::create() { AccountList::AccountList(QObject *parent) : ListProxy(parent) { mustBeInMainThread(getClassName()); + App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); } AccountList::~AccountList() { @@ -84,6 +85,7 @@ void AccountList::setSelf(QSharedPointer me) { mModelConnection->makeConnectToModel(&CoreModel::accountAdded, &AccountList::lUpdate); lUpdate(); + emit initialized(); } QSharedPointer AccountList::getDefaultAccountCore() const { diff --git a/Linphone/core/account/AccountList.hpp b/Linphone/core/account/AccountList.hpp index 9f5746c5a..5fc983e92 100644 --- a/Linphone/core/account/AccountList.hpp +++ b/Linphone/core/account/AccountList.hpp @@ -54,6 +54,7 @@ signals: void lUpdate(); void haveAccountChanged(); void defaultAccountChanged(); + void initialized(); private: bool mHaveAccount = false; diff --git a/Linphone/core/account/AccountProxy.cpp b/Linphone/core/account/AccountProxy.cpp index fb16c36cb..68e1aebad 100644 --- a/Linphone/core/account/AccountProxy.cpp +++ b/Linphone/core/account/AccountProxy.cpp @@ -21,13 +21,10 @@ #include "AccountProxy.hpp" #include "AccountGui.hpp" #include "AccountList.hpp" +#include "core/App.hpp" AccountProxy::AccountProxy(QObject *parent) : SortFilterProxy(parent) { - mAccountList = AccountList::create(); - connect(mAccountList.get(), &AccountList::countChanged, this, &AccountProxy::resetDefaultAccount); - connect(mAccountList.get(), &AccountList::defaultAccountChanged, this, &AccountProxy::resetDefaultAccount); - connect(mAccountList.get(), &AccountList::haveAccountChanged, this, &AccountProxy::haveAccountChanged); - setSourceModel(mAccountList.get()); + setSourceModel(App::getInstance()->getAccountList().get()); sort(0); } @@ -73,6 +70,20 @@ bool AccountProxy::getHaveAccount() const { return dynamic_cast(sourceModel())->getHaveAccount(); } +void AccountProxy::setSourceModel(QAbstractItemModel *model) { + auto oldAccountList = dynamic_cast(sourceModel()); + if (oldAccountList) { + disconnect(oldAccountList); + } + auto newAccountList = dynamic_cast(model); + if (newAccountList) { + connect(newAccountList, &AccountList::countChanged, this, &AccountProxy::resetDefaultAccount); + connect(newAccountList, &AccountList::defaultAccountChanged, this, &AccountProxy::resetDefaultAccount); + connect(newAccountList, &AccountList::haveAccountChanged, this, &AccountProxy::haveAccountChanged); + } + QSortFilterProxyModel::setSourceModel(model); +} + bool AccountProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { bool show = (mFilterText.isEmpty() || mFilterText == "*"); if (!show) { diff --git a/Linphone/core/account/AccountProxy.hpp b/Linphone/core/account/AccountProxy.hpp index 18572fed3..0a1a03013 100644 --- a/Linphone/core/account/AccountProxy.hpp +++ b/Linphone/core/account/AccountProxy.hpp @@ -49,10 +49,13 @@ public: bool getHaveAccount() const; + void setSourceModel(QAbstractItemModel *sourceModel) override; + signals: void filterTextChanged(); void defaultAccountChanged(); void haveAccountChanged(); + void initialized(); protected: virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; @@ -60,7 +63,6 @@ protected: QString mFilterText; QSharedPointer mDefaultAccount; // When null, a new UI object is build from List - QSharedPointer mAccountList; }; #endif diff --git a/Linphone/core/call/CallList.cpp b/Linphone/core/call/CallList.cpp index b19bceccc..1adefddde 100644 --- a/Linphone/core/call/CallList.cpp +++ b/Linphone/core/call/CallList.cpp @@ -44,6 +44,7 @@ QSharedPointer CallList::createCallCore(const std::shared_ptrmEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); } CallList::~CallList() { diff --git a/Linphone/core/call/CallProxy.cpp b/Linphone/core/call/CallProxy.cpp index 711004cc6..85bfa0a99 100644 --- a/Linphone/core/call/CallProxy.cpp +++ b/Linphone/core/call/CallProxy.cpp @@ -21,15 +21,12 @@ #include "CallProxy.hpp" #include "CallGui.hpp" #include "CallList.hpp" +#include "core/App.hpp" DEFINE_ABSTRACT_OBJECT(CallProxy) CallProxy::CallProxy(QObject *parent) : SortFilterProxy(parent) { - mList = CallList::create(); - connect(mList.get(), &CallList::currentCallChanged, this, &CallProxy::resetCurrentCall); - connect(mList.get(), &CallList::haveCallChanged, this, &CallProxy::haveCallChanged); - connect(this, &CallProxy::lMergeAll, mList.get(), &CallList::lMergeAll); - setSourceModel(mList.get()); + setSourceModel(App::getInstance()->getCallList().get()); sort(0); } @@ -68,6 +65,20 @@ bool CallProxy::getHaveCall() const { return dynamic_cast(sourceModel())->getHaveCall(); } +void CallProxy::setSourceModel(QAbstractItemModel *model) { + auto oldCallList = dynamic_cast(sourceModel()); + if (oldCallList) { + disconnect(oldCallList); + } + auto newCallList = dynamic_cast(model); + if (newCallList) { + connect(newCallList, &CallList::currentCallChanged, this, &CallProxy::resetCurrentCall); + connect(newCallList, &CallList::haveCallChanged, this, &CallProxy::haveCallChanged); + connect(this, &CallProxy::lMergeAll, newCallList, &CallList::lMergeAll); + } + QSortFilterProxyModel::setSourceModel(model); +} + bool CallProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { bool show = (mFilterText.isEmpty() || mFilterText == "*"); if (!show) { diff --git a/Linphone/core/call/CallProxy.hpp b/Linphone/core/call/CallProxy.hpp index 119551e7d..40bcf78f1 100644 --- a/Linphone/core/call/CallProxy.hpp +++ b/Linphone/core/call/CallProxy.hpp @@ -50,6 +50,8 @@ public: bool getHaveCall() const; + void setSourceModel(QAbstractItemModel *sourceModel) override; + signals: void lMergeAll(); void filterTextChanged(); @@ -62,7 +64,6 @@ protected: QString mFilterText; CallGui *mCurrentCall = nullptr; // When null, a new UI object is build from List - QSharedPointer mList; DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/conference/ConferenceInfoCore.cpp b/Linphone/core/conference/ConferenceInfoCore.cpp index 2c8064a87..147294dd8 100644 --- a/Linphone/core/conference/ConferenceInfoCore.cpp +++ b/Linphone/core/conference/ConferenceInfoCore.cpp @@ -574,6 +574,7 @@ void ConferenceInfoCore::save() { if (CoreModel::getInstance()->getCore()->getDefaultAccount()->getState() != linphone::RegistrationState::Ok) { Utils::showInformationPopup(tr("Erreur"), tr("Votre compte est déconnecté"), false); + emit saveFailed(); return; } auto linphoneConf = diff --git a/Linphone/core/conference/ConferenceInfoCore.hpp b/Linphone/core/conference/ConferenceInfoCore.hpp index 9a9121b68..41a702a7c 100644 --- a/Linphone/core/conference/ConferenceInfoCore.hpp +++ b/Linphone/core/conference/ConferenceInfoCore.hpp @@ -150,6 +150,7 @@ signals: void conferenceInfoStateChanged(); void conferenceSchedulerStateChanged(); void timeZoneModelChanged(); + void saveFailed(); void invitationsSent(); void removed(); diff --git a/Linphone/core/notifier/Notifier.cpp b/Linphone/core/notifier/Notifier.cpp index 6894877d1..a6c81bfe0 100644 --- a/Linphone/core/notifier/Notifier.cpp +++ b/Linphone/core/notifier/Notifier.cpp @@ -95,7 +95,7 @@ const QHash Notifier::Notifications = { // ----------------------------------------------------------------------------- -Notifier::Notifier(QObject *parent, QSharedPointer settings) : QObject(parent) { +Notifier::Notifier(QObject *parent) : QObject(parent) { mustBeInMainThread(getClassName()); const int nComponents = Notifications.size(); mComponents = new QQmlComponent *[nComponents]; @@ -113,7 +113,6 @@ Notifier::Notifier(QObject *parent, QSharedPointer settings) : QObject } mMutex = new QMutex(); - mSettings = settings; } Notifier::~Notifier() { @@ -268,7 +267,8 @@ void Notifier::deleteNotification(QVariant notification) { // ============================================================================= #define CREATE_NOTIFICATION(TYPE, DATA) \ - if (mSettings->dndEnabled()) return; \ + auto settings = App::getInstance()->getSettings(); \ + if (settings && settings->dndEnabled()) return; \ QObject *notification = createNotification(TYPE, DATA); \ if (!notification) return; \ const int timeout = Notifications[TYPE].getTimeout() * 1000; \ @@ -280,6 +280,8 @@ void Notifier::deleteNotification(QVariant notification) { void Notifier::notifyReceivedCall(const shared_ptr &call) { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); + auto remoteAddress = call->getRemoteAddress(); + auto accountSender = ToolModel::findAccount(remoteAddress); auto account = ToolModel::findAccount(call->getToAddress()); if (account) { auto accountModel = Utils::makeQObject_ptr(account); diff --git a/Linphone/core/notifier/Notifier.hpp b/Linphone/core/notifier/Notifier.hpp index 607c01fe4..9e71a8bdf 100644 --- a/Linphone/core/notifier/Notifier.hpp +++ b/Linphone/core/notifier/Notifier.hpp @@ -37,7 +37,7 @@ class Notifier : public QObject, public AbstractObject { Q_OBJECT public: - Notifier(QObject *parent = Q_NULLPTR, QSharedPointer settings = Q_NULLPTR); + Notifier(QObject *parent = Q_NULLPTR); ~Notifier(); enum NotificationType { @@ -98,7 +98,6 @@ private: QQmlComponent **mComponents = nullptr; static const QHash Notifications; - QSharedPointer mSettings; DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/participant/ParticipantProxy.cpp b/Linphone/core/participant/ParticipantProxy.cpp index 1f1cffd4a..28e7b8caf 100644 --- a/Linphone/core/participant/ParticipantProxy.cpp +++ b/Linphone/core/participant/ParticipantProxy.cpp @@ -106,30 +106,6 @@ bool ParticipantProxy::getShowMe() const { // } // } -void ParticipantProxy::setConferenceModel(ConferenceModel *conferenceModel) { - // if (!mConferenceModel || mConferenceModel != conferenceModel) { - // mConferenceModel = conferenceModel; - // if (mConferenceModel) { - // auto participants = mConferenceModel->getParticipantList(); - // connect(participants, &ParticipantList::countChanged, this, &ParticipantProxy::countChanged); - // setSourceModel(participants); - // emit participantListChanged(); - // for (int i = 0; i < participants->getCount(); ++i) { - // auto participant = participants->getAt(i); - // connect(participant.get(), &ParticipantCore::invitationTimeout, this, &ParticipantProxy::removeModel); - // emit addressAdded(participant->getSipAddress()); - // } - // } else if (!sourceModel()) { - // auto model = new ParticipantList((ConferenceModel *)nullptr, this); - // connect(model, &ParticipantList::countChanged, this, &ParticipantProxy::countChanged); - // setSourceModel(model); - // emit participantListChanged(); - // } - // sort(0); - // emit conferenceModelChanged(); - // } -} - void ParticipantProxy::setShowMe(const bool &show) { if (mShowMe != show) { mShowMe = show; diff --git a/Linphone/core/participant/ParticipantProxy.hpp b/Linphone/core/participant/ParticipantProxy.hpp index 1620e3a3b..7205b378a 100644 --- a/Linphone/core/participant/ParticipantProxy.hpp +++ b/Linphone/core/participant/ParticipantProxy.hpp @@ -53,8 +53,6 @@ public: bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; bool getShowMe() const; - - void setConferenceModel(ConferenceModel *conferenceModel); void setShowMe(const bool &show); Q_INVOKABLE void addAddress(const QString &address); diff --git a/Linphone/core/search/MagicSearchList.cpp b/Linphone/core/search/MagicSearchList.cpp index 8d76129b1..1aef5560c 100644 --- a/Linphone/core/search/MagicSearchList.cpp +++ b/Linphone/core/search/MagicSearchList.cpp @@ -41,15 +41,7 @@ MagicSearchList::MagicSearchList(QObject *parent) : ListProxy(parent) { mustBeInMainThread(getClassName()); mSourceFlags = (int)linphone::MagicSearch::Source::Friends | (int)linphone::MagicSearch::Source::LdapServers; mAggregationFlag = LinphoneEnums::MagicSearchAggregation::Friend; - App::postModelSync([this]() { - mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); - auto linphoneSearch = CoreModel::getInstance()->getCore()->createMagicSearch(); - linphoneSearch->setLimitedSearch(false); - mMagicSearch = Utils::makeQObject_ptr(linphoneSearch); - mMagicSearch->mSourceFlags = mSourceFlags; - mMagicSearch->mAggregationFlag = mAggregationFlag; - mMagicSearch->setSelf(mMagicSearch); - }); + mSearchFilter = "*"; } MagicSearchList::~MagicSearchList() { @@ -57,50 +49,6 @@ MagicSearchList::~MagicSearchList() { } void MagicSearchList::setSelf(QSharedPointer me) { - mModelConnection = QSharedPointer>( - new SafeConnection(me, mMagicSearch), &QObject::deleteLater); - mModelConnection->makeConnectToCore(&MagicSearchList::lSearch, [this](QString filter) { - mModelConnection->invokeToModel([this, filter]() { mMagicSearch->search(filter); }); - }); - mModelConnection->makeConnectToCore(&MagicSearchList::lSetSourceFlags, [this](int flags) { - mModelConnection->invokeToModel([this, flags]() { mMagicSearch->setSourceFlags(flags); }); - }); - mModelConnection->makeConnectToModel(&MagicSearchModel::sourceFlagsChanged, [this](int flags) { - mModelConnection->invokeToCore([this, flags]() { setSourceFlags(flags); }); - }); - mModelConnection->makeConnectToModel( - &MagicSearchModel::aggregationFlagChanged, [this](LinphoneEnums::MagicSearchAggregation flag) { - mModelConnection->invokeToCore([this, flag]() { setAggregationFlag(flag); }); - }); - mModelConnection->makeConnectToModel( - &MagicSearchModel::searchResultsReceived, - [this](const std::list> &results) { - auto *contacts = new QList>(); - for (auto it : results) { - QSharedPointer contact; - if (it->getFriend()) { - contact = FriendCore::create(it->getFriend()); - contacts->append(contact); - } else if (auto address = it->getAddress()) { - auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend(); - contact = FriendCore::create(linphoneFriend); - contact->setGivenName(Utils::coreStringToAppString(address->asStringUriOnly())); - contact->appendAddress(Utils::coreStringToAppString(address->asStringUriOnly())); - contacts->append(contact); - } else if (!it->getPhoneNumber().empty()) { - auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend(); - contact = FriendCore::create(linphoneFriend); - contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber())); - contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber())); - contacts->append(contact); - } - } - mModelConnection->invokeToCore([this, contacts]() { - setResults(*contacts); - delete contacts; - }); - }); - mCoreModelConnection = QSharedPointer>( new SafeConnection(me, CoreModel::getInstance()), &QObject::deleteLater); mCoreModelConnection->makeConnectToModel( @@ -113,13 +61,66 @@ void MagicSearchList::setSelf(QSharedPointer me) { if (haveContact == mList.end()) { connect(friendCore.get(), &FriendCore::removed, this, qOverload(&MagicSearchList::remove)); add(friendCore); - int index = -1; - get(friendCore.get(), &index); - if (index != -1) { - emit friendCreated(index); - } + emit friendCreated(getCount() - 1); } }); + mCoreModelConnection->invokeToModel([this] { + auto linphoneSearch = CoreModel::getInstance()->getCore()->createMagicSearch(); + linphoneSearch->setLimitedSearch(false); + auto magicSearch = Utils::makeQObject_ptr(linphoneSearch); + mCoreModelConnection->invokeToCore([this, magicSearch] { + mMagicSearch = magicSearch; + mMagicSearch->mSourceFlags = mSourceFlags; + mMagicSearch->mAggregationFlag = mAggregationFlag; + mMagicSearch->setSelf(mMagicSearch); + mModelConnection = QSharedPointer>( + new SafeConnection(mCoreModelConnection->mCore.mQData, mMagicSearch), + &QObject::deleteLater); + mModelConnection->makeConnectToCore(&MagicSearchList::lSearch, [this](QString filter) { + mModelConnection->invokeToModel([this, filter]() { mMagicSearch->search(filter); }); + }); + mModelConnection->makeConnectToCore(&MagicSearchList::lSetSourceFlags, [this](int flags) { + mModelConnection->invokeToModel([this, flags]() { mMagicSearch->setSourceFlags(flags); }); + }); + mModelConnection->makeConnectToModel(&MagicSearchModel::sourceFlagsChanged, [this](int flags) { + mModelConnection->invokeToCore([this, flags]() { setSourceFlags(flags); }); + }); + mModelConnection->makeConnectToModel( + &MagicSearchModel::aggregationFlagChanged, [this](LinphoneEnums::MagicSearchAggregation flag) { + mModelConnection->invokeToCore([this, flag]() { setAggregationFlag(flag); }); + }); + mModelConnection->makeConnectToModel( + &MagicSearchModel::searchResultsReceived, + [this](const std::list> &results) { + auto *contacts = new QList>(); + for (auto it : results) { + QSharedPointer contact; + if (it->getFriend()) { + contact = FriendCore::create(it->getFriend()); + contacts->append(contact); + } else if (auto address = it->getAddress()) { + auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend(); + contact = FriendCore::create(linphoneFriend); + contact->setGivenName(Utils::coreStringToAppString(address->asStringUriOnly())); + contact->appendAddress(Utils::coreStringToAppString(address->asStringUriOnly())); + contacts->append(contact); + } else if (!it->getPhoneNumber().empty()) { + auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend(); + contact = FriendCore::create(linphoneFriend); + contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber())); + contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber())); + contacts->append(contact); + } + } + mModelConnection->invokeToCore([this, contacts]() { + setResults(*contacts); + delete contacts; + }); + }); + emit initialized(); + emit lSearch(mSearchFilter); + }); + }); } void MagicSearchList::setResults(const QList> &contacts) { @@ -134,6 +135,7 @@ void MagicSearchList::addResult(const QSharedPointer &contact) { } void MagicSearchList::setSearch(const QString &search) { + mSearchFilter = search; if (!search.isEmpty()) { lSearch(search); } else { diff --git a/Linphone/core/search/MagicSearchList.hpp b/Linphone/core/search/MagicSearchList.hpp index b4861741d..9882a40b8 100644 --- a/Linphone/core/search/MagicSearchList.hpp +++ b/Linphone/core/search/MagicSearchList.hpp @@ -52,7 +52,7 @@ public: virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - int findFriendIndexByAddress(const QString& address); + int findFriendIndexByAddress(const QString &address); signals: void lSearch(QString filter); @@ -64,9 +64,12 @@ signals: void friendCreated(int index); + void initialized(); + private: int mSourceFlags; LinphoneEnums::MagicSearchAggregation mAggregationFlag; + QString mSearchFilter; std::shared_ptr mMagicSearch; QSharedPointer> mModelConnection; diff --git a/Linphone/core/search/MagicSearchProxy.cpp b/Linphone/core/search/MagicSearchProxy.cpp index f2f3d02cd..a58b64d8d 100644 --- a/Linphone/core/search/MagicSearchProxy.cpp +++ b/Linphone/core/search/MagicSearchProxy.cpp @@ -24,7 +24,9 @@ MagicSearchProxy::MagicSearchProxy(QObject *parent) : SortFilterProxy(parent) { mList = MagicSearchList::create(); - connect(mList.get(), &MagicSearchList::sourceFlagsChanged, this, &MagicSearchProxy::sourceFlagsChanged); + mSourceFlags = (int)LinphoneEnums::MagicSearchSource::Friends | (int)LinphoneEnums::MagicSearchSource::LdapServers; + mAggregationFlag = LinphoneEnums::MagicSearchAggregation::Friend; + (mList.get(), &MagicSearchList::sourceFlagsChanged, this, &MagicSearchProxy::sourceFlagsChanged); connect(mList.get(), &MagicSearchList::aggregationFlagChanged, this, &MagicSearchProxy::aggregationFlagChanged); connect(mList.get(), &MagicSearchList::friendCreated, this, [this](int index) { auto proxyIndex = mapFromSource(sourceModel()->index(index, 0)); @@ -33,6 +35,10 @@ MagicSearchProxy::MagicSearchProxy(QObject *parent) : SortFilterProxy(parent) { setSourceModel(mList.get()); connect(this, &MagicSearchProxy::forceUpdate, [this] { emit mList->lSearch(mSearchText); }); sort(0); + connect(mList.get(), &MagicSearchList::initialized, this, [this] { + emit mList->lSetSourceFlags(mSourceFlags); + emit mList->lSetAggregationFlag(mAggregationFlag); + }); } MagicSearchProxy::~MagicSearchProxy() { @@ -48,23 +54,29 @@ QString MagicSearchProxy::getSearchText() const { void MagicSearchProxy::setSearchText(const QString &search) { mSearchText = search; - qobject_cast(sourceModel())->setSearch(mSearchText); + mList->setSearch(mSearchText); } int MagicSearchProxy::getSourceFlags() const { - return qobject_cast(sourceModel())->getSourceFlags(); + return mSourceFlags; } void MagicSearchProxy::setSourceFlags(int flags) { - qobject_cast(sourceModel())->lSetSourceFlags(flags); + if (flags != mSourceFlags) { + mSourceFlags = flags; + emit mList->lSetSourceFlags(flags); + } } LinphoneEnums::MagicSearchAggregation MagicSearchProxy::getAggregationFlag() const { - return qobject_cast(sourceModel())->getAggregationFlag(); + return mAggregationFlag; } void MagicSearchProxy::setAggregationFlag(LinphoneEnums::MagicSearchAggregation flag) { - qobject_cast(sourceModel())->lSetAggregationFlag(flag); + if (flag != mAggregationFlag) { + mAggregationFlag = flag; + emit mList->lSetAggregationFlag(flag); + } } bool MagicSearchProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const { diff --git a/Linphone/core/search/MagicSearchProxy.hpp b/Linphone/core/search/MagicSearchProxy.hpp index a0f0410da..2884d416d 100644 --- a/Linphone/core/search/MagicSearchProxy.hpp +++ b/Linphone/core/search/MagicSearchProxy.hpp @@ -60,6 +60,8 @@ signals: protected: QString mSearchText; + int mSourceFlags; + LinphoneEnums::MagicSearchAggregation mAggregationFlag; QSharedPointer mList; virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; }; diff --git a/Linphone/core/setting/SettingsCore.cpp b/Linphone/core/setting/SettingsCore.cpp index abe6072fd..eb749a2e1 100644 --- a/Linphone/core/setting/SettingsCore.cpp +++ b/Linphone/core/setting/SettingsCore.cpp @@ -27,18 +27,18 @@ #include #include -DEFINE_ABSTRACT_OBJECT(Settings) +DEFINE_ABSTRACT_OBJECT(SettingsCore) // ============================================================================= -QSharedPointer Settings::create() { - auto sharedPointer = QSharedPointer(new Settings(), &QObject::deleteLater); +QSharedPointer SettingsCore::create() { + auto sharedPointer = QSharedPointer(new SettingsCore(), &QObject::deleteLater); sharedPointer->setSelf(sharedPointer); sharedPointer->moveToThread(App::getInstance()->thread()); return sharedPointer; } -Settings::Settings(QObject *parent) : QObject(parent) { +SettingsCore::SettingsCore(QObject *parent) : QObject(parent) { mustBeInLinphoneThread(getClassName()); mSettingsModel = Utils::makeQObject_ptr(); @@ -93,16 +93,16 @@ Settings::Settings(QObject *parent) : QObject(parent) { INIT_CORE_MEMBER(AutoStart, mSettingsModel) } -Settings::~Settings() { +SettingsCore::~SettingsCore() { } -void Settings::setSelf(QSharedPointer me) { +void SettingsCore::setSelf(QSharedPointer me) { mustBeInLinphoneThread(getClassName()); - mSettingsModelConnection = QSharedPointer>( - new SafeConnection(me, mSettingsModel), &QObject::deleteLater); + mSettingsModelConnection = QSharedPointer>( + new SafeConnection(me, mSettingsModel), &QObject::deleteLater); // VFS - mSettingsModelConnection->makeConnectToCore(&Settings::setVfsEnabled, [this](const bool enabled) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::setVfsEnabled, [this](const bool enabled) { mSettingsModelConnection->invokeToModel([this, enabled]() { mSettingsModel->setVfsEnabled(enabled); }); }); @@ -114,7 +114,7 @@ void Settings::setSelf(QSharedPointer me) { }); // Video Calls - mSettingsModelConnection->makeConnectToCore(&Settings::setVideoEnabled, [this](const bool enabled) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::setVideoEnabled, [this](const bool enabled) { mSettingsModelConnection->invokeToModel([this, enabled]() { mSettingsModel->setVideoEnabled(enabled); }); }); @@ -126,7 +126,7 @@ void Settings::setSelf(QSharedPointer me) { }); // Echo cancelling - mSettingsModelConnection->makeConnectToCore(&Settings::setEchoCancellationEnabled, [this](const bool enabled) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::setEchoCancellationEnabled, [this](const bool enabled) { mSettingsModelConnection->invokeToModel( [this, enabled]() { mSettingsModel->setEchoCancellationEnabled(enabled); }); }); @@ -140,7 +140,7 @@ void Settings::setSelf(QSharedPointer me) { }); // Auto recording - mSettingsModelConnection->makeConnectToCore(&Settings::setAutomaticallyRecordCallsEnabled, + mSettingsModelConnection->makeConnectToCore(&SettingsCore::setAutomaticallyRecordCallsEnabled, [this](const bool enabled) { mSettingsModelConnection->invokeToModel([this, enabled]() { mSettingsModel->setAutomaticallyRecordCallsEnabled(enabled); @@ -155,7 +155,7 @@ void Settings::setSelf(QSharedPointer me) { }); // Audio device(s) - mSettingsModelConnection->makeConnectToCore(&Settings::lSetCaptureDevice, [this](const QString id) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::lSetCaptureDevice, [this](const QString id) { mSettingsModelConnection->invokeToModel([this, id]() { mSettingsModel->setCaptureDevice(id); }); }); mSettingsModelConnection->makeConnectToModel(&SettingsModel::captureDeviceChanged, [this](const QString device) { @@ -165,7 +165,7 @@ void Settings::setSelf(QSharedPointer me) { }); }); - mSettingsModelConnection->makeConnectToCore(&Settings::lSetPlaybackDevice, [this](const QString id) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::lSetPlaybackDevice, [this](const QString id) { mSettingsModelConnection->invokeToModel([this, id]() { mSettingsModel->setPlaybackDevice(id); }); }); @@ -176,7 +176,7 @@ void Settings::setSelf(QSharedPointer me) { }); }); - mSettingsModelConnection->makeConnectToCore(&Settings::lSetPlaybackGain, [this](const float value) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::lSetPlaybackGain, [this](const float value) { mSettingsModelConnection->invokeToModel([this, value]() { mSettingsModel->setPlaybackGain(value); }); }); @@ -187,7 +187,7 @@ void Settings::setSelf(QSharedPointer me) { }); }); - mSettingsModelConnection->makeConnectToCore(&Settings::lSetCaptureGain, [this](const float value) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::lSetCaptureGain, [this](const float value) { mSettingsModelConnection->invokeToModel([this, value]() { mSettingsModel->setCaptureGain(value); }); }); @@ -219,7 +219,7 @@ void Settings::setSelf(QSharedPointer me) { }); // Video device(s) - mSettingsModelConnection->makeConnectToCore(&Settings::lSetVideoDevice, [this](const QString id) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::lSetVideoDevice, [this](const QString id) { mSettingsModelConnection->invokeToModel([this, id]() { mSettingsModel->setVideoDevice(id); }); }); @@ -239,7 +239,7 @@ void Settings::setSelf(QSharedPointer me) { }); // Logs - mSettingsModelConnection->makeConnectToCore(&Settings::setLogsEnabled, [this](const bool status) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::setLogsEnabled, [this](const bool status) { mSettingsModelConnection->invokeToModel([this, status]() { mSettingsModel->setLogsEnabled(status); }); }); @@ -250,7 +250,7 @@ void Settings::setSelf(QSharedPointer me) { }); }); - mSettingsModelConnection->makeConnectToCore(&Settings::setFullLogsEnabled, [this](const bool status) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::setFullLogsEnabled, [this](const bool status) { mSettingsModelConnection->invokeToModel([this, status]() { mSettingsModel->setFullLogsEnabled(status); }); }); @@ -262,7 +262,7 @@ void Settings::setSelf(QSharedPointer me) { }); // DND - mSettingsModelConnection->makeConnectToCore(&Settings::lEnableDnd, [this](const bool value) { + mSettingsModelConnection->makeConnectToCore(&SettingsCore::lEnableDnd, [this](const bool value) { mSettingsModelConnection->invokeToModel([this, value]() { mSettingsModel->enableDnd(value); }); }); mSettingsModelConnection->makeConnectToModel(&SettingsModel::dndChanged, [this](const bool value) { @@ -272,44 +272,44 @@ void Settings::setSelf(QSharedPointer me) { }); }); - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, disableChatFeature, DisableChatFeature) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, disableMeetingsFeature, DisableMeetingsFeature) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, disableBroadcastFeature, DisableBroadcastFeature) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, hideSettings, - HideSettings) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, + hideSettings, HideSettings) + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, hideAccountSettings, HideAccountSettings) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, disableCallRecordings, DisableCallRecordings) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, assistantHideCreateAccount, AssistantHideCreateAccount) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, assistantHideCreateAccount, AssistantHideCreateAccount) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, assistantDisableQrCode, AssistantDisableQrCode) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, assistantHideThirdPartyAccount, AssistantHideThirdPartyAccount) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, onlyDisplaySipUriUsername, OnlyDisplaySipUriUsername) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, darkModeAllowed, - DarkModeAllowed) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, int, maxAccount, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, + darkModeAllowed, DarkModeAllowed) + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, int, maxAccount, MaxAccount) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, assistantGoDirectlyToThirdPartySipAccountLogin, AssistantGoDirectlyToThirdPartySipAccountLogin) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, QString, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, QString, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport) - DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, Settings, SettingsModel, mSettingsModel, bool, autoStart, + DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, autoStart, AutoStart) - auto coreModelConnection = QSharedPointer>( - new SafeConnection(me, CoreModel::getInstance()), &QObject::deleteLater); + auto coreModelConnection = QSharedPointer>( + new SafeConnection(me, CoreModel::getInstance()), &QObject::deleteLater); coreModelConnection->makeConnectToModel( &CoreModel::logCollectionUploadStateChanged, [this](auto core, auto state, auto info) { @@ -323,7 +323,7 @@ void Settings::setSelf(QSharedPointer me) { }); } -QString Settings::getConfigPath(const QCommandLineParser &parser) { +QString SettingsCore::getConfigPath(const QCommandLineParser &parser) { QString filePath = parser.isSet("config") ? parser.value("config") : ""; QString configPath; if (!QUrl(filePath).isRelative()) { @@ -335,52 +335,52 @@ QString Settings::getConfigPath(const QCommandLineParser &parser) { return configPath; } -QStringList Settings::getCaptureDevices() const { +QStringList SettingsCore::getCaptureDevices() const { return mCaptureDevices; } -QStringList Settings::getPlaybackDevices() const { +QStringList SettingsCore::getPlaybackDevices() const { return mPlaybackDevices; } -int Settings::getVideoDeviceIndex() const { +int SettingsCore::getVideoDeviceIndex() const { return mVideoDevices.indexOf(mVideoDevice); } -QStringList Settings::getVideoDevices() const { +QStringList SettingsCore::getVideoDevices() const { return mVideoDevices; } -bool Settings::getCaptureGraphRunning() { +bool SettingsCore::getCaptureGraphRunning() { return mCaptureGraphRunning; } -float Settings::getCaptureGain() const { +float SettingsCore::getCaptureGain() const { return mCaptureGain; } -float Settings::getPlaybackGain() const { +float SettingsCore::getPlaybackGain() const { return mPlaybackGain; } -QString Settings::getCaptureDevice() const { +QString SettingsCore::getCaptureDevice() const { return mCaptureDevice; } -QString Settings::getPlaybackDevice() const { +QString SettingsCore::getPlaybackDevice() const { return mPlaybackDevice; } -int Settings::getEchoCancellationCalibration() const { +int SettingsCore::getEchoCancellationCalibration() const { return mEchoCancellationCalibration; } -bool Settings::getFirstLaunch() const { +bool SettingsCore::getFirstLaunch() const { auto val = mAppSettings.value("firstLaunch", 1).toInt(); return val; } -void Settings::setFirstLaunch(bool first) { +void SettingsCore::setFirstLaunch(bool first) { auto firstLaunch = getFirstLaunch(); if (firstLaunch != first) { mAppSettings.setValue("firstLaunch", (int)first); @@ -389,7 +389,7 @@ void Settings::setFirstLaunch(bool first) { } } -void Settings::setLastActiveTabIndex(int index) { +void SettingsCore::setLastActiveTabIndex(int index) { auto lastActiveIndex = getLastActiveTabIndex(); if (lastActiveIndex != index) { mAppSettings.setValue("lastActiveTabIndex", index); @@ -398,11 +398,11 @@ void Settings::setLastActiveTabIndex(int index) { } } -int Settings::getLastActiveTabIndex() { +int SettingsCore::getLastActiveTabIndex() { return mAppSettings.value("lastActiveTabIndex", 1).toInt(); } -void Settings::setDisplayDeviceCheckConfirmation(bool display) { +void SettingsCore::setDisplayDeviceCheckConfirmation(bool display) { if (getDisplayDeviceCheckConfirmation() != display) { mAppSettings.setValue("displayDeviceCheckConfirmation", display); mAppSettings.sync(); @@ -410,50 +410,50 @@ void Settings::setDisplayDeviceCheckConfirmation(bool display) { } } -bool Settings::getDisplayDeviceCheckConfirmation() const { +bool SettingsCore::getDisplayDeviceCheckConfirmation() const { auto val = mAppSettings.value("displayDeviceCheckConfirmation", 1).toInt(); return val; } -void Settings::startEchoCancellerCalibration() { +void SettingsCore::startEchoCancellerCalibration() { mSettingsModelConnection->invokeToModel([this]() { mSettingsModel->startEchoCancellerCalibration(); }); } -void Settings::accessCallSettings() { +void SettingsCore::accessCallSettings() { mSettingsModelConnection->invokeToModel([this]() { mSettingsModel->accessCallSettings(); }); } -void Settings::closeCallSettings() { +void SettingsCore::closeCallSettings() { mSettingsModelConnection->invokeToModel([this]() { mSettingsModel->closeCallSettings(); }); } -void Settings::updateMicVolume() const { +void SettingsCore::updateMicVolume() const { mSettingsModelConnection->invokeToModel([this]() { mSettingsModel->getMicVolume(); }); } -bool Settings::getLogsEnabled() const { +bool SettingsCore::getLogsEnabled() const { return mLogsEnabled; } -bool Settings::getFullLogsEnabled() const { +bool SettingsCore::getFullLogsEnabled() const { return mFullLogsEnabled; } -void Settings::cleanLogs() const { +void SettingsCore::cleanLogs() const { mSettingsModelConnection->invokeToModel([this]() { mSettingsModel->cleanLogs(); }); } -void Settings::sendLogs() const { +void SettingsCore::sendLogs() const { mSettingsModelConnection->invokeToModel([this]() { mSettingsModel->sendLogs(); }); } -QString Settings::getLogsEmail() const { +QString SettingsCore::getLogsEmail() const { return mLogsEmail; } -QString Settings::getLogsFolder() const { +QString SettingsCore::getLogsFolder() const { return mLogsFolder; } -bool Settings::dndEnabled() const { +bool SettingsCore::dndEnabled() const { return mDndEnabled; } diff --git a/Linphone/core/setting/SettingsCore.hpp b/Linphone/core/setting/SettingsCore.hpp index 3e6767bb2..66f134d8c 100644 --- a/Linphone/core/setting/SettingsCore.hpp +++ b/Linphone/core/setting/SettingsCore.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef SETTINGS_H_ -#define SETTINGS_H_ +#ifndef SETTINGS_CORE_H_ +#define SETTINGS_CORE_H_ #include "model/setting/SettingsModel.hpp" #include "tool/thread/SafeConnection.hpp" @@ -29,7 +29,7 @@ #include #include -class Settings : public QObject, public AbstractObject { +class SettingsCore : public QObject, public AbstractObject { Q_OBJECT // Security @@ -68,11 +68,11 @@ class Settings : public QObject, public AbstractObject { Q_PROPERTY(bool dnd READ dndEnabled WRITE lEnableDnd NOTIFY dndChanged) public: - static QSharedPointer create(); - Settings(QObject *parent = Q_NULLPTR); - virtual ~Settings(); + static QSharedPointer create(); + SettingsCore(QObject *parent = Q_NULLPTR); + virtual ~SettingsCore(); - void setSelf(QSharedPointer me); + void setSelf(QSharedPointer me); QString getConfigPath(const QCommandLineParser &parser = QCommandLineParser()); @@ -256,7 +256,7 @@ private: bool mDndEnabled; QSettings mAppSettings; - QSharedPointer> mSettingsModelConnection; + QSharedPointer> mSettingsModelConnection; DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/timezone/TimeZoneList.cpp b/Linphone/core/timezone/TimeZoneList.cpp index 3d5346bb8..e148d4671 100644 --- a/Linphone/core/timezone/TimeZoneList.cpp +++ b/Linphone/core/timezone/TimeZoneList.cpp @@ -58,6 +58,13 @@ void TimeZoneList::initTimeZones() { } } +QHash TimeZoneList::roleNames() const { + QHash roles; + roles[Qt::DisplayRole] = "$modelData"; + roles[Qt::DisplayRole + 1] = "$timeZoneModel"; + return roles; +} + QVariant TimeZoneList::data(const QModelIndex &index, int role) const { int row = index.row(); @@ -66,13 +73,17 @@ QVariant TimeZoneList::data(const QModelIndex &index, int role) const { if (!timeZoneModel) return QVariant(); int offset = timeZoneModel->getStandardTimeOffset() / 3600; int absOffset = std::abs(offset); - - return QStringLiteral("(GMT%1%2%3:00) %4 %5") - .arg(offset >= 0 ? "+" : "-") - .arg(absOffset < 10 ? "0" : "") - .arg(absOffset) - .arg(timeZoneModel->getCountryName()) - .arg(timeZoneModel->getTimeZone().comment().isEmpty() ? "" : (" - " + timeZoneModel->getTimeZone().comment())); + if (role == Qt::DisplayRole + 1) { + return QVariant::fromValue(new TimeZoneModel(timeZoneModel->getTimeZone())); + } else { + return QStringLiteral("(GMT%1%2%3:00) %4 %5") + .arg(offset >= 0 ? "+" : "-") + .arg(absOffset < 10 ? "0" : "") + .arg(absOffset) + .arg(timeZoneModel->getCountryName()) + .arg(timeZoneModel->getTimeZone().comment().isEmpty() ? "" + : (" - " + timeZoneModel->getTimeZone().comment())); + } } int TimeZoneList::get(const QTimeZone &timeZone) const { diff --git a/Linphone/core/timezone/TimeZoneList.hpp b/Linphone/core/timezone/TimeZoneList.hpp index 8c82ff9c3..4b255787b 100644 --- a/Linphone/core/timezone/TimeZoneList.hpp +++ b/Linphone/core/timezone/TimeZoneList.hpp @@ -38,6 +38,7 @@ public: void initTimeZones(); int get(const QTimeZone &timeZone = QTimeZone::systemTimeZone()) const; + QHash roleNames() const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; private: diff --git a/Linphone/model/call/CallModel.hpp b/Linphone/model/call/CallModel.hpp index 189a9e146..c14d703b3 100644 --- a/Linphone/model/call/CallModel.hpp +++ b/Linphone/model/call/CallModel.hpp @@ -152,7 +152,7 @@ private: virtual void onAudioDeviceChanged(const std::shared_ptr &call, const std::shared_ptr &audioDevice) override; virtual void onRemoteRecording(const std::shared_ptr &call, bool recording) override; - virtual void onAuthenticationTokenVerified(const std::shared_ptr &call, bool verified); + virtual void onAuthenticationTokenVerified(const std::shared_ptr &call, bool verified) override; signals: void dtmfReceived(const std::shared_ptr &call, int dtmf); diff --git a/Linphone/model/conference/ConferenceInfoModel.cpp b/Linphone/model/conference/ConferenceInfoModel.cpp index 8280dc0c0..9eed02905 100644 --- a/Linphone/model/conference/ConferenceInfoModel.cpp +++ b/Linphone/model/conference/ConferenceInfoModel.cpp @@ -66,7 +66,8 @@ void ConferenceInfoModel::setConferenceScheduler(const std::shared_ptrgetCore()->createDefaultChatRoomParams(); - mConferenceSchedulerModel->getMonitor()->sendInvitations(params); + // TODO : wait for new sdk api to send the invitations again + // mConferenceSchedulerModel->getMonitor()->sendInvitations(params); } emit schedulerStateChanged(state); }); diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp index ff4efcac1..475cca03c 100644 --- a/Linphone/model/tool/ToolModel.cpp +++ b/Linphone/model/tool/ToolModel.cpp @@ -128,13 +128,6 @@ bool ToolModel::createCall(const QString &sipAddress, } return false; } - for (auto &account : core->getAccountList()) { - if (account->getContactAddress() && account->getContactAddress()->weakEqual(address)) { - if (errorMessage) *errorMessage = tr("The calling address is a connected account."); - lDebug() << "[" + QString(gClassName) + "]" + *errorMessage; - return false; - } - } if (SettingsModel::dndEnabled( core->getConfig())) { // Force tones for outgoing calls when in DND mode (ringback, dtmf, etc ... ) disabled diff --git a/Linphone/view/App/CallsWindow.qml b/Linphone/view/App/CallsWindow.qml index fdbc81cd7..72d24ecf4 100644 --- a/Linphone/view/App/CallsWindow.qml +++ b/Linphone/view/App/CallsWindow.qml @@ -7,6 +7,7 @@ import EnumsToStringCpp 1.0 import UtilsCpp 1.0 import SettingsCpp 1.0 import DesktopToolsCpp 1.0 +import LinphoneCallsCpp AppWindow { id: mainWindow @@ -24,7 +25,7 @@ AppWindow { property var transferState: call && call.core.transferState onCallStateChanged: { - if (callState === LinphoneEnums.CallState.Connected || callState === LinphoneEnums.CallState.StreamsRunning) { + if (callState === LinphoneEnums.CallState.Connected) { if (middleItemStackView.currentItem.objectName != "inCallItem") { middleItemStackView.replace(inCallItem) bottomButtonsLayout.visible = true @@ -613,6 +614,7 @@ AppWindow { closeButtonVisible: false roundedBottom: true visible: parent.visible + currentCall: callsModel.currentCall leftPadding: 40 * DefaultStyle.dp rightPadding: 40 * DefaultStyle.dp topPadding: 41 * DefaultStyle.dp @@ -743,7 +745,7 @@ AppWindow { Layout.maximumHeight: rightPanel.height visible: callList.contentHeight > 0 leftPadding: 16 * DefaultStyle.dp - rightPadding: 16 * DefaultStyle.dp + rightPadding: 6 * DefaultStyle.dp topPadding: 15 * DefaultStyle.dp bottomPadding: 16 * DefaultStyle.dp @@ -754,7 +756,9 @@ AppWindow { contentItem: ListView { id: callList - model: callsModel + model: CallProxy { + id: callProxy + } implicitHeight: contentHeight// Math.min(contentHeight, rightPanel.height) spacing: 15 * DefaultStyle.dp clip: true @@ -800,6 +804,7 @@ AppWindow { id: listCallOptionsButton Layout.preferredWidth: 24 * DefaultStyle.dp Layout.preferredHeight: 24 * DefaultStyle.dp + Layout.rightMargin: 10 * DefaultStyle.dp popup.contentItem: ColumnLayout { spacing: 0 diff --git a/Linphone/view/App/Layout/MainLayout.qml b/Linphone/view/App/Layout/MainLayout.qml index 06d224f6b..708a3040a 100644 --- a/Linphone/view/App/Layout/MainLayout.qml +++ b/Linphone/view/App/Layout/MainLayout.qml @@ -11,6 +11,7 @@ import QtQuick.Effects import Linphone import UtilsCpp import SettingsCpp +import LinphoneAccountsCpp Item { id: mainItem @@ -65,10 +66,11 @@ Item { openContextualMenuComponent(page) } - AccountProxy { + AccountProxy { id: accountProxy onDefaultAccountChanged: if (tabbar.currentIndex === 0 && defaultAccount) defaultAccount.core.lResetMissedCalls() } + CallProxy { id: callsModel } @@ -79,7 +81,7 @@ Item { id: currentCallNotif background: Item{} closePolicy: Control.Popup.NoAutoClose - visible: currentCall + visible: currentCall && currentCall.core.state != LinphoneEnums.CallState.Idle && currentCall.core.state != LinphoneEnums.CallState.IncomingReceived && currentCall.core.state != LinphoneEnums.CallState.PushIncomingReceived @@ -444,7 +446,6 @@ Item { popup.contentItem: ColumnLayout { Accounts { id: accounts - accountProxy: accountProxy onAddAccountRequest: mainItem.addAccountRequest() onEditAccount: function(account) { avatarButton.popup.close() diff --git a/Linphone/view/App/Main.qml b/Linphone/view/App/Main.qml index bf4f6948b..b23db3987 100644 --- a/Linphone/view/App/Main.qml +++ b/Linphone/view/App/Main.qml @@ -5,6 +5,7 @@ import QtQuick.Controls import Linphone import UtilsCpp 1.0 import SettingsCpp 1.0 +import LinphoneAccountsCpp AppWindow { id: mainWindow @@ -62,9 +63,11 @@ AppWindow { } } - AccountProxy { + AccountProxy { id: accountProxy + onInitialized: initStackViewItem() } + StackView { id: mainWindowStackView anchors.fill: parent diff --git a/Linphone/view/Item/Account/Accounts.qml b/Linphone/view/Item/Account/Accounts.qml index 04873686f..784dcf0ea 100644 --- a/Linphone/view/Item/Account/Accounts.qml +++ b/Linphone/view/Item/Account/Accounts.qml @@ -7,6 +7,7 @@ import QtQuick.Dialogs import Linphone import UtilsCpp import SettingsCpp +import LinphoneAccountsCpp Item { id: mainItem @@ -16,7 +17,7 @@ Item { readonly property int leftPadding: 32 * DefaultStyle.dp readonly property int rightPadding: 32 * DefaultStyle.dp readonly property int spacing: 16 * DefaultStyle.dp - property AccountProxy accountProxy + property AccountProxy accountProxy signal addAccountRequest() signal editAccount(AccountGui account) @@ -37,7 +38,7 @@ Item { Layout.preferredHeight: contentHeight Layout.fillWidth: true spacing: mainItem.spacing - model: mainItem.accountProxy + model: LinphoneAccountsCpp delegate: Contact{ id: contactItem width: list.width diff --git a/Linphone/view/Item/Call/CallContactsLists.qml b/Linphone/view/Item/Call/CallContactsLists.qml index d020e7bc6..05f6e445a 100644 --- a/Linphone/view/Item/Call/CallContactsLists.qml +++ b/Linphone/view/Item/Call/CallContactsLists.qml @@ -62,8 +62,10 @@ FocusScope { ColumnLayout { id: content - width: parent.width spacing: 32 * DefaultStyle.dp + anchors.left: parent.left + anchors.right: parent.right + anchors.rightMargin: 39 * DefaultStyle.dp Button { id: grouCallButton visible: mainItem.groupCallVisible && !SettingsCpp.disableMeetingsFeature @@ -111,7 +113,6 @@ FocusScope { } ColumnLayout { spacing: 18 * DefaultStyle.dp - Layout.rightMargin: 39 * DefaultStyle.dp Text { text: qsTr("All contacts") font { diff --git a/Linphone/view/Item/Call/WaitingRoom.qml b/Linphone/view/Item/Call/WaitingRoom.qml index f91d67ed9..b92c9c647 100644 --- a/Linphone/view/Item/Call/WaitingRoom.qml +++ b/Linphone/view/Item/Call/WaitingRoom.qml @@ -4,6 +4,7 @@ import QtQuick.Effects import QtQuick.Controls as Control import Linphone import UtilsCpp 1.0 +import LinphoneAccountsCpp RowLayout { id: mainItem @@ -29,7 +30,7 @@ RowLayout { displayAll: false displayPresence: false mutedStatus: microButton.checked - AccountProxy{ + AccountProxy { id: accounts } account: accounts.findAccountByAddress(mainItem.localAddress) diff --git a/Linphone/view/Item/ComboBox.qml b/Linphone/view/Item/ComboBox.qml index 34548d83c..bb7d758f7 100644 --- a/Linphone/view/Item/ComboBox.qml +++ b/Linphone/view/Item/ComboBox.qml @@ -173,7 +173,7 @@ Control.ComboBox { visible: source != "" width: visible ? 20 * DefaultStyle.dp : 0 sourceSize.width: 20 * DefaultStyle.dp - source: modelData && modelData.img ? modelData.img : "" + source: typeof(modelData) != "undefined" && modelData.img ? modelData.img : "" fillMode: Image.PreserveAspectFit anchors.left: parent.left anchors.leftMargin: visible ? 10 * DefaultStyle.dp : 0 @@ -181,11 +181,13 @@ Control.ComboBox { } Text { - text: modelData + text: typeof(modelData) != "undefined" ? modelData.text ? modelData.text : modelData - : "" + : $modelData + ? $modelData + : "" elide: Text.ElideRight maximumLineCount: 1 wrapMode: Text.WrapAnywhere diff --git a/Linphone/view/Item/Contact/ContactEdition.qml b/Linphone/view/Item/Contact/ContactEdition.qml index b06b32925..8803dd5ba 100644 --- a/Linphone/view/Item/Contact/ContactEdition.qml +++ b/Linphone/view/Item/Contact/ContactEdition.qml @@ -265,7 +265,7 @@ RightPanelLayout { } TextField { id: addressTextField - onTextEdited: { + onEditingFinished: { if (text.length != 0) mainItem.contact.core.setAddressAt(index, qsTr("Adresse SIP"), text) } property string _initialText: modelData.address diff --git a/Linphone/view/Item/Contact/ContactsList.qml b/Linphone/view/Item/Contact/ContactsList.qml index 55e0c219b..90e3e3c6a 100644 --- a/Linphone/view/Item/Contact/ContactsList.qml +++ b/Linphone/view/Item/Contact/ContactsList.qml @@ -132,7 +132,7 @@ ListView { RowLayout { id: contactDelegate anchors.left: initial.visible ? initial.right : parent.left - anchors.right: actionsRow.left + anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter spacing: 10 * DefaultStyle.dp z: 1 @@ -162,127 +162,128 @@ ListView { function onSelectedContactCountChanged(){ isSelectedCheck.visible = (mainItem.selectedContacts.indexOf(modelData.core.defaultAddress) != -1)} } } + Item{Layout.fillWidth: true} + RowLayout { + id: actionsRow + z: 1 + // anchors.right: parent.right + Layout.rightMargin: 5 * DefaultStyle.dp + // anchors.verticalCenter: parent.verticalCenter + spacing: 10 * DefaultStyle.dp // TODO : change when mockup ready + RowLayout{ + id: actionButtons + visible: mainItem.actionLayoutVisible + spacing: 10 * DefaultStyle.dp + Button { + id: callButton + Layout.preferredWidth: 45 * DefaultStyle.dp + Layout.preferredHeight: 45 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + icon.source: AppIcons.phone + focus: visible + contentImageColor: DefaultStyle.main2_500main + background: Rectangle { + anchors.fill: parent + radius: 40 * DefaultStyle.dp + color: DefaultStyle.main2_200 + } + onClicked: UtilsCpp.createCall(modelData.core.defaultAddress) + KeyNavigation.right: chatButton + KeyNavigation.left: chatButton + } + Button { + id: chatButton + Layout.preferredWidth: 45 * DefaultStyle.dp + Layout.preferredHeight: 45 * DefaultStyle.dp + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + icon.source: AppIcons.chatTeardropText + focus: visible && !callButton.visible + contentImageColor: DefaultStyle.main2_500main + background: Rectangle { + anchors.fill: parent + radius: 40 * DefaultStyle.dp + color: DefaultStyle.main2_200 + } + KeyNavigation.right: callButton + KeyNavigation.left: callButton + } + } + PopupButton { + id: friendPopup + z: 1 + // Layout.rightMargin: 13 * DefaultStyle.dp + Layout.alignment: Qt.AlignVCenter + popup.x: 0 + popup.padding: 10 * DefaultStyle.dp + hoverEnabled: mainItem.hoverEnabled + visible: mainItem.contactMenuVisible && (contactArea.containsMouse || hovered || popup.opened) && (!mainItem.delegateButtons || mainItem.delegateButtons.length === 0) + + popup.contentItem: ColumnLayout { + Button { + text: modelData.core.starred ? qsTr("Enlever des favoris") : qsTr("Mettre en favori") + background: Item{} + icon.source: modelData.core.starred ? AppIcons.heartFill : AppIcons.heart + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + spacing: 10 * DefaultStyle.dp + textSize: 14 * DefaultStyle.dp + textWeight: 400 * DefaultStyle.dp + textColor: DefaultStyle.main2_500main + contentImageColor: modelData.core.starred ? DefaultStyle.danger_500main : DefaultStyle.main2_600 + onClicked: { + modelData.core.lSetStarred(!modelData.core.starred) + friendPopup.close() + } + } + Button { + text: qsTr("Partager") + background: Item{} + icon.source: AppIcons.shareNetwork + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + spacing: 10 * DefaultStyle.dp + textSize: 14 * DefaultStyle.dp + textWeight: 400 * DefaultStyle.dp + textColor: DefaultStyle.main2_500main + onClicked: { + var vcard = modelData.core.getVCard() + var username = modelData.core.givenName + modelData.core.familyName + var filepath = UtilsCpp.createVCardFile(username, vcard) + if (filepath == "") UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La création du fichier vcard a échoué"), false) + else mainWindow.showInformationPopup(qsTr("VCard créée"), qsTr("VCard du contact enregistrée dans %1").arg(filepath)) + UtilsCpp.shareByEmail(qsTr("Partage de contact"), vcard, filepath) + } + } + Button { + text: qsTr("Supprimer") + background: Item{} + icon.source: AppIcons.trashCan + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + spacing: 10 * DefaultStyle.dp + textSize: 14 * DefaultStyle.dp + textWeight: 400 * DefaultStyle.dp + textColor: DefaultStyle.danger_500main + contentImageColor: DefaultStyle.danger_500main + onClicked: { + mainItem.contactDeletionRequested(modelData) + friendPopup.close() + } + } + } + } + } } - RowLayout { - id: actionsRow - z: 1 - anchors.right: parent.right - anchors.rightMargin: 5 * DefaultStyle.dp - anchors.verticalCenter: parent.verticalCenter - spacing: 10 * DefaultStyle.dp // TODO : change when mockup ready - RowLayout{ - id: actionButtons - visible: mainItem.actionLayoutVisible - spacing: 10 * DefaultStyle.dp - Button { - id: callButton - Layout.preferredWidth: 45 * DefaultStyle.dp - Layout.preferredHeight: 45 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - icon.source: AppIcons.phone - focus: visible - contentImageColor: DefaultStyle.main2_500main - background: Rectangle { - anchors.fill: parent - radius: 40 * DefaultStyle.dp - color: DefaultStyle.main2_200 - } - onClicked: UtilsCpp.createCall(modelData.core.defaultAddress) - KeyNavigation.right: chatButton - KeyNavigation.left: chatButton - } - Button { - id: chatButton - Layout.preferredWidth: 45 * DefaultStyle.dp - Layout.preferredHeight: 45 * DefaultStyle.dp - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - icon.source: AppIcons.chatTeardropText - focus: visible && !callButton.visible - contentImageColor: DefaultStyle.main2_500main - background: Rectangle { - anchors.fill: parent - radius: 40 * DefaultStyle.dp - color: DefaultStyle.main2_200 - } - KeyNavigation.right: callButton - KeyNavigation.left: callButton - } - } - PopupButton { - id: friendPopup - z: 1 - // Layout.rightMargin: 13 * DefaultStyle.dp - Layout.alignment: Qt.AlignVCenter - popup.x: 0 - popup.padding: 10 * DefaultStyle.dp - hoverEnabled: mainItem.hoverEnabled - visible: mainItem.contactMenuVisible && (contactArea.containsMouse || hovered || popup.opened) && (!mainItem.delegateButtons || mainItem.delegateButtons.length === 0) - - popup.contentItem: ColumnLayout { - Button { - text: modelData.core.starred ? qsTr("Enlever des favoris") : qsTr("Mettre en favori") - background: Item{} - icon.source: modelData.core.starred ? AppIcons.heartFill : AppIcons.heart - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - spacing: 10 * DefaultStyle.dp - textSize: 14 * DefaultStyle.dp - textWeight: 400 * DefaultStyle.dp - textColor: DefaultStyle.main2_500main - contentImageColor: modelData.core.starred ? DefaultStyle.danger_500main : DefaultStyle.main2_600 - onClicked: { - modelData.core.lSetStarred(!modelData.core.starred) - friendPopup.close() - } - } - Button { - text: qsTr("Partager") - background: Item{} - icon.source: AppIcons.shareNetwork - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - spacing: 10 * DefaultStyle.dp - textSize: 14 * DefaultStyle.dp - textWeight: 400 * DefaultStyle.dp - textColor: DefaultStyle.main2_500main - onClicked: { - var vcard = modelData.core.getVCard() - var username = modelData.core.givenName + modelData.core.familyName - var filepath = UtilsCpp.createVCardFile(username, vcard) - if (filepath == "") UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La création du fichier vcard a échoué"), false) - else mainWindow.showInformationPopup(qsTr("VCard créée"), qsTr("VCard du contact enregistrée dans %1").arg(filepath)) - UtilsCpp.shareByEmail(qsTr("Partage de contact"), vcard, filepath) - } - } - Button { - text: qsTr("Supprimer") - background: Item{} - icon.source: AppIcons.trashCan - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - spacing: 10 * DefaultStyle.dp - textSize: 14 * DefaultStyle.dp - textWeight: 400 * DefaultStyle.dp - textColor: DefaultStyle.danger_500main - contentImageColor: DefaultStyle.danger_500main - onClicked: { - mainItem.contactDeletionRequested(modelData) - friendPopup.close() - } - } - } - } - } MouseArea { id: contactArea enabled: mainItem.selectionEnabled hoverEnabled: mainItem.hoverEnabled - anchors.fill: itemDelegate + anchors.fill: contactDelegate height: mainItem.height acceptedButtons: Qt.AllButtons z: -1 diff --git a/Linphone/view/Item/Contact/Sticker.qml b/Linphone/view/Item/Contact/Sticker.qml index 6e1dd07e8..24166219f 100644 --- a/Linphone/view/Item/Contact/Sticker.qml +++ b/Linphone/view/Item/Contact/Sticker.qml @@ -163,7 +163,7 @@ Item { } ColumnLayout { spacing: 0 - visible: mainItem.displayAll && !mainItem.remoteIsPaused + visible: mainItem.displayAll && !mainItem.remoteIsPaused && !mainItem.conference anchors.horizontalCenter: parent.horizontalCenter anchors.top: centerItem.bottom anchors.topMargin: 21 * DefaultStyle.dp diff --git a/Linphone/view/Item/Dialog.qml b/Linphone/view/Item/Dialog.qml index dbb5bc63e..c1084f1b1 100644 --- a/Linphone/view/Item/Dialog.qml +++ b/Linphone/view/Item/Dialog.qml @@ -29,8 +29,8 @@ Popup { signal rejected() contentItem: FocusScope { - width: child.implicitWidth - height: child.implicitHeight + implicitWidth: child.implicitWidth + implicitHeight: child.implicitHeight onVisibleChanged: { if(visible) forceActiveFocus() } diff --git a/Linphone/view/Item/Notification/NotificationReceivedCall.qml b/Linphone/view/Item/Notification/NotificationReceivedCall.qml index efc46ba35..83545a24f 100644 --- a/Linphone/view/Item/Notification/NotificationReceivedCall.qml +++ b/Linphone/view/Item/Notification/NotificationReceivedCall.qml @@ -89,8 +89,8 @@ Notification { imageHeight: 32 * DefaultStyle.dp } onClicked: { - mainItem.call.core.lAccept(false) UtilsCpp.openCallsWindow(mainItem.call) + mainItem.call.core.lAccept(false) } } Button { diff --git a/Linphone/view/Item/NumericPad.qml b/Linphone/view/Item/NumericPad.qml index fb74219e8..4eae2c7d5 100644 --- a/Linphone/view/Item/NumericPad.qml +++ b/Linphone/view/Item/NumericPad.qml @@ -4,27 +4,27 @@ import QtQuick.Layouts as Layout import QtQuick.Effects import Linphone import UtilsCpp - +import LinphoneCallsCpp + Control.Popup { id: mainItem - property bool closeButtonVisible: true - property bool roundedBottom: false closePolicy: Control.Popup.CloseOnEscape leftPadding: 72 * DefaultStyle.dp rightPadding: 72 * DefaultStyle.dp topPadding: 41 * DefaultStyle.dp bottomPadding: 18 * DefaultStyle.dp - onOpened: numPad.forceActiveFocus() - signal buttonPressed(string text) + property bool closeButtonVisible: true + property bool roundedBottom: false + property var currentCall onButtonPressed: (text) => { - if (callsModel.currentCall) callsModel.currentCall.core.lSendDtmf(text) + if (currentCall) currentCall.core.lSendDtmf(text) else UtilsCpp.playDtmf(text) } + onOpened: numPad.forceActiveFocus() + signal buttonPressed(string text) signal launchCall() signal wipe() - CallProxy{ - id: callsModel - } + background: Item { anchors.fill: parent Rectangle { diff --git a/Linphone/view/Layout/Call/ActiveSpeakerLayout.qml b/Linphone/view/Layout/Call/ActiveSpeakerLayout.qml index 3f38326cb..216cc05b6 100644 --- a/Linphone/view/Layout/Call/ActiveSpeakerLayout.qml +++ b/Linphone/view/Layout/Call/ActiveSpeakerLayout.qml @@ -7,6 +7,7 @@ import Linphone import EnumsToStringCpp 1.0 import UtilsCpp 1.0 import SettingsCpp 1.0 +import LinphoneAccountsCpp // ============================================================================= Item{ @@ -111,6 +112,7 @@ Item{ call: mainItem.call width: mainStackView.width height: mainStackView.height + displayAll: !mainItem.conference participantDevice: mainItem.conference && mainItem.conference.core.activeSpeaker property var address: participantDevice && participantDevice.core.address videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call && call.core.remoteVideoEnabled) @@ -168,7 +170,8 @@ Item{ anchors.bottomMargin: 10 * DefaultStyle.dp videoEnabled: preview.visible && mainItem.call && mainItem.call.core.localVideoEnabled onVideoEnabledChanged: console.log("P : " +videoEnabled + " / " +visible +" / " +mainItem.call) - property AccountProxy accounts: AccountProxy{id: accountProxy} + property AccountProxy accounts: AccountProxy {id: accountProxy + } account: accountProxy.findAccountByAddress(mainItem.localAddress) call: mainItem.call displayAll: false diff --git a/Linphone/view/Layout/Call/GridLayout.qml b/Linphone/view/Layout/Call/GridLayout.qml index f02ba8783..b79677a45 100644 --- a/Linphone/view/Layout/Call/GridLayout.qml +++ b/Linphone/view/Layout/Call/GridLayout.qml @@ -3,6 +3,7 @@ import QtQuick.Layouts import QtQml.Models import Linphone +import LinphoneAccountsCpp // ============================================================================= @@ -22,7 +23,8 @@ Mosaic { qmlName: "G" Component.onCompleted: console.log("Loaded : " +allDevices + " = " +allDevices.count) } - property AccountProxy accounts: AccountProxy{id: accountProxy} + property AccountProxy accounts: AccountProxy {id: accountProxy + } model: grid.call && grid.call.core.isConference ? participantDevices: [0,1] delegate: Item{ id: avatarCell diff --git a/Linphone/view/Page/Main/AccountSettingsPage.qml b/Linphone/view/Page/Main/AccountSettingsPage.qml index 347f5d976..bebc3e5d5 100644 --- a/Linphone/view/Page/Main/AccountSettingsPage.qml +++ b/Linphone/view/Page/Main/AccountSettingsPage.qml @@ -5,11 +5,12 @@ import QtQuick.Controls as Control import Linphone import UtilsCpp 1.0 import SettingsCpp 1.0 +import LinphoneAccountsCpp AbstractMasterDetailPage { layoutsPath: "qrc:/Linphone/view/App/Layout/Account" titleText: qsTr("Mon compte") - property AccountProxy accounts: AccountProxy{id: accountProxy} + property AccountProxy accounts: AccountProxy {id: accountProxy} property AccountGui account: accountProxy.defaultAccount signal accountRemoved() families: [ diff --git a/Linphone/view/Page/Main/CallPage.qml b/Linphone/view/Page/Main/CallPage.qml index b8bbad80e..c3024a4a3 100644 --- a/Linphone/view/Page/Main/CallPage.qml +++ b/Linphone/view/Page/Main/CallPage.qml @@ -5,6 +5,7 @@ import QtQuick.Controls as Control import Linphone import UtilsCpp import SettingsCpp +import LinphoneAccountsCpp AbstractMainPage { id: mainItem @@ -17,7 +18,7 @@ AbstractMainPage { //Group call properties property ConferenceInfoGui confInfoGui - property AccountProxy accounts: AccountProxy{id: accountProxy} + property AccountProxy accounts: AccountProxy {id: accountProxy} property AccountGui account: accountProxy.defaultAccount property var state: account && account.core.registrationState || 0 property bool isRegistered: account ? account.core.registrationState == LinphoneEnums.RegistrationState.Ok : false diff --git a/Linphone/view/Page/Main/MeetingPage.qml b/Linphone/view/Page/Main/MeetingPage.qml index ac1c7d1a7..aad8f9369 100644 --- a/Linphone/view/Page/Main/MeetingPage.qml +++ b/Linphone/view/Page/Main/MeetingPage.qml @@ -136,7 +136,7 @@ AbstractMainPage { spacing: 0 RowLayout { enabled: mainItem.leftPanelEnabled - Layout.rightMargin: 39 * DefaultStyle.dp + Layout.rightMargin: 38 * DefaultStyle.dp spacing: 0 Text { Layout.fillWidth: true @@ -163,7 +163,7 @@ AbstractMainPage { id: searchBar Layout.fillWidth: true Layout.topMargin: 18 * DefaultStyle.dp - Layout.rightMargin: 39 * DefaultStyle.dp + Layout.rightMargin: 38 * DefaultStyle.dp placeholderText: qsTr("Rechercher une réunion") KeyNavigation.up: conferenceList KeyNavigation.down: conferenceList @@ -231,9 +231,8 @@ AbstractMainPage { property bool isCreation ColumnLayout { spacing: 33 * DefaultStyle.dp - + anchors.fill: parent RowLayout { - width: 320 * DefaultStyle.dp Layout.rightMargin: 35 * DefaultStyle.dp spacing: 5 * DefaultStyle.dp Button { @@ -263,6 +262,7 @@ AbstractMainPage { } Layout.fillWidth: true } + Item {Layout.fillWidth: true} Button { id: createButton Layout.preferredWidth: 57 * DefaultStyle.dp @@ -317,6 +317,10 @@ AbstractMainPage { } createConfLayout.enabled = meetingSetup.conferenceInfoGui.core.schedulerState != LinphoneEnums.ConferenceSchedulerState.AllocationPending } + function onSaveFailed() { + var mainWin = UtilsCpp.getMainWindow() + mainWin.closeLoadingPopup() + } } onSaveSucceed: { leftPanelStackView.pop() diff --git a/Linphone/view/Prototype/AccountsPrototype.qml b/Linphone/view/Prototype/AccountsPrototype.qml index 7e6772e2c..cdcc0471a 100644 --- a/Linphone/view/Prototype/AccountsPrototype.qml +++ b/Linphone/view/Prototype/AccountsPrototype.qml @@ -3,12 +3,13 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls as Control import Linphone import UtilsCpp 1.0 +import LinphoneAccountsCpp // Snippet ListView{ id: mainItem - model: AccountProxy{} + model: AccountProxy {} function printObject(o) { var out = ''; for (var p in o) { diff --git a/Linphone/view/Prototype/CallPrototype.qml b/Linphone/view/Prototype/CallPrototype.qml index 84d4e121e..a4d751a20 100644 --- a/Linphone/view/Prototype/CallPrototype.qml +++ b/Linphone/view/Prototype/CallPrototype.qml @@ -3,6 +3,8 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls as Control import Linphone import UtilsCpp 1.0 +import LinphoneAccountsCpp +import LinphoneCallsCpp // Snippet Window { @@ -21,7 +23,6 @@ Window { onCallChanged: console.log('New Call:' +call) onClosing: { accountStatus.defaultAccount = accountStatus - accountLayout.accounts = null gc() } Component.onDestruction: gc() @@ -39,8 +40,8 @@ Window { ListView{ id: callList anchors.fill: parent - model: CallProxy{ - id: callsModel + model: CallProxy { + id: callProxy onCountChanged: console.log("count:"+count) } delegate: RectangleTest{ @@ -57,7 +58,7 @@ Window { anchors.fill: parent onClicked: { //modelData.core.lSetPaused(false) - callsModel.currentCall = modelData + callProxy.currentCall = modelData } } } @@ -69,7 +70,7 @@ Window { RowLayout { id: accountLayout Layout.fillWidth: true - property AccountProxy accounts: AccountProxy{id: accountProxy} + property AccountProxy accounts: AccountProxy {id: accountProxy} property var haveAccountVar: UtilsCpp.haveAccount() property var haveAccount: haveAccountVar ? haveAccountVar.value : false onHaveAccountChanged: { @@ -87,7 +88,7 @@ Window { ListView{ id: accountList Layout.fillHeight: true - model: AccountProxy{} + model: AccountProxy {} delegate:Rectangle{ color: "#11111111" height: 20 diff --git a/external/linphone-sdk b/external/linphone-sdk index 09ec61ae5..7f93384a7 160000 --- a/external/linphone-sdk +++ b/external/linphone-sdk @@ -1 +1 @@ -Subproject commit 09ec61ae54e4f972ac00bf5b20dd48e4aad867b1 +Subproject commit 7f93384a7206b754c1f550751a633ab1e8fee076