From a51eba1db2be0e77728ee5d1375b4b79472460c4 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 1 Dec 2018 16:09:35 +0100 Subject: [PATCH] added filtering mechanism in ForumModel --- .../src/gui/gxsforums/GxsForumModel.cpp | 44 ++++++++++- .../src/gui/gxsforums/GxsForumModel.h | 6 ++ .../gui/gxsforums/GxsForumThreadWidget.cpp | 75 +++++++++++-------- 3 files changed, 91 insertions(+), 34 deletions(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp index d3609c197..37d7ead53 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp @@ -10,6 +10,7 @@ #include "GxsForumModel.h" #include "retroshare/rsgxsflags.h" #include "retroshare/rsgxsforums.h" +#include "retroshare/rsexpr.h" //#define DEBUG_FORUMMODEL @@ -17,6 +18,8 @@ Q_DECLARE_METATYPE(RsMsgMetaData); std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere +const QString RsGxsForumModel::FilterString("filtered"); + RsGxsForumModel::RsGxsForumModel(QObject *parent) : QAbstractItemModel(parent) { @@ -307,6 +310,7 @@ QVariant RsGxsForumModel::data(const QModelIndex &index, int role) const case Qt::TextColorRole: return textColorRole (fmpe,index.column()) ; case Qt::BackgroundRole: return backgroundRole(fmpe,index.column()) ; + case FilterRole: return filterRole (fmpe,index.column()) ; case ThreadPinnedRole: return pinnedRole (fmpe,index.column()) ; case MissingRole: return missingRole (fmpe,index.column()) ; case StatusRole: return statusRole (fmpe,index.column()) ; @@ -337,10 +341,41 @@ QVariant RsGxsForumModel::statusRole(const ForumModelPostEntry& fmpe,int column) return QVariant(fmpe.mMsgStatus); } +QVariant RsGxsForumModel::filterRole(const ForumModelPostEntry& fmpe,int column) const +{ + if(mFilterColumn < 0) + return QVariant(QString()); + + switch(mFilterColumn) + { + case COLUMN_THREAD_TITLE: + { + for(auto iter(mFilterStrings.begin()); iter != mFilterStrings.end(); ++iter) + if(fmpe.mTitle.end() != std::search( fmpe.mTitle.begin(), fmpe.mTitle.end(), (*iter).begin(), (*iter).end(), RsRegularExpression::CompareCharIC() )) + return QVariant(FilterString); + + return QVariant(QString()); + } + + default: + return QVariant(FilterString); + } +} + +void RsGxsForumModel::setFilter(int column,const std::list& strings) +{ + mFilterColumn = column; + mFilterStrings = strings; + + emit layoutAboutToBeChanged(); + emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(0,COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL)); + emit layoutChanged(); +} + QVariant RsGxsForumModel::missingRole(const ForumModelPostEntry& fmpe,int column) const { - if(column != COLUMN_THREAD_DATA) - return QVariant(); +// if(column != COLUMN_THREAD_DATA) +// return QVariant(); if(fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_IS_MISSING) return QVariant(true); @@ -455,7 +490,10 @@ QVariant RsGxsForumModel::displayRole(const ForumModelPostEntry& fmpe,int col) c return QVariant(QString::fromUtf8(fmpe.mTitle.c_str())); case COLUMN_THREAD_READ:return QVariant(); - case COLUMN_THREAD_DATE: { + case COLUMN_THREAD_DATE:{ + if(fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_IS_MISSING) + return QVariant(QString()); + QDateTime qtime; qtime.setTime_t(fmpe.mPublishTs); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.h b/retroshare-gui/src/gui/gxsforums/GxsForumModel.h index 78fd9f6e3..4637b1be1 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.h @@ -78,11 +78,14 @@ public: MissingRole = Qt::UserRole+3, StatusRole = Qt::UserRole+4, UnreadChildrenRole = Qt::UserRole+5, + FilterRole = Qt::UserRole+6, }; QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;} QModelIndex getIndexOfMessage(const RsGxsMessageId& mid) const; + static const QString FilterString ; + std::vector > getPostVersions(const RsGxsMessageId& mid) const; #ifdef TO_REMOVE @@ -117,6 +120,7 @@ public: void setTextColorMissing (QColor color) { mTextColorMissing = color;} void setMsgReadStatus(const QModelIndex &i, bool read_status, bool with_children); + void setFilter(int column,const std::list& strings) ; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -142,6 +146,7 @@ public: QVariant authorRole (const ForumModelPostEntry& fmpe, int col) const; QVariant sortRole (const ForumModelPostEntry& fmpe, int col) const; QVariant fontRole (const ForumModelPostEntry& fmpe, int col) const; + QVariant filterRole (const ForumModelPostEntry& fmpe, int col) const; QVariant textColorRole (const ForumModelPostEntry& fmpe, int col) const; QVariant backgroundRole(const ForumModelPostEntry& fmpe, int col) const; @@ -160,6 +165,7 @@ private: bool mUseChildTS; bool mFlatView; int mFilterColumn; + std::list mFilterStrings; void *getParentRef(void *ref,int& row) const; void *getChildRef(void *ref,int row) const; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index c2a12b426..329839131 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -100,12 +100,6 @@ class DistributionItemDelegate: public QStyledItemDelegate public: DistributionItemDelegate() {} - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override - { - const QRect r = option.rect; - return QSize(r.height(),r.height()); - } - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if(!index.isValid()) @@ -130,11 +124,11 @@ public: switch(warning_level) { + default: + case 3: case 0: icon = QIcon(IMAGE_VOID); break; case 1: icon = QIcon(IMAGE_WARNING_YELLOW); break; case 2: icon = QIcon(IMAGE_WARNING_RED); break; - default: - case 3: icon = QIcon(IMAGE_WARNING_UNKNOWN); break; } QPixmap pix = icon.pixmap(r.size()); @@ -225,7 +219,7 @@ public: QPixmap pix = icon.pixmap(r.size()); - return QSize(pix.width() + fm.width(str),std::max(1.1*pix.height(),1.4*fm.height())); + return QSize(1.2*(pix.width() + fm.width(str)),std::max(1.1*pix.height(),1.4*fm.height())); } virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override @@ -261,12 +255,17 @@ public: else icon = *icons.begin(); - QPixmap pix = icon.pixmap(r.size()); + if(index.data(RsGxsForumModel::MissingRole).toBool()) + painter->drawText(r.topLeft() + QPoint(f/2.0,f*1.0), tr("[None]")); + else + { + QPixmap pix = icon.pixmap(r.size()); + const QPoint p = QPoint(pix.width()/2.0, (r.height() - pix.height())/2); - // draw pixmap at center of item - const QPoint p = QPoint(pix.width()/2.0, (r.height() - pix.height())/2); - painter->drawPixmap(r.topLeft() + p, pix); - painter->drawText(r.topLeft() + p + QPoint(pix.width()+f/2.0,f*0.8), str); + // draw pixmap at center of item + painter->drawPixmap(r.topLeft() + p, pix); + painter->drawText(r.topLeft() + p + QPoint(pix.width()+f/2.0,f*1.0), str); + } } }; @@ -375,6 +374,9 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget mThreadProxyModel->setSortRole(RsGxsForumModel::SortRole); ui->threadTreeWidget->setModel(mThreadProxyModel); + mThreadProxyModel->setFilterRole(RsGxsForumModel::FilterRole); + mThreadProxyModel->setFilterRegExp(QRegExp(QString(RsGxsForumModel::FilterString))) ; + ui->threadTreeWidget->setSortingEnabled(true); //ui->threadTreeWidget->setDynamicSortFilter(true);// is that useful?? @@ -419,14 +421,6 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget itemDelegate->setOnlyPlainText(true); ui->threadTreeWidget->setItemDelegate(itemDelegate); - float f = QFontMetricsF(font()).height()/14.0f ; - - QHeaderView * ttheader = ui->threadTreeWidget->header () ; - ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_DATE, 140*f); - ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_TITLE, 440*f); - ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, 24*f); - ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_AUTHOR, 150*f); - #ifdef SUSPENDED_CODE /* Set text of column "Read" to empty - without this the column has a number as header text */ QTreeWidgetItem *headerItem = ui->threadTreeWidget->headerItem(); @@ -449,16 +443,25 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget // load settings processSettings(true); + float f = QFontMetricsF(font()).height()/14.0f ; + /* Set header resize modes and initial section sizes */ + + QHeaderView * ttheader = ui->threadTreeWidget->header () ; + ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_DATE, 140*f); + ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_TITLE, 440*f); + ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, 24*f); + ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_AUTHOR, 150*f); + ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_READ, 24*f); + QHeaderView_setSectionResizeModeColumn(ttheader, RsGxsForumModel::COLUMN_THREAD_TITLE, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(ttheader, RsGxsForumModel::COLUMN_THREAD_READ, QHeaderView::Fixed); QHeaderView_setSectionResizeModeColumn(ttheader, RsGxsForumModel::COLUMN_THREAD_DATE, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(ttheader, RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, QHeaderView::ResizeToContents); QHeaderView_setSectionResizeModeColumn(ttheader, RsGxsForumModel::COLUMN_THREAD_AUTHOR, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(ttheader, RsGxsForumModel::COLUMN_THREAD_READ, QHeaderView::Fixed); + QHeaderView_setSectionResizeModeColumn(ttheader, RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, QHeaderView::Fixed); ui->threadTreeWidget->header()->setCascadingSectionResizes(true); /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ - ttheader->resizeSection (RsGxsForumModel::COLUMN_THREAD_READ, 24*f); ttheader->hideSection (RsGxsForumModel::COLUMN_THREAD_CONTENT); ttheader->hideSection (RsGxsForumModel::COLUMN_THREAD_MSGID); ttheader->hideSection (RsGxsForumModel::COLUMN_THREAD_DATA); @@ -2685,14 +2688,24 @@ void GxsForumThreadWidget::filterColumnChanged(int column) void GxsForumThreadWidget::filterItems(const QString& text) { -#ifdef TODO + //FileSearchFlags flags = isRemote()?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL; + QStringList lst = text.split(" ",QString::SkipEmptyParts) ; + std::list keywords ; + + for(auto it(lst.begin());it!=lst.end();++it) + keywords.push_back((*it).toStdString()); + int filterColumn = ui->filterLineEdit->currentFilter(); - int count = ui->threadTreeWidget->topLevelItemCount(); - for (int index = 0; index < count; ++index) { - filterItem(ui->threadTreeWidget->topLevelItem(index), text, filterColumn); - } -#endif + mThreadModel->setFilter(filterColumn,keywords) ; + + //if(found > 0) + // expandAll(); + + //if(found == 0) + // ui.filterLineEdit->setToolTip(tr("No result.")) ; + //else + // ui.filterLineEdit->setToolTip(tr("Found %1 results.").arg(found)) ; } bool GxsForumThreadWidget::filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn)