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 cbbd1b4a..6f3f070a 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 44d92547..c05ea101 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 6eebccb7..ab58fb10 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 9f5746c5..5fc983e9 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 fb16c36c..68e1aeba 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 18572fed..0a1a0301 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 b19bcecc..1adefddd 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 711004cc..85bfa0a9 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 119551e7..40bcf78f 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 2c8064a8..147294dd 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 9a9121b6..41a702a7 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 6894877d..a6c81bfe 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 607c01fe..9e71a8bd 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 1f1cffd4..28e7b8ca 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 1620e3a3..7205b378 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 8d76129b..1aef5560 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 b4861741..9882a40b 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 f2f3d02c..a58b64d8 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 a0f0410d..2884d416 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 abe6072f..eb749a2e 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 3e6767bb..66f134d8 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 3d5346bb..e148d467 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 8c82ff9c..4b255787 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 189a9e14..c14d703b 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 8280dc0c..9eed0290 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 ff4efcac..475cca03 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 fdbc81cd..72d24ecf 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 06d224f6..708a3040 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 bf4f6948..b23db398 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 04873686..784dcf0e 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 d020e7bc..05f6e445 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 f91d67ed..b92c9c64 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 34548d83..bb7d758f 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 b06b3292..8803dd5b 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 55e0c219..90e3e3c6 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 6e1dd07e..24166219 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 dbb5bc63..c1084f1b 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 efc46ba3..83545a24 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 fb74219e..4eae2c7d 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 3f38326c..216cc05b 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 f02ba878..b79677a4 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 347f5d97..bebc3e5d 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 b8bbad80..c3024a4a 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 ac1c7d1a..aad8f936 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 7e6772e2..cdcc0471 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 84d4e121..a4d751a2 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 09ec61ae..7f93384a 160000 --- a/external/linphone-sdk +++ b/external/linphone-sdk @@ -1 +1 @@ -Subproject commit 09ec61ae54e4f972ac00bf5b20dd48e4aad867b1 +Subproject commit 7f93384a7206b754c1f550751a633ab1e8fee076