From 8ad4d8be1ec7fef5dc0c7700c4e7da8339d885cf Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Wed, 6 Nov 2024 18:05:45 +0100 Subject: [PATCH] Fixes magic search : - remove suggestions items if already in contacts. - display sip address. --- Linphone/core/search/MagicSearchList.cpp | 4 +- Linphone/core/search/MagicSearchProxy.cpp | 46 +++++++++++++++++-- Linphone/core/search/MagicSearchProxy.hpp | 9 +++- Linphone/model/tool/ToolModel.cpp | 2 - .../Display/Contact/ContactListView.qml | 40 +++++++++------- Linphone/view/Page/Form/Call/NewCallForm.qml | 5 +- .../Page/Form/Meeting/AddParticipantsForm.qml | 3 +- Linphone/view/Page/Layout/Main/MainLayout.qml | 5 +- 8 files changed, 82 insertions(+), 32 deletions(-) diff --git a/Linphone/core/search/MagicSearchList.cpp b/Linphone/core/search/MagicSearchList.cpp index b4c7fb100..61fc41c13 100644 --- a/Linphone/core/search/MagicSearchList.cpp +++ b/Linphone/core/search/MagicSearchList.cpp @@ -194,8 +194,7 @@ QVariant MagicSearchList::data(const QModelIndex &index, int role) const { } int MagicSearchList::findFriendIndexByAddress(const QString &address) { - int i = 0; - for (int i = 0; i < getCount();) { + for (int i = 0; i < getCount(); ++i) { auto friendCore = getAt(i); if (!friendCore) continue; for (auto &friendAddress : friendCore->getAllAddresses()) { @@ -204,7 +203,6 @@ int MagicSearchList::findFriendIndexByAddress(const QString &address) { return i; } } - ++i; } return -1; } diff --git a/Linphone/core/search/MagicSearchProxy.cpp b/Linphone/core/search/MagicSearchProxy.cpp index 75ced5c0d..97894bab3 100644 --- a/Linphone/core/search/MagicSearchProxy.cpp +++ b/Linphone/core/search/MagicSearchProxy.cpp @@ -71,15 +71,24 @@ void MagicSearchProxy::setList(QSharedPointer newList) { if (oldModel) { sortFilterList->mShowFavoritesOnly = oldModel->mShowFavoritesOnly; sortFilterList->mShowLdapContacts = oldModel->mShowLdapContacts; + sortFilterList->mHideListProxy = oldModel->mHideListProxy; + if (sortFilterList->mHideListProxy) { + connect(sortFilterList->mHideListProxy, &MagicSearchProxy::countChanged, sortFilterList, + [this, sortFilterList]() { sortFilterList->invalidate(); }); + connect(sortFilterList, &MagicSearchProxy::modelReset, sortFilterList, + [this, sortFilterList]() { sortFilterList->invalidate(); }); + } } setSourceModels(sortFilterList); } int MagicSearchProxy::findFriendIndexByAddress(const QString &address) { auto magicSearchList = getListModel(); - if (magicSearchList) - return mapFromSource(magicSearchList->index(magicSearchList->findFriendIndexByAddress(address), 0)).row(); - else return -1; + if (magicSearchList) { + auto listIndex = magicSearchList->findFriendIndexByAddress(address); + if (listIndex == -1) return -1; + return dynamic_cast(sourceModel())->mapFromSource(magicSearchList->index(listIndex, 0)).row(); + } else return -1; } QString MagicSearchProxy::getSearchText() const { @@ -122,6 +131,25 @@ void MagicSearchProxy::setParentProxy(MagicSearchProxy *proxy) { emit parentProxyChanged(); } +MagicSearchProxy *MagicSearchProxy::getHideListProxy() const { + auto list = dynamic_cast(sourceModel()); + return list ? list->mHideListProxy : nullptr; +} + +void MagicSearchProxy::setHideListProxy(MagicSearchProxy *proxy) { + auto list = dynamic_cast(sourceModel()); + if (list && list->mHideListProxy != proxy) { + if (list->mHideListProxy) list->disconnect(list->mHideListProxy); + list->mHideListProxy = proxy; + list->invalidate(); + if (proxy) { + connect(proxy, &MagicSearchProxy::countChanged, list, [this, list]() { list->invalidate(); }); + connect(proxy, &MagicSearchProxy::modelReset, list, [this, list]() { list->invalidate(); }); + } + emit hideListProxyChanged(); + } +} + LinphoneEnums::MagicSearchAggregation MagicSearchProxy::getAggregationFlag() const { return mAggregationFlag; } @@ -135,10 +163,18 @@ void MagicSearchProxy::setAggregationFlag(LinphoneEnums::MagicSearchAggregation bool MagicSearchProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { auto friendCore = getItemAtSource(sourceRow); + auto toShow = false; if (friendCore) { - return (!mShowFavoritesOnly || friendCore->getStarred()) && (mShowLdapContacts || !friendCore->isLdap()); + toShow = (!mShowFavoritesOnly || friendCore->getStarred()) && (mShowLdapContacts || !friendCore->isLdap()); + if (toShow && mHideListProxy) { + for (auto &friendAddress : friendCore->getAllAddresses()) { + toShow = mHideListProxy->findFriendIndexByAddress(friendAddress.toMap()["address"].toString()) == -1; + if (!toShow) break; + } + } } - return false; + + return toShow; } bool MagicSearchProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const { diff --git a/Linphone/core/search/MagicSearchProxy.hpp b/Linphone/core/search/MagicSearchProxy.hpp index 6419e736a..4ffecd00b 100644 --- a/Linphone/core/search/MagicSearchProxy.hpp +++ b/Linphone/core/search/MagicSearchProxy.hpp @@ -36,10 +36,13 @@ class MagicSearchProxy : public LimitProxy { NOTIFY aggregationFlagChanged) Q_PROPERTY(bool showFavoritesOnly READ showFavoritesOnly WRITE setShowFavoritesOnly NOTIFY showFavoriteOnlyChanged) Q_PROPERTY(MagicSearchProxy *parentProxy WRITE setParentProxy NOTIFY parentProxyChanged) + Q_PROPERTY(MagicSearchProxy *hideListProxy READ getHideListProxy WRITE setHideListProxy NOTIFY hideListProxyChanged) + Q_PROPERTY(bool showLdapContacts READ showLdapContacts WRITE setShowLdapContacts CONSTANT) public: - DECLARE_SORTFILTER_CLASS(bool mShowFavoritesOnly = false; bool mShowLdapContacts = false;) + DECLARE_SORTFILTER_CLASS(bool mShowFavoritesOnly = false; bool mShowLdapContacts = false; + MagicSearchProxy *mHideListProxy = nullptr;) MagicSearchProxy(QObject *parent = Q_NULLPTR); ~MagicSearchProxy(); @@ -62,6 +65,9 @@ public: void setList(QSharedPointer list); Q_INVOKABLE void setParentProxy(MagicSearchProxy *proxy); + MagicSearchProxy *getHideListProxy() const; + void setHideListProxy(MagicSearchProxy *proxy); + // Q_INVOKABLE forceUpdate(); Q_INVOKABLE int findFriendIndexByAddress(const QString &address); @@ -73,6 +79,7 @@ signals: void friendCreated(int index); void showFavoriteOnlyChanged(); void parentProxyChanged(); + void hideListProxyChanged(); void initialized(); protected: diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp index be1b1fa01..e2f75855f 100644 --- a/Linphone/model/tool/ToolModel.cpp +++ b/Linphone/model/tool/ToolModel.cpp @@ -299,8 +299,6 @@ bool ToolModel::friendIsInFriendList(const std::shared_ptr const std::shared_ptr &f) { for (auto contact : friendList->getFriends()) { if (f == contact) { - qWarning() << Utils::coreStringToAppString(f->getAddress()->asStringUriOnly()) << " / " - << Utils::coreStringToAppString(contact->getAddress()->asStringUriOnly()); return true; } } diff --git a/Linphone/view/Control/Display/Contact/ContactListView.qml b/Linphone/view/Control/Display/Contact/ContactListView.qml index 0bef1540a..18fe8f85c 100644 --- a/Linphone/view/Control/Display/Contact/ContactListView.qml +++ b/Linphone/view/Control/Display/Contact/ContactListView.qml @@ -11,11 +11,11 @@ ListView { id: mainItem height: contentHeight visible: contentHeight > 0 - clip: true + clip: true + currentIndex: -1 //keyNavigationWraps: true // rightMargin: 5 * DefaultStyle.dp - property bool selectionEnabled: true property bool hoverEnabled: true // dots popup menu @@ -25,11 +25,12 @@ ListView { property bool initialHeadersVisible: true property bool displayNameCapitalization: true property bool showFavoritesOnly: false - property bool showDefaultAddress: false + property bool showDefaultAddress: true property bool showLdapContacts: false property bool searchOnInitialization: false property var listProxy: MagicSearchProxy{} + property alias hideListProxy: magicSearchProxy.hideListProxy // Model properties // set searchBarText without specifying a model to bold @@ -44,20 +45,9 @@ ListView { property bool multiSelectionEnabled: false property list selectedContacts property int selectedContactCount: selectedContacts.length - Component.onCompleted: { - if (confInfoGui) { - for(var i = 0; i < confInfoGui.core.participants.length; ++i) { - selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i)); - } - } - } - currentIndex: -1 property FriendGui selectedContact: model.getAt(currentIndex) || null - onCurrentIndexChanged: selectedContact = model.getAt(currentIndex) || null - onCountChanged: selectedContact = model.getAt(currentIndex) || null - signal contactStarredChanged() signal contactDeletionRequested(FriendGui contact) signal contactAddedToSelection(string address) @@ -94,6 +84,21 @@ ListView { contactRemovedFromSelection(address) } } + function haveAddress(address){ + var index = magicSearchProxy.findFriendIndexByAddress(address) + return index != -1 + } + + onCurrentIndexChanged: selectedContact = model.getAt(currentIndex) || null + onCountChanged: selectedContact = model.getAt(currentIndex) || null + + Component.onCompleted: { + if (confInfoGui) { + for(var i = 0; i < confInfoGui.core.participants.length; ++i) { + selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i)); + } + } + } // strange behaviour with this lines // When a popup opens after clicking on a contact, the selected contact @@ -109,13 +114,13 @@ ListView { // considering its starred status. Otherwise, the row in the list still // exists even if its delegate is not visible, and creates navigation issues showFavoritesOnly: mainItem.showFavoritesOnly - onFriendCreated: (index) => { - mainItem.currentIndex = index - } aggregationFlag: mainItem.aggregationFlag parentProxy: mainItem.listProxy showLdapContacts: mainItem.showLdapContacts sourceFlags: mainItem.sourceFlags + onFriendCreated: (index) => { + mainItem.currentIndex = index + } onInitialized: { if(mainItem.searchOnInitialization) magicSearchProxy.forceUpdate() } @@ -201,6 +206,7 @@ ListView { Layout.topMargin: 2 * DefaultStyle.dp visible: mainItem.showDefaultAddress text: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(modelData.core.defaultAddress) : modelData.core.defaultAddress + font { weight: 300 * DefaultStyle.dp pixelSize: 12 * DefaultStyle.dp diff --git a/Linphone/view/Page/Form/Call/NewCallForm.qml b/Linphone/view/Page/Form/Call/NewCallForm.qml index 918c12efb..b4bfd77c5 100644 --- a/Linphone/view/Page/Form/Call/NewCallForm.qml +++ b/Linphone/view/Page/Form/Call/NewCallForm.qml @@ -181,15 +181,16 @@ FocusScope { } ContactListView{ id: searchList - contactMenuVisible: false Layout.fillWidth: true Layout.fillHeight: true - Control.ScrollBar.vertical.visible: false Layout.preferredHeight: contentHeight + contactMenuVisible: false + Control.ScrollBar.vertical.visible: false initialHeadersVisible: false displayNameCapitalization: false searchBarText: searchBar.text sourceFlags: LinphoneEnums.MagicSearchSource.All + hideListProxy: contactList.model onContactClicked: (contact) => { mainItem.contactClicked(contact) } diff --git a/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml b/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml index ef69c4bc2..a6b9060cb 100644 --- a/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml +++ b/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml @@ -156,17 +156,18 @@ FocusScope{ Layout.fillWidth: true Layout.fillHeight: true Layout.preferredHeight: contentHeight + Control.ScrollBar.vertical.visible: false contactMenuVisible: false searchBarText: searchbar.text sourceFlags: LinphoneEnums.MagicSearchSource.All multiSelectionEnabled: true displayNameCapitalization: false + hideListProxy: contactList.model onContactAddedToSelection: (address) => { contactList.addContactToSelection(address) participantList.positionViewAtEnd() } onContactRemovedFromSelection: (address) => contactList.removeSelectedContactByAddress(address) - Control.ScrollBar.vertical.visible: false } } } diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index fbc86a472..bd6c06f31 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -280,8 +280,9 @@ Item { footer: FocusScope{ id: suggestionFocusScope width: contactList.width - height: content.implicitHeight + height: visible ? content.implicitHeight : 0 onActiveFocusChanged: if(activeFocus) contactList.positionViewAtEnd() + visible: !contactList.haveAddress(suggestionText.text) Rectangle{ anchors.left: parent.left anchors.right: parent.right @@ -317,12 +318,14 @@ Item { RowLayout { id: suggestionRow spacing: 10 * DefaultStyle.dp + Avatar { Layout.preferredWidth: 45 * DefaultStyle.dp Layout.preferredHeight: 45 * DefaultStyle.dp _address: magicSearchBar.text } Text { + id: suggestionText property var urlObj: UtilsCpp.interpretUrl(magicSearchBar.text) text: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(urlObj?.value) : urlObj?.value font {