From 5b8a64b6777c833642e5ca3ea7e067ab9c501b34 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 6 Dec 2018 23:04:53 +0100 Subject: [PATCH] fixed a number of bugs in the update/display of forum model --- libretroshare/src/gxs/rsgxsdataaccess.cc | 5 +- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 2 +- .../src/gui/gxsforums/GxsForumModel.cpp | 46 ++++- .../src/gui/gxsforums/GxsForumModel.h | 4 +- .../gui/gxsforums/GxsForumThreadWidget.cpp | 186 +++++++++--------- .../src/gui/gxsforums/GxsForumThreadWidget.h | 7 +- 6 files changed, 140 insertions(+), 110 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index f9049d9f0..1206696f7 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -1714,10 +1714,11 @@ void RsGxsDataAccess::filterMsgList( MsgMetaFilter::const_iterator cit = msgMetas.find(groupId); if(cit == msgMetas.end()) continue; - +#ifdef DATA_DEBUG std::cerr << __PRETTY_FUNCTION__ << " " << msgsIdSet.size() << " for group: " << groupId << " before filtering" << std::endl; +#endif for( std::set::iterator msgIdIt = msgsIdSet.begin(); msgIdIt != msgsIdSet.end(); ) @@ -1738,9 +1739,11 @@ void RsGxsDataAccess::filterMsgList( else msgIdIt = msgsIdSet.erase(msgIdIt); } +#ifdef DATA_DEBUG std::cerr << __PRETTY_FUNCTION__ << " " << msgsIdSet.size() << " for group: " << groupId << " after filtering" << std::endl; +#endif } } diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index fac557122..6168090eb 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -37,7 +37,7 @@ #define IMAGE_PGPKNOWN ":/images/contact.png" #define IMAGE_PGPUNKNOWN ":/images/tags/pgp-unknown.png" #define IMAGE_ANON ":/images/tags/anon.png" -#define IMAGE_BANNED ":/icons/yellow_biohazard64.png" +#define IMAGE_BANNED ":/icons/biohazard_red.png" #define IMAGE_DEV_AMBASSADOR ":/images/tags/dev-ambassador.png" #define IMAGE_DEV_CONTRIBUTOR ":/images/tags/vote_down.png" diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp index d3336abe5..444b8e7ee 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp @@ -664,13 +664,8 @@ QVariant RsGxsForumModel::decorationRole(const ForumModelPostEntry& fmpe,int col return QVariant(); } -void RsGxsForumModel::setForum(const RsGxsGroupId& forum_group_id) +void RsGxsForumModel::updateForum(const RsGxsGroupId& forum_group_id) { - //if(mForumGroup.mMeta.mGroupId == forum_group_id) - // return ; - - // we do not set mForumGroupId yet. We'll do it when the forum data is updated. - if(forum_group_id.isNull()) return; @@ -818,12 +813,19 @@ void RsGxsForumModel::convertMsgToPostEntry(const RsGxsForumGroup& mForumGroup,c // Early check for a message that should be hidden because its author // is flagged with a bad reputation + computeReputationLevel(mForumGroup.mMeta.mSignFlags,fentry); +} + +void RsGxsForumModel::computeReputationLevel(uint32_t forum_sign_flags,ForumModelPostEntry& fentry) +{ uint32_t idflags =0; - RsReputations::ReputationLevel reputation_level = rsReputations->overallReputationLevel(msg.mMeta.mAuthorId,&idflags) ; + RsReputations::ReputationLevel reputation_level = rsReputations->overallReputationLevel(fentry.mAuthorId,&idflags) ; bool redacted = false; if(reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE) - fentry.mPostFlags |= ForumModelPostEntry::FLAG_POST_IS_REDACTED; + fentry.mPostFlags |= ForumModelPostEntry::FLAG_POST_IS_REDACTED; + else + fentry.mPostFlags &= ~ForumModelPostEntry::FLAG_POST_IS_REDACTED; // We use a specific item model for forums in order to handle the post pinning. @@ -831,7 +833,7 @@ void RsGxsForumModel::convertMsgToPostEntry(const RsGxsForumGroup& mForumGroup,c fentry.mReputationWarningLevel = 3 ; else if(reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE) fentry.mReputationWarningLevel = 2 ; - else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(mForumGroup.mMeta.mSignFlags,idflags)) + else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(forum_sign_flags,idflags)) fentry.mReputationWarningLevel = 1 ; else fentry.mReputationWarningLevel = 0 ; @@ -1278,4 +1280,30 @@ void RsGxsForumModel::debug_dump() } #endif +void RsGxsForumModel::setAuthorOpinion(const QModelIndex& indx,RsReputations::Opinion op) +{ + if(!indx.isValid()) + return ; + void *ref = indx.internalPointer(); + uint32_t entry = 0; + + if(!convertRefPointerToTabEntry(ref,entry) || entry >= mPosts.size()) + return ; + + std::cerr << "Setting own opinion for author " << mPosts[entry].mAuthorId << " to " << op << std::endl; + RsGxsId author_id = mPosts[entry].mAuthorId; + + rsReputations->setOwnOpinion(author_id,op) ; + + // update opinions and distribution flags. No need to re-load all posts. + + for(uint32_t i=0;i > getPostVersions(const RsGxsMessageId& mid) const; // This method will asynchroneously update the data - void setForum(const RsGxsGroupId& forumGroup); + void updateForum(const RsGxsGroupId& forumGroup); void setTreeMode(TreeMode mode) ; void setSortMode(SortMode mode) ; @@ -117,6 +117,7 @@ public: void setMsgReadStatus(const QModelIndex &i, bool read_status, bool with_children); void setFilter(int column, const QStringList &strings, uint32_t &count) ; + void setAuthorOpinion(const QModelIndex& indx,RsReputations::Opinion op); int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -175,6 +176,7 @@ private: static bool convertTabEntryToRefPointer(uint32_t entry,void *& ref); static bool convertRefPointerToTabEntry(void *ref,uint32_t& entry); + static void computeReputationLevel(uint32_t forum_sign_flags, ForumModelPostEntry& entry); void update_posts(const RsGxsGroupId &group_id); void setForumMessageSummary(const std::vector& messages); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index f664842ce..5fcdf948d 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -304,9 +304,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget setUpdateWhenInvisible(true); - mSubscribeFlags = 0; mUpdating = false; - mSignFlags = 0; mUnreadCount = 0; mNewCount = 0; @@ -405,7 +403,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget setGroupId(forumId); - ui->threadTreeWidget->installEventFilter(this) ; + //ui->threadTreeWidget->installEventFilter(this) ; ui->postText->clear() ; ui->by_label->setId(RsGxsId()) ; @@ -511,7 +509,7 @@ void GxsForumThreadWidget::groupIdChanged() mNewCount = 0; mUnreadCount = 0; - mThreadModel->setForum(groupId()); + //mThreadModel->updateForum(groupId()); updateDisplay(true); } @@ -535,6 +533,7 @@ QIcon GxsForumThreadWidget::groupIcon() return QIcon(); } +#ifdef TO_REMOVE void GxsForumThreadWidget::changeEvent(QEvent *e) { RsGxsUpdateBroadcastWidget::changeEvent(e); @@ -581,6 +580,7 @@ static void removeMessages(std::map > &ms } } } +#endif void GxsForumThreadWidget::saveExpandedItems(QList& expanded_items) const { @@ -614,62 +614,74 @@ void GxsForumThreadWidget::recursRestoreExpandedItems(const QModelIndex& index, void GxsForumThreadWidget::updateDisplay(bool complete) { + std::cerr << "udateDisplay: groupId()=" << groupId()<< std::endl; + if(mUpdating) + { + std::cerr << " Already updating. Return!"<< std::endl; return; + } - if (complete) { - /* Fill complete */ + if(groupId().isNull()) + { + std::cerr << " group_id=0. Return!"<< std::endl; + return; + } + if(mForumGroup.mMeta.mGroupId.isNull() && !groupId().isNull()) + { + std::cerr << " inconsistent group data. Reloading!"<< std::endl; + complete = true; + } + + if(!complete) + { + std::cerr << " checking changed group data and msgs"<< std::endl; + + const std::set &grpIdsMeta = getGrpIdsMeta(); + + if(grpIdsMeta.find(groupId())!=grpIdsMeta.end()) + { + std::cerr << " grpMeta change. reloading!" << std::endl; + complete = true; + } + + const std::set &grpIds = getGrpIds(); + + if (grpIds.find(groupId())!=grpIds.end()) + { + std::cerr << " grp data change. reloading!" << std::endl; + complete = true; + } + else + { + // retrieve the list of modified msg ids + // if current group is listed in the map, reload the whole hierarchy + + std::map > msgIds; + getAllMsgIds(msgIds); + + // if (!mIgnoredMsgId.empty()) /* Filter ignored messages */ + // removeMessages(msgIds, mIgnoredMsgId); + + if (msgIds.find(groupId()) != msgIds.end()) + { + std::cerr << " msg data change. reloading!" << std::endl; + complete=true; + } + } + } + + if(complete) // need to update the group data, reload the messages etc. + { saveExpandedItems(mSavedExpandedMessages); mUpdating=true; updateGroupData(); - mThreadModel->setForum(groupId()); - insertMessage(); - - mIgnoredMsgId.clear(); + mThreadModel->updateForum(groupId()); return; } - else - { - - bool updateGroup = false; - const std::set &grpIdsMeta = getGrpIdsMeta(); - - if(grpIdsMeta.find(groupId())!=grpIdsMeta.end()) - updateGroup = true; - - const std::set &grpIds = getGrpIds(); - - if (grpIds.find(groupId())!=grpIds.end()){ - updateGroup = true; - /* Update threads */ - mUpdating=true; - mThreadModel->setForum(groupId()); - } - else - { - std::map > msgIds; - getAllMsgIds(msgIds); - - if (!mIgnoredMsgId.empty()) /* Filter ignored messages */ - removeMessages(msgIds, mIgnoredMsgId); - - if (msgIds.find(groupId()) != msgIds.end()) - { - mUpdating=true; - - saveExpandedItems(mSavedExpandedMessages); - - mThreadModel->setForum(groupId()); /* Update threads */ - } - } - - if (updateGroup) - updateGroupData(); - - } } QModelIndex GxsForumThreadWidget::GxsForumThreadWidget::getCurrentIndex() const @@ -728,7 +740,7 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) connect(flagasnegativeAct, SIGNAL(triggered()), this, SLOT(flagperson())); QAction *newthreadAct = new QAction(QIcon(IMAGE_MESSAGE), tr("Start New Thread"), &contextMnu); - newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags)); + newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)); connect(newthreadAct , SIGNAL(triggered()), this, SLOT(createthread())); QAction* expandAll = new QAction(tr("Expand all"), &contextMnu); @@ -752,7 +764,7 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) QAction *showinpeopleAct = new QAction(QIcon(":/images/info16.png"), tr("Show author in people tab"), &contextMnu); connect(showinpeopleAct, SIGNAL(triggered()), this, SLOT(showInPeopleTab())); - if (IS_GROUP_SUBSCRIBED(mSubscribeFlags)) + if (IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) { markMsgAsReadChildren->setEnabled(current_post.mPostFlags & ForumModelPostEntry::FLAG_POST_HAS_UNREAD_CHILDREN); markMsgAsUnreadChildren->setEnabled(current_post.mPostFlags & ForumModelPostEntry::FLAG_POST_HAS_READ_CHILDREN); @@ -796,7 +808,7 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) } } - if(IS_GROUP_ADMIN(mSubscribeFlags) && (current_post.mParent == 0)) + if(IS_GROUP_ADMIN(mForumGroup.mMeta.mSubscribeFlags) && (current_post.mParent == 0)) contextMnu.addAction(pinUpPostAct); } @@ -861,9 +873,9 @@ void GxsForumThreadWidget::contextMenuTextBrowser(QPoint point) delete(contextMnu); } +#ifdef TODO bool GxsForumThreadWidget::eventFilter(QObject *obj, QEvent *event) { -#ifdef TODO if (obj == ui->threadTreeWidget) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); @@ -877,9 +889,9 @@ bool GxsForumThreadWidget::eventFilter(QObject *obj, QEvent *event) } // pass the event on to the parent class return RsGxsUpdateBroadcastWidget::eventFilter(obj, event); -#endif return RsGxsUpdateBroadcastWidget::eventFilter(obj, event); } +#endif void GxsForumThreadWidget::togglethreadview() { @@ -945,18 +957,11 @@ void GxsForumThreadWidget::clickedThread(QModelIndex index) if(!index.isValid()) return; - RsGxsMessageId tmp(index.sibling(index.row(),RsGxsForumModel::COLUMN_THREAD_MSGID).data(Qt::UserRole).toString().toStdString()); - - if( tmp.isNull()) - return; - - mThreadId = tmp; - mOrigThreadId = tmp; - std::cerr << "Clicked on message ID " << mThreadId << std::endl; if (index.column() == RsGxsForumModel::COLUMN_THREAD_READ) { + std::cerr << " changing read status" << std::endl; ForumModelPostEntry fmpe; QModelIndex src_index = mThreadProxyModel->mapToSource(index); @@ -965,7 +970,7 @@ void GxsForumThreadWidget::clickedThread(QModelIndex index) mThreadModel->setMsgReadStatus(src_index, IS_MSG_UNREAD(fmpe.mMsgStatus),false); } else - changedThread(index); + std::cerr << " doing nothing" << std::endl; } static void cleanupItems (QList &items) @@ -1011,7 +1016,7 @@ void GxsForumThreadWidget::insertMessage() ui->versions_CB->hide(); ui->time_label->show(); - ui->postText->setText(mForumDescription); + ui->postText->setText(QString::fromUtf8(mForumGroup.mDescription.c_str())); return; } @@ -1034,7 +1039,7 @@ void GxsForumThreadWidget::insertMessage() return; } - mStateHelper->setWidgetEnabled(ui->newmessageButton, (IS_GROUP_SUBSCRIBED(mSubscribeFlags) && mThreadId.isNull() == false)); + mStateHelper->setWidgetEnabled(ui->newmessageButton, (IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags) && mThreadId.isNull() == false)); /* blank text, incase we get nothing */ ui->postText->clear(); @@ -1139,6 +1144,7 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg) ui->lineLeft->show(); ui->by_text_label->show(); ui->by_label->show(); + ui->threadTreeWidget->setFocus(); if(redacted) { @@ -1248,7 +1254,7 @@ void GxsForumThreadWidget::nextUnreadMessage() void GxsForumThreadWidget::markMsgAsReadUnread (bool read, bool children, bool forum) { - if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { + if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) { return; } @@ -1337,7 +1343,7 @@ void GxsForumThreadWidget::subscribeGroup(bool subscribe) void GxsForumThreadWidget::createmessage() { - if (groupId().isNull () || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { + if (groupId().isNull () || !IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) { return; } @@ -1418,14 +1424,8 @@ void GxsForumThreadWidget::flagperson() } RsReputations::Opinion opinion = static_cast(qobject_cast(sender())->data().toUInt()); - ForumModelPostEntry fmpe ; - getCurrentPost(fmpe); - RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId); - - std::cerr << "Setting own opinion for author " << fmpe.mAuthorId << " to " << opinion << std::endl; - - rsReputations->setOwnOpinion(fmpe.mAuthorId,opinion) ; + mThreadModel->setAuthorOpinion(mThreadProxyModel->mapToSource(getCurrentIndex()),opinion); } void GxsForumThreadWidget::replytoforummessage() { async_msg_action( &GxsForumThreadWidget::replyForumMessageData ); } @@ -1672,15 +1672,21 @@ bool GxsForumThreadWidget::filterItem(QTreeWidgetItem *item, const QString &text void GxsForumThreadWidget::postForumLoading() { + std::cerr << "Post forum loading..." << std::endl; + QModelIndex indx = mThreadModel->getIndexOfMessage(mThreadId); - if(indx.isValid()) + if(!mThreadId.isNull() && indx.isValid()) { QModelIndex index = mThreadProxyModel->mapFromSource(indx); - ui->threadTreeWidget->selectionModel()->select(index,QItemSelectionModel::ClearAndSelect); + ui->threadTreeWidget->selectionModel()->select(index,QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + + std::cerr << " re-selecting index of message " << mThreadId << " to " << indx.row() << "," << indx.column() << " " << (void*)indx.internalPointer() << std::endl; } else { + std::cerr << " previously message " << mThreadId << " not visible anymore -> de-selecting" << std::endl; + ui->threadTreeWidget->selectionModel()->clear(); ui->threadTreeWidget->selectionModel()->reset(); mThreadId.clear(); @@ -1692,7 +1698,6 @@ void GxsForumThreadWidget::postForumLoading() ui->threadTreeWidget->update(); recursRestoreExpandedItems(mThreadProxyModel->mapFromSource(mThreadModel->root()),mSavedExpandedMessages); - mUpdating = false; } void GxsForumThreadWidget::updateGroupData() @@ -1700,14 +1705,9 @@ void GxsForumThreadWidget::updateGroupData() if(groupId().isNull()) return; - mSubscribeFlags = 0; - mSignFlags = 0; - mForumDescription.clear(); - ui->threadTreeWidget->selectionModel()->clear(); - ui->threadTreeWidget->selectionModel()->reset(); - mThreadProxyModel->clear(); - - emit groupChanged(this); + // ui->threadTreeWidget->selectionModel()->clear(); + // ui->threadTreeWidget->selectionModel()->reset(); + // mThreadProxyModel->clear(); RsThread::async([this]() { @@ -1732,7 +1732,7 @@ void GxsForumThreadWidget::updateGroupData() // 2 - sort the messages into a proper hierarchy - RsGxsForumGroup group = groups[0]; + RsGxsForumGroup *group = new RsGxsForumGroup(groups[0]); // we use a pointer in order to avoid group deletion while we're in the thread. // 3 - update the model in the UI thread. @@ -1744,12 +1744,11 @@ void GxsForumThreadWidget::updateGroupData() * Qt::QueuedConnection is important! */ - mForumGroup = group; - mSubscribeFlags = group.mMeta.mSubscribeFlags; + mForumGroup = *group; + delete group; ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); - ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mSubscribeFlags)) ; - + ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; }, this ); }); @@ -1782,7 +1781,7 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) // 2 - sort the messages into a proper hierarchy - RsGxsForumMsg msg = msgs[0]; + RsGxsForumMsg *msg = new RsGxsForumMsg(msgs[0]); // 3 - update the model in the UI thread. @@ -1794,10 +1793,11 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) * Qt::QueuedConnection is important! */ - insertMessageData(msg); + insertMessageData(*msg); + delete msg; ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); - ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mSubscribeFlags)) ; + ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; }, this ); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 9dba7efb5..cfc790324 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -84,8 +84,8 @@ public: virtual void blank(); protected: - bool eventFilter(QObject *obj, QEvent *ev); - void changeEvent(QEvent *e); + //bool eventFilter(QObject *obj, QEvent *ev); + //void changeEvent(QEvent *e); /* RsGxsUpdateBroadcastWidget */ virtual void updateDisplay(bool complete); @@ -177,9 +177,6 @@ private: RsGxsMessageId mThreadId; RsGxsMessageId mOrigThreadId; RsGxsForumGroup mForumGroup; - QString mForumDescription; - int mSubscribeFlags; - int mSignFlags; bool mUpdating; bool mInProcessSettings; bool mInMsgAsReadUnread;