From b5b2c430c5f8c1ac8ab77493dccdbc1319fe7817 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 12 Mar 2019 14:17:42 +0100 Subject: [PATCH] fixed QuickView filtering system --- libretroshare/src/retroshare/rsmsgs.h | 2 + libretroshare/src/services/p3msgservice.cc | 14 +- libretroshare/src/services/p3msgservice.h | 3 +- retroshare-gui/src/gui/MessagesDialog.cpp | 143 ++++++------------ retroshare-gui/src/gui/MessagesDialog.h | 13 -- .../src/gui/msgs/MessageComposer.cpp | 3 +- retroshare-gui/src/gui/msgs/MessageModel.cpp | 48 ++++-- retroshare-gui/src/gui/msgs/MessageModel.h | 47 ++++-- 8 files changed, 132 insertions(+), 141 deletions(-) diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index 4893bb6c6..6658a53bc 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -241,6 +241,7 @@ struct MsgInfoSummary : RsSerializable RsPeerId srcId; uint32_t msgflags; + std::list msgtags; // that leaves 25 bits for user-defined tags. std::string title; int count; /* file count */ @@ -253,6 +254,7 @@ struct MsgInfoSummary : RsSerializable RS_SERIAL_PROCESS(srcId); RS_SERIAL_PROCESS(msgflags); + RS_SERIAL_PROCESS(msgtags); RS_SERIAL_PROCESS(title); RS_SERIAL_PROCESS(count); diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 3e51558d8..3e2f9902c 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -1290,6 +1290,12 @@ bool p3MsgService::MessageToDraft(MessageInfo &info, const std::string &msgParen return false; } +bool p3MsgService::getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info) +{ + RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ + return locked_getMessageTag(msgId,info); +} + bool p3MsgService::getMessageTagTypes(MsgTagType& tags) { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1413,10 +1419,8 @@ bool p3MsgService::removeMessageTagType(uint32_t tagId) return true; } -bool p3MsgService::getMessageTag(const std::string &msgId, MsgTagInfo& info) +bool p3MsgService::locked_getMessageTag(const std::string &msgId, MsgTagInfo& info) { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - uint32_t mid = atoi(msgId.c_str()); if (mid == 0) { std::cerr << "p3MsgService::MessageGetMsgTag: Unknown msgId " << msgId << std::endl; @@ -1740,6 +1744,10 @@ void p3MsgService::initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis) mis.title = msg->subject; mis.count = msg->attachment.items.size(); mis.ts = msg->sendTime; + + MsgTagInfo taginfo; + locked_getMessageTag(mis.msgId,taginfo); + mis.msgtags = taginfo.tagIds ; } void p3MsgService::initMIRsMsg(RsMsgItem *msg,const MessageInfo& info) diff --git a/libretroshare/src/services/p3msgservice.h b/libretroshare/src/services/p3msgservice.h index 658425c4f..d94df85ba 100644 --- a/libretroshare/src/services/p3msgservice.h +++ b/libretroshare/src/services/p3msgservice.h @@ -77,11 +77,11 @@ public: bool MessageToDraft(Rs::Msgs::MessageInfo &info, const std::string &msgParentId); bool MessageToTrash(const std::string &mid, bool bTrash); + bool getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info); bool getMessageTagTypes(Rs::Msgs::MsgTagType& tags); bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color); bool removeMessageTagType(uint32_t tagId); - bool getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info); /* set == false && tagId == 0 --> remove all */ bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set); @@ -142,6 +142,7 @@ public: private: void sendDistantMsgItem(RsMsgItem *msgitem); + bool locked_getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info); /** This contains the ongoing tunnel handling contacts. * The map is indexed by the hash */ diff --git a/retroshare-gui/src/gui/MessagesDialog.cpp b/retroshare-gui/src/gui/MessagesDialog.cpp index 8c218626d..5218e49b9 100644 --- a/retroshare-gui/src/gui/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/MessagesDialog.cpp @@ -92,33 +92,6 @@ #define ROW_TRASHBOX 4 -MessagesDialog::LockUpdate::LockUpdate (MessagesDialog *pDialog, bool bUpdate) -{ -#ifdef TODO - m_pDialog = pDialog; - m_bUpdate = bUpdate; - - ++m_pDialog->lockUpdate; -#endif -} - -MessagesDialog::LockUpdate::~LockUpdate () -{ -#ifdef TODO - if(--m_pDialog->lockUpdate < 0) - m_pDialog->lockUpdate = 0; - - if (m_bUpdate && m_pDialog->lockUpdate == 0) { - m_pDialog->insertMessages(); - } -#endif -} - -void MessagesDialog::LockUpdate::setUpdate(bool bUpdate) -{ - m_bUpdate = bUpdate; -} - class MessageSortFilterProxyModel: public QSortFilterProxyModel { public: @@ -149,24 +122,6 @@ MessagesDialog::MessagesDialog(QWidget *parent) inChange = false; lockUpdate = 0; - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(insertMessages())); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); - connect(ui.messageTreeWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(messageTreeWidgetCustomPopupMenu(const QPoint&))); - connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(folderlistWidgetCustomPopupMenu(QPoint))); - connect(ui.messageTreeWidget, SIGNAL(clicked(const QModelIndex&)) , this, SLOT(clicked(const QModelIndex&))); - connect(ui.messageTreeWidget, SIGNAL(doubleClicked(const QModelIndex&)) , this, SLOT(doubleClicked(const QModelIndex&))); - connect(ui.messageTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*))); - connect(ui.messageTreeWidget->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(currentChanged(const QModelIndex&))); - connect(ui.listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeBox(int))); - connect(ui.quickViewWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeQuickView(int))); - connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); - connect(ui.tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int))); - connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(newmessage())); - - connect(ui.actionTextBesideIcon, SIGNAL(triggered()), this, SLOT(buttonStyle())); - connect(ui.actionIconOnly, SIGNAL(triggered()), this, SLOT(buttonStyle())); - connect(ui.actionTextUnderIcon, SIGNAL(triggered()), this, SLOT(buttonStyle())); - ui.actionTextBesideIcon->setData(Qt::ToolButtonTextBesideIcon); ui.actionIconOnly->setData(Qt::ToolButtonIconOnly); ui.actionTextUnderIcon->setData(Qt::ToolButtonTextUnderIcon); @@ -339,6 +294,26 @@ MessagesDialog::MessagesDialog(QWidget *parent) ").arg(QString::number(2*S)).arg(QString::number(S)) ; registerHelpButton(ui.helpButton,help_str,"MessagesDialog") ; + + connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), mMessageModel, SLOT(updateMessages())); + connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); + connect(ui.messageTreeWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(messageTreeWidgetCustomPopupMenu(const QPoint&))); + connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(folderlistWidgetCustomPopupMenu(QPoint))); + connect(ui.messageTreeWidget, SIGNAL(clicked(const QModelIndex&)) , this, SLOT(clicked(const QModelIndex&))); + connect(ui.messageTreeWidget, SIGNAL(doubleClicked(const QModelIndex&)) , this, SLOT(doubleClicked(const QModelIndex&))); + connect(ui.messageTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*))); + connect(ui.messageTreeWidget->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(currentChanged(const QModelIndex&))); + connect(ui.listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeBox(int))); + connect(ui.quickViewWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeQuickView(int))); + connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); + connect(ui.tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int))); + connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(newmessage())); + + connect(ui.actionTextBesideIcon, SIGNAL(triggered()), this, SLOT(buttonStyle())); + connect(ui.actionIconOnly, SIGNAL(triggered()), this, SLOT(buttonStyle())); + connect(ui.actionTextUnderIcon, SIGNAL(triggered()), this, SLOT(buttonStyle())); + + } MessagesDialog::~MessagesDialog() @@ -830,40 +805,34 @@ void MessagesDialog::changeBox(int box_row) void MessagesDialog::changeQuickView(int newrow) { -#warning Missing code here! -#ifdef TODO Q_UNUSED(newrow); - if (inChange) { - // already in change method - return; - } - - inChange = true; - - ui.messageTreeWidget->clear(); - ui.listWidget->setCurrentItem(NULL); listMode = LIST_QUICKVIEW; - insertMessages(); - insertMsgTxtAndFiles(ui.messageTreeWidget->currentItem()); + RsMessageModel::QuickViewFilter f = RsMessageModel::QUICK_VIEW_ALL ; - inChange = false; -#endif + if(newrow >= 0) // -1 means that nothing is selected + switch(newrow) + { + case 0x00: f = RsMessageModel::QUICK_VIEW_STARRED ; break; + case 0x01: f = RsMessageModel::QUICK_VIEW_SYSTEM ; break; + case 0x02: f = RsMessageModel::QUICK_VIEW_IMPORTANT; break; + case 0x03: f = RsMessageModel::QUICK_VIEW_WORK ; break; + case 0x04: f = RsMessageModel::QUICK_VIEW_PERSONAL ; break; + case 0x05: f = RsMessageModel::QUICK_VIEW_TODO ; break; + case 0x06: f = RsMessageModel::QUICK_VIEW_LATER ; break; + default: + f = RsMessageModel::QuickViewFilter( (int)RsMessageModel::QUICK_VIEW_USER + newrow - 0x06); + } + mMessageModel->setQuickViewFilter(f); + insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex()); } void MessagesDialog::messagesTagsChanged() { -#ifdef TODO - if (lockUpdate) { - return; - } - fillQuickView(); - insertMessages(); -#endif -#warning Missing code here! + mMessageModel->updateMessages(); } static void InitIconAndFont(QTreeWidgetItem *item) @@ -1545,8 +1514,6 @@ bool MessagesDialog::getCurrentMsg(std::string &cid, std::string &mid) void MessagesDialog::removemessage() { - LockUpdate Lock (this, true); - QList selectedMessages ; getSelectedMessages(selectedMessages); @@ -1567,21 +1534,15 @@ void MessagesDialog::removemessage() rsMail->MessageToTrash(m.toStdString(), true); } } - - // LockUpdate -> insertMessages(); } void MessagesDialog::undeletemessage() { - LockUpdate Lock (this, true); - QList msgids; getSelectedMessages(msgids); foreach (const QString& s, msgids) rsMail->MessageToTrash(s.toStdString(), false); - - // LockUpdate -> insertMessages(); } void MessagesDialog::setToolbarButtonStyle(Qt::ToolButtonStyle style) @@ -1638,21 +1599,19 @@ void MessagesDialog::updateMessageSummaryList() unsigned int systemCount = 0; /* calculating the new messages */ -// rsMail->getMessageCount (&inboxCount, &newInboxCount, &newOutboxCount, &newDraftCount, &newSentboxCount); std::list msgList; - std::list::const_iterator it; - rsMail->getMessageSummaries(msgList); QMap tagCount; /* calculating the new messages */ - for (it = msgList.begin(); it != msgList.end(); ++it) { + for (auto it = msgList.begin(); it != msgList.end(); ++it) + { /* calcluate tag count */ - MsgTagInfo tagInfo; - rsMail->getMessageTag(it->msgId, tagInfo); - for (std::list::iterator tagId = tagInfo.tagIds.begin(); tagId != tagInfo.tagIds.end(); ++tagId) { + + for (auto tagId = (*it).msgtags.begin(); tagId != (*it).msgtags.end(); ++tagId) + { int nCount = tagCount [*tagId]; ++nCount; tagCount [*tagId] = nCount; @@ -1836,6 +1795,7 @@ void MessagesDialog::updateMessageSummaryList() void MessagesDialog::tagAboutToShow() { +#ifdef TODO TagsMenu *menu = dynamic_cast(ui.tagButton->menu()); if (menu == NULL) { return; @@ -1851,22 +1811,16 @@ void MessagesDialog::tagAboutToShow() rsMail->getMessageTag(msgids.front().toStdString(), tagInfo); menu->activateActions(tagInfo.tagIds); +#endif } void MessagesDialog::tagRemoveAll() { - LockUpdate Lock (this, false); - QList msgids; getSelectedMessages(msgids); foreach(const QString& s, msgids) - { rsMail->setMessageTag(s.toStdString(), 0, false); - Lock.setUpdate(true); - } - - // LockUpdate -> insertMessages(); } void MessagesDialog::tagSet(int tagId, bool set) @@ -1875,27 +1829,20 @@ void MessagesDialog::tagSet(int tagId, bool set) return; } - LockUpdate Lock (this, false); - QList msgids; getSelectedMessages(msgids); foreach (const QString& s, msgids) - if (rsMail->setMessageTag(s.toStdString(), tagId, set)) - Lock.setUpdate(true); + rsMail->setMessageTag(s.toStdString(), tagId, set); } void MessagesDialog::emptyTrash() { - LockUpdate Lock (this, true); - std::list msgs ; mMessageModel->getMessageSummaries(RsMessageModel::BOX_TRASH,msgs); for(auto it(msgs.begin());it!=msgs.end();++it) rsMail->MessageDelete(it->msgId); - - // LockUpdate -> insertMessages(); } void MessagesDialog::tabChanged(int /*tab*/) diff --git a/retroshare-gui/src/gui/MessagesDialog.h b/retroshare-gui/src/gui/MessagesDialog.h index 084ba70de..ba56f0224 100644 --- a/retroshare-gui/src/gui/MessagesDialog.h +++ b/retroshare-gui/src/gui/MessagesDialog.h @@ -105,19 +105,6 @@ private slots: void tabCloseRequested(int tab); private: - class LockUpdate - { - public: - LockUpdate (MessagesDialog *pDialog, bool bUpdate); - ~LockUpdate (); - - void setUpdate(bool bUpdate); - - private: - MessagesDialog *m_pDialog; - bool m_bUpdate; - }; - void updateInterface(); void connectActions(); diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.cpp b/retroshare-gui/src/gui/msgs/MessageComposer.cpp index 7c2db10eb..8f485b410 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.cpp +++ b/retroshare-gui/src/gui/msgs/MessageComposer.cpp @@ -976,7 +976,8 @@ MessageComposer *MessageComposer::newMsg(const std::string &msgId /* = ""*/) msgComposer->addEmptyRecipient(); - if (msgId.empty() == false) { + if (!msgId.empty()) + { // fill existing message MessageInfo msgInfo; if (!rsMail->getMessage(msgId, msgInfo)) { diff --git a/retroshare-gui/src/gui/msgs/MessageModel.cpp b/retroshare-gui/src/gui/msgs/MessageModel.cpp index cd32dd05a..eccff958b 100644 --- a/retroshare-gui/src/gui/msgs/MessageModel.cpp +++ b/retroshare-gui/src/gui/msgs/MessageModel.cpp @@ -50,6 +50,7 @@ RsMessageModel::RsMessageModel(QObject *parent) { mFilteringEnabled=false; mCurrentBox = BOX_NONE; + mQuickViewFilter = QUICK_VIEW_ALL; } void RsMessageModel::preMods() @@ -295,9 +296,29 @@ QVariant RsMessageModel::statusRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col return QVariant();//fmpe.mMsgStatus); } +bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const +{ + QString s = displayRole(fmpe,mFilterColumn).toString(); + bool passes_strings = true ; + + if(!mFilterStrings.empty()) + for(auto iter(mFilterStrings.begin()); iter != mFilterStrings.end(); ++iter) + passes_strings = passes_strings && s.contains(*iter,Qt::CaseInsensitive); + else + passes_strings = true; + + bool passes_quick_view = + (mQuickViewFilter==QUICK_VIEW_ALL) + || (std::find(fmpe.msgtags.begin(),fmpe.msgtags.end(),mQuickViewFilter) != fmpe.msgtags.end()) + || (mQuickViewFilter==QUICK_VIEW_STARRED && (fmpe.msgflags & RS_MSG_STAR)) + || (mQuickViewFilter==QUICK_VIEW_SYSTEM && (fmpe.msgflags & RS_MSG_SYSTEM)); + + return passes_quick_view && passes_strings; +} + QVariant RsMessageModel::filterRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const { - if(!mFilteringEnabled) + if(passesFilter(fmpe,column)) return QVariant(FilterString); return QVariant(QString()); @@ -312,20 +333,12 @@ uint32_t RsMessageModel::updateFilterStatus(ForumModelIndex i,int column,const Q } -void RsMessageModel::setFilter(int column,const QStringList& strings,uint32_t& count) +void RsMessageModel::setFilter(int column,const QStringList& strings) { preMods(); - if(!strings.empty()) - { - count = updateFilterStatus(ForumModelIndex(0),column,strings); - mFilteringEnabled = true; - } - else - { - count=0; - mFilteringEnabled = false; - } + mFilterColumn = column; + mFilterStrings = strings; postMods(); } @@ -557,6 +570,16 @@ void RsMessageModel::setCurrentBox(BoxName bn) } } +void RsMessageModel::setQuickViewFilter(QuickViewFilter fn) +{ + if(fn != mQuickViewFilter) + { + preMods(); + mQuickViewFilter = fn ; + postMods(); + } +} + void RsMessageModel::getMessageSummaries(BoxName box,std::list& msgs) { rsMsgs->getMessageSummaries(msgs); @@ -575,6 +598,7 @@ void RsMessageModel::getMessageSummaries(BoxName box,std::listmsgflags & RS_MSG_BOXMASK) == RS_MSG_DRAFTBOX ; break ; case BOX_TRASH : ok = (it->msgflags & RS_MSG_TRASH) ; break ; default: + ++it; continue; } diff --git a/retroshare-gui/src/gui/msgs/MessageModel.h b/retroshare-gui/src/gui/msgs/MessageModel.h index baf2c45ba..5e7f78d9f 100644 --- a/retroshare-gui/src/gui/msgs/MessageModel.h +++ b/retroshare-gui/src/gui/msgs/MessageModel.h @@ -53,17 +53,29 @@ public: }; enum Columns { - COLUMN_THREAD_STAR =0x00, - COLUMN_THREAD_ATTACHMENT =0x01, - COLUMN_THREAD_SUBJECT =0x02, - COLUMN_THREAD_READ =0x03, - COLUMN_THREAD_AUTHOR =0x04, - COLUMN_THREAD_DATE =0x05, - COLUMN_THREAD_TAGS =0x06, - COLUMN_THREAD_MSGID =0x07, - COLUMN_THREAD_NB_COLUMNS =0x08, + COLUMN_THREAD_STAR = 0x00, + COLUMN_THREAD_ATTACHMENT = 0x01, + COLUMN_THREAD_SUBJECT = 0x02, + COLUMN_THREAD_READ = 0x03, + COLUMN_THREAD_AUTHOR = 0x04, + COLUMN_THREAD_DATE = 0x05, + COLUMN_THREAD_TAGS = 0x06, + COLUMN_THREAD_MSGID = 0x07, + COLUMN_THREAD_NB_COLUMNS = 0x08, }; + enum QuickViewFilter { + QUICK_VIEW_ALL = 0x00, + QUICK_VIEW_IMPORTANT = 0x01, // These numbers have been carefuly chosen to match the ones in rsmsgs.h + QUICK_VIEW_WORK = 0x02, + QUICK_VIEW_PERSONAL = 0x03, + QUICK_VIEW_TODO = 0x04, + QUICK_VIEW_LATER = 0x05, + QUICK_VIEW_STARRED = 0x06, + QUICK_VIEW_SYSTEM = 0x07, + QUICK_VIEW_USER = 100 + }; + enum Roles{ SortRole = Qt::UserRole+1, StatusRole = Qt::UserRole+2, UnreadRole = Qt::UserRole+3, @@ -77,15 +89,16 @@ public: QModelIndex getIndexOfMessage(const std::string &mid) const; static const QString FilterString ; - static void getMessageSummaries(BoxName box,std::list& msgs); + static void getMessageSummaries(BoxName box, std::list& msgs); // This method will asynchroneously update the data void setCurrentBox(BoxName bn) ; - void updateMessages(); + void setQuickViewFilter(QuickViewFilter fn) ; + const RsMessageId& currentMessageId() const; - void setFilter(int column, const QStringList& strings, uint32_t &count) ; + void setFilter(int column, const QStringList& strings) ; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -125,11 +138,14 @@ public: void setMsgReadStatus(const QModelIndex& i, bool read_status); void setMsgStar(const QModelIndex& index,bool star) ; +public slots: + void updateMessages(); + signals: void messagesLoaded(); // emitted after the messages have been set. Can be used to updated the UI. private: - bool mFilteringEnabled; + bool passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const; void preMods() ; void postMods() ; @@ -153,5 +169,10 @@ private: QColor mTextColorMissing ; BoxName mCurrentBox ; + QuickViewFilter mQuickViewFilter ; + QStringList mFilterStrings; + int mFilterColumn; + bool mFilteringEnabled; + std::vector mMessages; };