Add search feature in messages

This commit is contained in:
Julien Wadel 2021-08-24 20:36:54 +02:00
parent 479869cf22
commit 0fa9d7b136
5 changed files with 175 additions and 99 deletions

View file

@ -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<ChatCallModel*>() != 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<ChatMessageModel*>();
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();

View file

@ -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<QString> 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<QString> 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<QString> getComposers () const;
QString getCachedText() const;
void reload (ChatRoomModel *chatRoomModel);
void handleIsActiveChanged (QWindow *window);
void handleIsRemoteComposingChanged ();
void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
void handleMessageSent (const std::shared_ptr<linphone::ChatMessage> &message);
int mMaxDisplayedEntries = EntriesChunkSize;
QString mPeerAddress;
QString mLocalAddress;
QString mFullPeerAddress;
QString mFullLocalAddress;
//int mIsSecure;
static QString gCachedText;
//std::shared_ptr<linphone::ChatRoom> mChatRoom;
std::shared_ptr<ChatRoomModel> 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<QString> getComposers () const;
QString getCachedText() const;
void reload (ChatRoomModel *chatRoomModel);
void handleIsActiveChanged (QWindow *window);
void handleIsRemoteComposingChanged ();
void handleMessageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
void handleMessageSent (const std::shared_ptr<linphone::ChatMessage> &message);
int mMaxDisplayedEntries = EntriesChunkSize;
QString mPeerAddress;
QString mLocalAddress;
QString mFullPeerAddress;
QString mFullLocalAddress;
static QString gCachedText;
QString mFilterText;
std::shared_ptr<ChatRoomModel> mChatRoomModel;
static constexpr int EntriesChunkSize = 50;
};
#endif // CHAT_ROOM_PROXY_MODEL_H_

View file

@ -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?

View file

@ -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{

View file

@ -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
}
}
}
// ---------------------------------------------------------------------------