fixed a number of bugs in the update/display of forum model

This commit is contained in:
csoler 2018-12-06 23:04:53 +01:00
parent 600a3d8e16
commit 5b8a64b677
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
6 changed files with 140 additions and 110 deletions

View File

@ -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<RsGxsMessageId>::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
}
}

View File

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

View File

@ -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<mPosts.size();++i)
if(mPosts[i].mAuthorId == author_id)
{
computeReputationLevel(mForumGroup.mMeta.mSignFlags,mPosts[i]);
// notify the widgets that the data has changed.
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(0,COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
}
}

View File

@ -105,7 +105,7 @@ public:
std::vector<std::pair<time_t,RsGxsMessageId> > 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<RsGxsForumMsg>& messages);

View File

@ -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<RsGxsGroupId, std::set<RsGxsMessageId> > &ms
}
}
}
#endif
void GxsForumThreadWidget::saveExpandedItems(QList<RsGxsMessageId>& 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<RsGxsGroupId> &grpIdsMeta = getGrpIdsMeta();
if(grpIdsMeta.find(groupId())!=grpIdsMeta.end())
{
std::cerr << " grpMeta change. reloading!" << std::endl;
complete = true;
}
const std::set<RsGxsGroupId> &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<RsGxsGroupId, std::set<RsGxsMessageId> > 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<RsGxsGroupId> &grpIdsMeta = getGrpIdsMeta();
if(grpIdsMeta.find(groupId())!=grpIdsMeta.end())
updateGroup = true;
const std::set<RsGxsGroupId> &grpIds = getGrpIds();
if (grpIds.find(groupId())!=grpIds.end()){
updateGroup = true;
/* Update threads */
mUpdating=true;
mThreadModel->setForum(groupId());
}
else
{
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > 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<QKeyEvent*>(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<QTreeWidgetItem *> &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<RsReputations::Opinion>(qobject_cast<QAction*>(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 );

View File

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