diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp index 922947b12..e9270cae2 100644 --- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp @@ -57,7 +57,6 @@ protected: return true; QModelIndex index = sourceModel()->index(sourceRow, 0, QModelIndex()); - auto eventModel = sourceModel()->data(index); if( mEntryTypeFilter == ChatRoomModel::EntryType::CallEntry && eventModel.value() != nullptr) @@ -164,8 +163,20 @@ void ChatRoomProxyModel::setEntryTypeFilter (int type) { // ----------------------------------------------------------------------------- -bool ChatRoomProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) const { - return true; +bool ChatRoomProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const { + bool show = false; + if(mFilterText != ""){ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + auto eventModel = sourceModel()->data(index); + ChatMessageModel * chatModel = eventModel.value(); + if( chatModel){ + QRegularExpression search(QRegularExpression::escape(mFilterText), QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption); + show = chatModel->mContent.contains(search); + } + }else + show = true; + + return show; } bool ChatRoomProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { auto l = sourceModel()->data(left); @@ -278,6 +289,14 @@ void ChatRoomProxyModel::resetMessageCount(){ } } +void ChatRoomProxyModel::setFilterText(const QString& text){ + if( mFilterText != text){ + mFilterText = text; + invalidate(); + emit filterTextChanged(); + } +} + ChatRoomModel *ChatRoomProxyModel::getChatRoomModel () const{ return mChatRoomModel.get(); diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp index c933a3ed4..5dd0faa01 100644 --- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp +++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp @@ -30,105 +30,109 @@ class QWindow; class ChatRoomProxyModel : public QSortFilterProxyModel { - class ChatRoomModelFilter; - - Q_OBJECT - - Q_PROPERTY(QString peerAddress READ getPeerAddress WRITE setPeerAddress NOTIFY peerAddressChanged) - Q_PROPERTY(QString localAddress READ getLocalAddress WRITE setLocalAddress NOTIFY localAddressChanged) - Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress WRITE setFullPeerAddress NOTIFY fullPeerAddressChanged) - Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress WRITE setFullLocalAddress NOTIFY fullLocalAddressChanged) - //Q_PROPERTY(int isSecure READ isSecure WRITE setIsSecure NOTIFY isSecureChanged) - Q_PROPERTY(ChatRoomModel *chatRoomModel READ getChatRoomModel WRITE setChatRoomModel NOTIFY chatRoomModelChanged) - //Q_PROPERTY(bool isSecure MEMBER mIsSecure NOTIFY isSecureChanged) - //Q_PROPERTY(bool isRemoteComposing READ getIsRemoteComposing NOTIFY isRemoteComposingChanged) - Q_PROPERTY(QList composers READ getComposers NOTIFY isRemoteComposingChanged) - //Q_PROPERTY(bool isSecure READ getIsSecure NOTIFY isSecureChanged) - Q_PROPERTY(QString cachedText READ getCachedText) - + class ChatRoomModelFilter; + + Q_OBJECT + + Q_PROPERTY(QString peerAddress READ getPeerAddress WRITE setPeerAddress NOTIFY peerAddressChanged) + Q_PROPERTY(QString localAddress READ getLocalAddress WRITE setLocalAddress NOTIFY localAddressChanged) + Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress WRITE setFullPeerAddress NOTIFY fullPeerAddressChanged) + Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress WRITE setFullLocalAddress NOTIFY fullLocalAddressChanged) + //Q_PROPERTY(int isSecure READ isSecure WRITE setIsSecure NOTIFY isSecureChanged) + Q_PROPERTY(ChatRoomModel *chatRoomModel READ getChatRoomModel WRITE setChatRoomModel NOTIFY chatRoomModelChanged) + //Q_PROPERTY(bool isSecure MEMBER mIsSecure NOTIFY isSecureChanged) + //Q_PROPERTY(bool isRemoteComposing READ getIsRemoteComposing NOTIFY isRemoteComposingChanged) + Q_PROPERTY(QList composers READ getComposers NOTIFY isRemoteComposingChanged) + //Q_PROPERTY(bool isSecure READ getIsSecure NOTIFY isSecureChanged) + Q_PROPERTY(QString cachedText READ getCachedText) + + Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged) + public: - ChatRoomProxyModel (QObject *parent = Q_NULLPTR); - - Q_INVOKABLE QString getDisplayNameComposers()const; - Q_INVOKABLE QVariant getAt(int row); - - Q_INVOKABLE void loadMoreEntries (); - Q_INVOKABLE void setEntryTypeFilter (int type); - - Q_INVOKABLE void removeAllEntries (); - Q_INVOKABLE void removeRow (int index); - - Q_INVOKABLE void sendMessage (const QString &message); - - Q_INVOKABLE void sendFileMessage (const QString &path); - - Q_INVOKABLE void compose (const QString& text); - - Q_INVOKABLE void resetMessageCount(); - + ChatRoomProxyModel (QObject *parent = Q_NULLPTR); + + Q_INVOKABLE QString getDisplayNameComposers()const; + Q_INVOKABLE QVariant getAt(int row); + + Q_INVOKABLE void loadMoreEntries (); + Q_INVOKABLE void setEntryTypeFilter (int type); + + Q_INVOKABLE void removeAllEntries (); + Q_INVOKABLE void removeRow (int index); + + Q_INVOKABLE void sendMessage (const QString &message); + + Q_INVOKABLE void sendFileMessage (const QString &path); + + Q_INVOKABLE void compose (const QString& text); + + Q_INVOKABLE void resetMessageCount(); + + Q_INVOKABLE void setFilterText(const QString& text); + signals: - void peerAddressChanged (const QString &peerAddress); - void localAddressChanged (const QString &localAddress); - void fullPeerAddressChanged (const QString &fullPeerAddress); - void fullLocalAddressChanged (const QString &fullLocalAddress); - bool isRemoteComposingChanged (); - //bool isSecureChanged(bool secure); - - void chatRoomModelChanged(); - - void moreEntriesLoaded (int n); - - void entryTypeFilterChanged (int type); - + void peerAddressChanged (const QString &peerAddress); + void localAddressChanged (const QString &localAddress); + void fullPeerAddressChanged (const QString &fullPeerAddress); + void fullLocalAddressChanged (const QString &fullLocalAddress); + bool isRemoteComposingChanged (); + //bool isSecureChanged(bool secure); + + void chatRoomModelChanged(); + + void moreEntriesLoaded (int n); + + void entryTypeFilterChanged (int type); + void filterTextChanged(); + protected: - bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; - bool lessThan (const QModelIndex &left, const QModelIndex &right) const override; - + bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; + bool lessThan (const QModelIndex &left, const QModelIndex &right) const override; + private: - QString getPeerAddress () const; - void setPeerAddress (const QString &peerAddress); - - QString getLocalAddress () const; - void setLocalAddress (const QString &localAddress); - - QString getFullPeerAddress () const; - void setFullPeerAddress (const QString &peerAddress); - - QString getFullLocalAddress () const; - void setFullLocalAddress (const QString &localAddress); - - //bool isSecure () const; - //void setIsSecure (const int &secure); - - ChatRoomModel *getChatRoomModel() const; - void setChatRoomModel (ChatRoomModel *chatRoomModel); - - QList getComposers () const; - - QString getCachedText() const; - - void reload (ChatRoomModel *chatRoomModel); - - void handleIsActiveChanged (QWindow *window); - - void handleIsRemoteComposingChanged (); - void handleMessageReceived (const std::shared_ptr &message); - void handleMessageSent (const std::shared_ptr &message); - - int mMaxDisplayedEntries = EntriesChunkSize; - - QString mPeerAddress; - QString mLocalAddress; - QString mFullPeerAddress; - QString mFullLocalAddress; - //int mIsSecure; - static QString gCachedText; - //std::shared_ptr mChatRoom; - - - std::shared_ptr mChatRoomModel; - - static constexpr int EntriesChunkSize = 50; + QString getPeerAddress () const; + void setPeerAddress (const QString &peerAddress); + + QString getLocalAddress () const; + void setLocalAddress (const QString &localAddress); + + QString getFullPeerAddress () const; + void setFullPeerAddress (const QString &peerAddress); + + QString getFullLocalAddress () const; + void setFullLocalAddress (const QString &localAddress); + + //bool isSecure () const; + //void setIsSecure (const int &secure); + + ChatRoomModel *getChatRoomModel() const; + void setChatRoomModel (ChatRoomModel *chatRoomModel); + + QList getComposers () const; + + QString getCachedText() const; + + void reload (ChatRoomModel *chatRoomModel); + + void handleIsActiveChanged (QWindow *window); + + void handleIsRemoteComposingChanged (); + void handleMessageReceived (const std::shared_ptr &message); + void handleMessageSent (const std::shared_ptr &message); + + int mMaxDisplayedEntries = EntriesChunkSize; + + QString mPeerAddress; + QString mLocalAddress; + QString mFullPeerAddress; + QString mFullLocalAddress; + static QString gCachedText; + + QString mFilterText; + + std::shared_ptr mChatRoomModel; + + static constexpr int EntriesChunkSize = 50; }; #endif // CHAT_ROOM_PROXY_MODEL_H_ diff --git a/linphone-app/src/components/timeline/TimelineProxyModel.cpp b/linphone-app/src/components/timeline/TimelineProxyModel.cpp index eba53a093..9c9fa4219 100644 --- a/linphone-app/src/components/timeline/TimelineProxyModel.cpp +++ b/linphone-app/src/components/timeline/TimelineProxyModel.cpp @@ -103,7 +103,7 @@ bool TimelineProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sou if( !show && ( (mFilterFlags & TimelineFilter::EphemeralChatRoom) == TimelineFilter::EphemeralChatRoom)) show = timeline->getChatRoomModel()->isEphemeralEnabled(); if(show && mFilterText != ""){ - QRegularExpression search(mFilterText, QRegularExpression::CaseInsensitiveOption); + QRegularExpression search(QRegularExpression::escape(mFilterText), QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption); show = timeline->getChatRoomModel()->getSubject().contains(search) || timeline->getChatRoomModel()->getUsername().contains(search); //|| timeline->getChatRoomModel()->getFullPeerAddress().contains(search); not enough significant? diff --git a/linphone-app/ui/modules/Common/Form/Fields/TextField.qml b/linphone-app/ui/modules/Common/Form/Fields/TextField.qml index 11e127878..b6e2d880c 100644 --- a/linphone-app/ui/modules/Common/Form/Fields/TextField.qml +++ b/linphone-app/ui/modules/Common/Form/Fields/TextField.qml @@ -18,6 +18,8 @@ Controls.TextField { property var tools property QtObject textFieldStyle : TextFieldStyle.normal onTextFieldStyleChanged: if( !textFieldStyle) textFieldStyle = TextFieldStyle.normal + + signal iconClicked() // --------------------------------------------------------------------------- @@ -83,6 +85,10 @@ Controls.TextField { iconSize: parent.contentHeight visible: !parent.text + MouseArea{ + anchors.fill: parent + onClicked: textField.iconClicked() + } } bottomPadding: (statusItem.visible?statusItem.height:2) TextEdit{ diff --git a/linphone-app/ui/views/App/Main/Conversation.qml b/linphone-app/ui/views/App/Main/Conversation.qml index 824337288..258ae8f00 100644 --- a/linphone-app/ui/views/App/Main/Conversation.qml +++ b/linphone-app/ui/views/App/Main/Conversation.qml @@ -379,6 +379,7 @@ ColumnLayout { visible: SettingsModel.chatEnabled ExclusiveButtons { + id: filterButtons anchors { left: parent.left leftMargin: ConversationStyle.filters.leftMargin @@ -393,6 +394,52 @@ ColumnLayout { onClicked: Logic.updateChatFilter(button) } + // ------------------------------------------------------------------------- + // Search. + // ------------------------------------------------------------------------- + Icon { + id:searchButton + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.rightMargin: 20 + icon: 'timeline_search' + iconSize: searchBar.contentHeight + visible: !searchView.visible + MouseArea{ + anchors.fill:parent + onClicked:{ + searchView.visible = !searchView.visible + } + } + } + Rectangle{ + id:searchView + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left : filterButtons.right + anchors.rightMargin: 10 + anchors.leftMargin: 10 + visible:false + + TextField { + id:searchBar + anchors { + fill: parent + margins: 7 + } + Layout.fillWidth: true + icon: 'search' + //: 'Search in messages' : this is a placeholder when searching something in the timeline list + placeholderText: qsTr('searchMessagesPlaceholder') + + onTextChanged: chatRoomProxyModel.filterText = text + onIconClicked: searchView.visible = false + } + + } + } // ---------------------------------------------------------------------------