From 2066248b3b44747460c244fb9e3dcc344e10e100 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 20 Nov 2018 23:28:07 +0100 Subject: [PATCH] started updating ForumFillThread to new model --- .../src/gui/gxsforums/GxsForumModel.cpp | 101 ++++++++++++++++-- .../src/gui/gxsforums/GxsForumModel.h | 27 ++++- .../gui/gxsforums/GxsForumThreadWidget.cpp | 1 + .../src/gui/gxsforums/GxsForumsFillThread.cpp | 74 ++++++++++++- 4 files changed, 191 insertions(+), 12 deletions(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp index a3a228374..91836723f 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp @@ -260,7 +260,6 @@ QVariant RsGxsForumModel::data(const QModelIndex &index, int role) const case Qt::TextColorRole: case Qt::WhatsThisRole: case Qt::EditRole: - case Qt::ToolTipRole: case Qt::StatusTipRole: return QVariant(); default: break; } @@ -299,11 +298,63 @@ QVariant RsGxsForumModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: return displayRole (meta,index.column()) ; case Qt::DecorationRole: return decorationRole(meta,index.column()) ; case Qt::UserRole: return userRole (meta,index.column()) ; + case Qt::ToolTipRole: return toolTipRole (meta,index.column()) + + case ThreadPinnedRole: return pinnedRole(index.column()) ; + case MissingRole: return missingRole(index.column()) ; + case StatusRole: return statusRole(index.column()) ; default: return QVariant(); } } +QVariant RsGxsForumModel::statusRole(int column,const ForumModelPostEntry& fmpe) +{ + if(column != COLUMN_THREAD_DATA) + return QVariant(); + + return QVariant(fmpe.mMsgStatus); +} + +QVariant RsGxsForumModel::missingRole(int column,const ForumModelPostEntry& fmpe) +{ + if(column != COLUMN_THREAD_DATA) + return QVariant(); + + if(fmpe.mPostFlags & FLAG_POST_IS_MISSING) + return QVariant(true); + else + return QVariant(false); +} + +QVariant RsGxsForumModel::toolTipRole(int column,const ForumModelPostEntry& fmpe) +{ + if(column != COLUMN_THREAD_DISTRIBUTION) + return QVariant(); + + switch(fmpe.mReputationWaningLevel) + { + case 3: return QVariant(tr("Information for this identity is currently missing.")) ; + case 2: return QVariant(tr("You have banned this ID. The message will not be\ndisplayed nor forwarded to your friends.")) ; + case 1: return QVariant(tr("You have not set an opinion for this person,\n and your friends do not vote positively: Spam regulation \nprevents the message to be forwarded to your friends.")) ; + case 0: return QVariant(tr("Message will be forwarded to your friends.") ; + default: + return QVariant("[ERROR: missing reputation level information - contact the developers]"); + } +} + +QVariant RsGxsForumModel::pinnedRole(int column,const ForumModelPostEntry& fmpe) +{ + if(column != COLUMN_THREAD_DATE) + return QVariant(); + + if(fmpe.mFlags & ForumModelPostEntry::FLAG_POST_IS_PINNED) + return QVariant(true); + else + return QVariant(false); +} + + QVariant RsGxsForumModel::sizeHintRole(int col) const { float factor = QFontMetricsF(QApplication::font()).height()/14.0f ; @@ -318,15 +369,50 @@ QVariant RsGxsForumModel::sizeHintRole(int col) const } } +QVariant RsGxsForumModel::authorRole(int column,const ForumModelPostEntry& fmpe) +{ + if(column == COLUMN_THREAD_DATA) + return QVariant(QString::fromStdString(msg.mMeta.mAuthorId.toStdString())); + + return QVariant(); +} + +QVariant RsGxsForumModel::sortRole(int column,const ForumModelPostEntry& fmpe) +{ + if(column == COLUMN_THREAD_DATA) + return QVariant(QString::number(fmpe.mPublishTs)); // we should probably have leading zeroes here + +} + QVariant RsGxsForumModel::displayRole(const RsMsgMetaData& meta,int col) const { switch(col) { - case COLUMN_TITLE: return QVariant(QString::fromUtf8(meta.mMsgName.c_str())); - case COLUMN_READ_STATUS: return QVariant(meta.mMsgStatus); - case COLUMN_DATE: return QVariant(qulonglong(meta.mPublishTs)); - case COLUMN_AUTHOR: return QVariant(QString::fromStdString(meta.mAuthorId.toStdString())); + case COLUMN_TITLE: if(fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_IS_REDACTED) + return QVariant(tr("[ ... Redacted message ... ]")); + else if(fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_IS_PINNED) + return QVariant(tr("[PINNED] ") + QString::fromUtf8(msg.mMeta.mMsgName.c_str())); + else + return QVariant(QString::fromUtf8(msg.mMeta.mMsgName.c_str())); + case COLUMN_READ_STATUS:return QVariant(meta.mMsgStatus); + case COLUMN_DATE: { + QDateTime qtime; + qtime.setTime_t(msg.mMeta.mPublishTs); + + return QVariant(DateTime::formatDateTime(qtime)); + } + + case COLUMN_AUTHOR: return QVariant(QString::fromStdString(meta.mAuthorId.toStdString())); + case COLUMN_THREAD_MSGID: return QVariant(QString::fromStdString(meta.mMsgId.toStdString())); +#ifdef TODO + if (filterColumn == COLUMN_THREAD_CONTENT) { + // need content for filter + QTextDocument doc; + doc.setHtml(QString::fromUtf8(msg.mMsg.c_str())); + item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); + } +#endif default: return QVariant("[ TODO ]"); } @@ -381,7 +467,10 @@ QVariant RsGxsForumModel::userRole(const RsMsgMetaData &meta, int col) const QVariant RsGxsForumModel::decorationRole(const RsMsgMetaData& meta,int col) const { - return QVariant(); + if(col == COLUMN_THREAD_DISTRIBUTION) + return QVariant(fmpe.mReputationWarningLevel); + else + return QVariant(); } void RsGxsForumModel::update_posts() diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.h b/retroshare-gui/src/gui/gxsforums/GxsForumModel.h index 556aff4f9..384367097 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.h @@ -24,12 +24,25 @@ struct RsMsgMetaData typedef uint32_t ForumModelIndex; -struct ForumPostEntry +struct ForumModelPostEntry { + typedef enum { // flags for display of posts + FLAG_POST_IS_PINNED = 0x0001, + FLAG_POST_IS_MISSING = 0x0002, + FLAG_POST_IS_REDACTED = 0x0004, + }; + + std::string mTitle ; + RsGxsId mAuthorId ; + RsGxsMessageId mMsgId; + uint32_t mPublishTs; + uint32_t mPostFlags; + int mReputationWarningLevel; + std::vector meta_versions; // maybe we don't need all this. Could be too large. - std::vector children; - ForumModelIndex parent; + std::vector mChildren; + ForumModelIndex mParent; int prow ; // parent row }; @@ -43,7 +56,11 @@ public: explicit RsGxsForumModel(QObject *parent = NULL); ~RsGxsForumModel(){} - enum Roles{ SortRole = Qt::UserRole+1 }; + enum Roles{ SortRole = Qt::UserRole+1, + ThreadPinnedRole = Qt::UserRole+2, + MissingRole = Qt::UserRole+3, + StatusRole = Qt::UserRole+4, + }; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -72,5 +89,5 @@ private: static bool convertTabEntryToRefPointer(uint32_t entry,void *& ref); static bool convertRefPointerToTabEntry(void *ref,uint32_t& entry); - std::vector mPosts ; // store the list of posts updated from rsForums. + std::vector mPosts ; // store the list of posts updated from rsForums. }; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index d33aab4eb..48609a9c0 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -1427,6 +1427,7 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum return item; } + QTreeWidgetItem *GxsForumThreadWidget::generateMissingItem(const RsGxsMessageId &msgId) { GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_AVATAR); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp index 7545e4f07..f0c61d877 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp @@ -23,9 +23,10 @@ #include "GxsForumsFillThread.h" #include "GxsForumThreadWidget.h" +#include "GxsForumModel.h" #include "retroshare/rsgxsflags.h" -#include +#include "retroshare/rsgxsforums.h" #include #include @@ -553,4 +554,75 @@ void GxsForumsFillThread::run() deleteLater(); } +QTreeWidgetItem *GxsForumsFillThread::convertMsgToThreadWidget(const RsGxsForumMsg& msg, bool useChildTS, uint32_t filterColumn, ForumModelIndex parent) +{ + ForumModelPostEntry fentry; + fentry.mMsgId = msg.mMeta.mMsgId; + fentry.mPublishTs = msg.mMeta.mPublishTs; + fentry.mParent = parent; + + if(mForumGroup.mPinnedPosts.ids.find(msg.mMeta.mMsgId) != mForumGroup.mPinnedPosts.ids.end()) + fentry.mFlags |= ForumModelPostEntry::FLAG_POST_IS_PINNED; + + // Early check for a message that should be hidden because its author + // is flagged with a bad reputation + + uint32_t idflags =0; + RsReputations::ReputationLevel reputation_level = rsReputations->overallReputationLevel(msg.mMeta.mAuthorId,&idflags) ; + bool redacted = false; + + if(reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE) + fentry.mPostFlags |= ForumModelPostEntry::FLAG_POST_IS_REDACTED; + + // We use a specific item model for forums in order to handle the post pinning. + + if(reputation_level == RsReputations::REPUTATION_UNKNOWN) + fentry.mReputationWarningLevel = 3 ; + else if(reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE) + fentry.mReputationWarningLevel = 2 ; + else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(mForumGroup.mMeta.mSignFlags,idflags)) + fentry.mReputationWarningLevel = 1 ; + else + fentry.mReputationWarningLevel = 0 ; + +#ifdef TODO + // This is an attempt to put pinned posts on the top. We should rather use a QSortFilterProxyModel here. + QString itemSort = QString::number(msg.mMeta.mPublishTs);//Don't need to format it as for sort. + + if (useChildTS) + { + for(QTreeWidgetItem *grandParent = parent; grandParent!=NULL; grandParent = grandParent->parent()) + { + //Update Parent Child TimeStamp + QString oldTSSort = grandParent->data(COLUMN_THREAD_DATE, ROLE_THREAD_SORT).toString(); + + QString oldCTSSort = oldTSSort.split("|").at(0); + QString oldPTSSort = oldTSSort.contains("|") ? oldTSSort.split(" | ").at(1) : oldCTSSort; +#ifdef SHOW_COMBINED_DATES + QString oldTSText = grandParent->text(COLUMN_THREAD_DATE); + QString oldCTSText = oldTSText.split("|").at(0); + QString oldPTSText = oldTSText.contains("|") ? oldTSText.split(" | ").at(1) : oldCTSText;//If first time parent get only its mPublishTs + #endif + if (oldCTSSort.toDouble() < itemSort.toDouble()) + { +#ifdef SHOW_COMBINED_DATES + grandParent->setText(COLUMN_THREAD_DATE, DateTime::formatDateTime(qtime) + " | " + oldPTSText); +#endif + grandParent->setData(COLUMN_THREAD_DATE, ROLE_THREAD_SORT, itemSort + " | " + oldPTSSort); + } + } + } +#endif +//#TODO +#if 0 + if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { + rsGxsForums->getMessageStatus(msginfo.forumId, msginfo.msgId, status); + } else { + // show message as read + status = RSGXS_MSG_STATUS_READ; + } +#endif + if (parent) parent->addChild(item); + return item; +}