From 5a6c8de0056fb7fd40e7de30c647e2001d04cbda Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 2 Jun 2020 22:22:36 +0200 Subject: [PATCH] fixed abstract item model for channels. Display still missing --- .../gui/gxschannels/GxsChannelFilesWidget.cpp | 9 - .../gui/gxschannels/GxsChannelPostsWidget.h | 2 +- .../GxsChannelPostsWidgetWithModel.cpp | 271 ++++++++---------- .../GxsChannelPostsWidgetWithModel.h | 19 +- .../gui/gxsforums/GxsForumThreadWidget.cpp | 1 + 5 files changed, 134 insertions(+), 168 deletions(-) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesWidget.cpp index 3afb4e645..5ae905cea 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesWidget.cpp @@ -80,15 +80,6 @@ GxsChannelFilesWidget::GxsChannelFilesWidget(QWidget *parent) : ui->treeWidget->setColumnWidth(COLUMN_PUBLISHED, 150); } -GxsChannelFilesWidget::paintEvent() -{ - QWidget::paintEvent(); - - if(!mLoaded) - { - } -} - GxsChannelFilesWidget::~GxsChannelFilesWidget() { delete(mCompareRole); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h index 28a521944..dded41491 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h @@ -98,7 +98,7 @@ private: int viewMode(); void insertChannelDetails(const RsGxsChannelGroup &group); - void insertChannelPosts(std::vector &posts); + void insertChannelPosts(std::vector& posts, GxsMessageFramePostThread *thread, bool related); void createPostItem(const RsGxsChannelPost &post, bool related); void handleEvent_main_thread(std::shared_ptr event); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp index bc3c564e3..dd2c8cccc 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp @@ -24,7 +24,8 @@ #include "retroshare/rsgxscircles.h" #include "GxsChannelPostsWidgetWithModel.h" -#include "ui_GxsChannelPostsWidget.h" +#include "GxsChannelPostsModel.h" +#include "ui_GxsChannelPostsWidgetWithModel.h" #include "gui/feeds/GxsChannelPostItem.h" #include "gui/gxs/GxsIdDetails.h" #include "gui/gxschannels/CreateGxsChannelMsg.h" @@ -53,27 +54,27 @@ /** Constructor */ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupId &channelId, QWidget *parent) : - GxsMessageFramePostWidget(rsGxsChannels, parent), - ui(new Ui::GxsChannelPostsWidget) + GxsMessageFrameWidget(rsGxsChannels, parent), + ui(new Ui::GxsChannelPostsWidgetWithModel) { /* Invoke the Qt Designer generated object setup routine */ ui->setupUi(this); - ui->postsTree->setModel(new RsGxsChannelPostsModel()); + ui->postsTree->setModel(mThreadModel = new RsGxsChannelPostsModel()); /* Setup UI helper */ - mStateHelper->addWidget(mTokenTypeAllPosts, ui->progressBar, UISTATE_LOADING_VISIBLE); - mStateHelper->addWidget(mTokenTypeAllPosts, ui->loadingLabel, UISTATE_LOADING_VISIBLE); - mStateHelper->addWidget(mTokenTypeAllPosts, ui->filterLineEdit); + //mStateHelper->addWidget(mTokenTypeAllPosts, ui->progressBar, UISTATE_LOADING_VISIBLE); + //mStateHelper->addWidget(mTokenTypeAllPosts, ui->loadingLabel, UISTATE_LOADING_VISIBLE); + //mStateHelper->addWidget(mTokenTypeAllPosts, ui->filterLineEdit); - mStateHelper->addWidget(mTokenTypePosts, ui->loadingLabel, UISTATE_LOADING_VISIBLE); + //mStateHelper->addWidget(mTokenTypePosts, ui->loadingLabel, UISTATE_LOADING_VISIBLE); - mStateHelper->addLoadPlaceholder(mTokenTypeGroupData, ui->nameLabel); + //mStateHelper->addLoadPlaceholder(mTokenTypeGroupData, ui->nameLabel); - mStateHelper->addWidget(mTokenTypeGroupData, ui->postButton); - mStateHelper->addWidget(mTokenTypeGroupData, ui->logoLabel); - mStateHelper->addWidget(mTokenTypeGroupData, ui->subscribeToolButton); + //mStateHelper->addWidget(mTokenTypeGroupData, ui->postButton); + //mStateHelper->addWidget(mTokenTypeGroupData, ui->logoLabel); + //mStateHelper->addWidget(mTokenTypeGroupData, ui->subscribeToolButton); /* Connect signals */ connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createMsg())); @@ -111,8 +112,8 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI ui->nameLabel->setMinimumWidth(20); /* Initialize feed widget */ - ui->feedWidget->setSortRole(ROLE_PUBLISH, Qt::DescendingOrder); - ui->feedWidget->setFilterCallback(filterItem); + //ui->feedWidget->setSortRole(ROLE_PUBLISH, Qt::DescendingOrder); + //ui->feedWidget->setFilterCallback(filterItem); /* load settings */ processSettings(true); @@ -141,7 +142,7 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI mEventHandlerId, RsEventType::GXS_CHANNELS ); } -void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr event) +void GxsChannelPostsWidgetWithModel::handleEvent_main_thread(std::shared_ptr event) { const RsGxsChannelEvent *e = dynamic_cast(event.get()); @@ -157,29 +158,90 @@ void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptrmChannelGroupId == groupId()) updateDisplay(true); break; - case RsChannelEventCode::READ_STATUS_CHANGED: - if (FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(e->mChannelMsgId))) - if (GxsChannelPostItem *channelPostItem = dynamic_cast(feedItem)) - channelPostItem->setReadStatus(false,!channelPostItem->isUnread()); - //channelPostItem->setReadStatus(false,e->Don't get read status. Will be more easier and accurate); - break; +// case RsChannelEventCode::READ_STATUS_CHANGED: +// if (FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(e->mChannelMsgId))) +// if (GxsChannelPostItem *channelPostItem = dynamic_cast(feedItem)) +// channelPostItem->setReadStatus(false,!channelPostItem->isUnread()); +// //channelPostItem->setReadStatus(false,e->Don't get read status. Will be more easier and accurate); +// break; default: break; } } -GxsChannelPostsWidget::~GxsChannelPostsWidget() +void GxsChannelPostsWidgetWithModel::updateGroupData() +{ + if(groupId().isNull()) + return; + + RsThread::async([this]() + { + std::vector groups; + + if(!rsGxsChannels->getChannelsInfo(std::list{ groupId() }, groups)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to get autodownload value for channel: " << groupId() << std::endl; + return; + } + + if(groups.size() != 1) + { + RsErr() << __PRETTY_FUNCTION__ << " cannot retrieve channel data for group ID " << groupId() << ": ERROR." << std::endl; + return; + } + + RsQThreadUtils::postToObject( [this,groups]() + { + mGroup = groups[0]; + mThreadModel->updateChannel(groupId()); + } ); + }); +} + +void GxsChannelPostsWidgetWithModel::updateDisplay(bool complete) +{ +#ifdef DEBUG_CHANNEL + std::cerr << "udateDisplay: groupId()=" << groupId()<< std::endl; +#endif + if(groupId().isNull()) + { +#ifdef DEBUG_CHANNEL + std::cerr << " group_id=0. Return!"<< std::endl; +#endif + return; + } + + if(mGroup.mMeta.mGroupId.isNull() && !groupId().isNull()) + { +#ifdef DEBUG_FORUMS + std::cerr << " inconsistent group data. Reloading!"<< std::endl; +#endif + complete = true; + } + if(complete) // need to update the group data, reload the messages etc. + { +#warning todo + //saveExpandedItems(mSavedExpandedMessages); + + //if(mGroupId != mThreadModel->currentGroupId()) + // mThreadId.clear(); + + updateGroupData(); + + return; + } +} +GxsChannelPostsWidgetWithModel::~GxsChannelPostsWidgetWithModel() { rsEvents->unregisterEventsHandler(mEventHandlerId); // save settings processSettings(false); delete(mAutoDownloadAction); - delete ui; } -void GxsChannelPostsWidget::processSettings(bool load) +void GxsChannelPostsWidgetWithModel::processSettings(bool load) { Settings->beginGroup(QString("ChannelPostsWidget")); @@ -204,14 +266,19 @@ void GxsChannelPostsWidget::processSettings(bool load) Settings->endGroup(); } -void GxsChannelPostsWidget::settingsChanged() +void GxsChannelPostsWidgetWithModel::settingsChanged() { mUseThread = Settings->getChannelLoadThread(); - mStateHelper->setWidgetVisible(ui->progressBar, mUseThread); + //mStateHelper->setWidgetVisible(ui->progressBar, mUseThread); } -void GxsChannelPostsWidget::groupNameChanged(const QString &name) +QString GxsChannelPostsWidgetWithModel::groupName(bool) +{ + return "Group name" ; +} + +void GxsChannelPostsWidgetWithModel::groupNameChanged(const QString &name) { if (groupId().isNull()) { ui->nameLabel->setText(tr("No Channel Selected")); @@ -221,11 +288,11 @@ void GxsChannelPostsWidget::groupNameChanged(const QString &name) } } -QIcon GxsChannelPostsWidget::groupIcon() +QIcon GxsChannelPostsWidgetWithModel::groupIcon() { - if (mStateHelper->isLoading(mTokenTypeGroupData) || mStateHelper->isLoading(mTokenTypeAllPosts)) { - return QIcon(":/images/kalarm.png"); - } +// if (mStateHelper->isLoading(mTokenTypeGroupData) || mStateHelper->isLoading(mTokenTypeAllPosts)) { +// return QIcon(":/images/kalarm.png"); +// } // if (mNewCount) { // return QIcon(":/images/message-state-new.png"); @@ -238,36 +305,19 @@ QIcon GxsChannelPostsWidget::groupIcon() /*************************************************************************************/ /*************************************************************************************/ -QScrollArea *GxsChannelPostsWidget::getScrollArea() -{ - return NULL; -} - -void GxsChannelPostsWidget::deleteFeedItem(FeedItem *feedItem, uint32_t /*type*/) -{ - if (!feedItem) - return; - - ui->feedWidget->removeFeedItem(feedItem); -} - -void GxsChannelPostsWidget::openChat(const RsPeerId & /*peerId*/) -{ -} - // Callback from Widget->FeedHolder->ServiceDialog->CommentContainer->CommentDialog, -void GxsChannelPostsWidget::openComments(uint32_t /*type*/, const RsGxsGroupId &groupId, const QVector& msg_versions,const RsGxsMessageId &msgId, const QString &title) +void GxsChannelPostsWidgetWithModel::openComments(uint32_t /*type*/, const RsGxsGroupId &groupId, const QVector& msg_versions,const RsGxsMessageId &msgId, const QString &title) { emit loadComment(groupId, msg_versions,msgId, title); } -void GxsChannelPostsWidget::createMsg() +void GxsChannelPostsWidgetWithModel::createMsg() { if (groupId().isNull()) { return; } - if (!IS_GROUP_SUBSCRIBED(subscribeFlags())) { + if (!IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) { return; } @@ -277,7 +327,7 @@ void GxsChannelPostsWidget::createMsg() /* window will destroy itself! */ } -void GxsChannelPostsWidget::insertChannelDetails(const RsGxsChannelGroup &group) +void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGroup &group) { /* IMAGE */ QPixmap chanImage; @@ -387,7 +437,7 @@ void GxsChannelPostsWidget::insertChannelDetails(const RsGxsChannelGroup &group) } } -int GxsChannelPostsWidget::viewMode() +int GxsChannelPostsWidgetWithModel::viewMode() { if (ui->feedToolButton->isChecked()) { return VIEW_MODE_FEEDS; @@ -399,7 +449,7 @@ int GxsChannelPostsWidget::viewMode() return VIEW_MODE_FEEDS; } -void GxsChannelPostsWidget::setViewMode(int viewMode) +void GxsChannelPostsWidgetWithModel::setViewMode(int viewMode) { #ifdef TODO switch (viewMode) { @@ -426,7 +476,7 @@ void GxsChannelPostsWidget::setViewMode(int viewMode) #endif } -void GxsChannelPostsWidget::filterChanged(int filter) +void GxsChannelPostsWidgetWithModel::filterChanged(int filter) { #ifdef TODO ui->feedWidget->setFilterType(filter); @@ -434,7 +484,8 @@ void GxsChannelPostsWidget::filterChanged(int filter) #endif } -/*static*/ bool GxsChannelPostsWidget::filterItem(FeedItem *feedItem, const QString &text, int filter) +#ifdef TODO +/*static*/ bool GxsChannelPostsWidgetWithModel::filterItem(FeedItem *feedItem, const QString &text, int filter) { GxsChannelPostItem *item = dynamic_cast(feedItem); if (!item) { @@ -474,7 +525,6 @@ void GxsChannelPostsWidget::filterChanged(int filter) return bVisible; } -#ifdef TODO void GxsChannelPostsWidget::createPostItemFromMetaData(const RsGxsMsgMetaData& meta,bool related) { GxsChannelPostItem *item = NULL; @@ -518,14 +568,7 @@ void GxsChannelPostsWidget::createPostItemFromMetaData(const RsGxsMsgMetaData& m ui->fileWidget->addFiles(post, related); #endif } -#endif -void GxsChannelPostsWidget::insertChannelPosts(std::vector& posts) -{ - mModel->setPosts(posts); -} - -#ifdef TODO void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool related) { GxsChannelPostItem *item = NULL; @@ -734,31 +777,25 @@ void GxsChannelPostsWidget::clearPosts() } #endif -void GxsChannelPostsWidget::blank() +void GxsChannelPostsWidgetWithModel::blank() { - mStateHelper->setWidgetEnabled(ui->postButton, false); - mStateHelper->setWidgetEnabled(ui->subscribeToolButton, false); + //mStateHelper->setWidgetEnabled(ui->postButton, false); + //mStateHelper->setWidgetEnabled(ui->subscribeToolButton, false); - clearPosts(); - + mThreadModel->clear(); groupNameChanged(QString()); ui->infoWidget->hide(); - ui->feedWidget->show(); - ui->fileWidget->hide(); } -bool GxsChannelPostsWidget::navigatePostItem(const RsGxsMessageId &msgId) +bool GxsChannelPostsWidgetWithModel::navigate(const RsGxsMessageId &msgId) { - FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(msgId)); - if (!feedItem) { - return false; - } - - return ui->feedWidget->scrollTo(feedItem, true); +#warning TODO + //return ui->feedWidget->scrollTo(feedItem, true); + return true; } -void GxsChannelPostsWidget::subscribeGroup(bool subscribe) +void GxsChannelPostsWidgetWithModel::subscribeGroup(bool subscribe) { RsGxsGroupId grpId(groupId()); if (grpId.isNull()) return; @@ -769,13 +806,13 @@ void GxsChannelPostsWidget::subscribeGroup(bool subscribe) } ); } -void GxsChannelPostsWidget::setAutoDownload(bool autoDl) +void GxsChannelPostsWidgetWithModel::setAutoDownload(bool autoDl) { mAutoDownloadAction->setChecked(autoDl); mAutoDownloadAction->setText(autoDl ? tr("Disable Auto-Download") : tr("Enable Auto-Download")); } -void GxsChannelPostsWidget::toggleAutoDownload() +void GxsChannelPostsWidgetWithModel::toggleAutoDownload() { RsGxsGroupId grpId = groupId(); if (grpId.isNull()) { @@ -813,7 +850,8 @@ void GxsChannelPostsWidget::toggleAutoDownload() }); } -bool GxsChannelPostsWidget::insertGroupData(const RsGxsGenericGroupData *data) +#ifdef TODO +bool GxsChannelPostsWidgetWithModel::insertGroupData(const RsGxsGenericGroupData *data) { const RsGxsChannelGroup *d = dynamic_cast(data); @@ -827,67 +865,6 @@ bool GxsChannelPostsWidget::insertGroupData(const RsGxsGenericGroupData *data) return true; } -void GxsChannelPostsWidget::getMsgData(const std::set& msgIds,std::vector& psts) -{ - std::vector posts; - std::vector comments; - std::vector votes; - - rsGxsChannels->getChannelContent( groupId(),msgIds,posts,comments,votes ); - - psts.clear(); - - for(auto& post: posts) - psts.push_back(new RsGxsChannelPost(post)); -} - -void GxsChannelPostsWidget::getAllMsgData(std::vector& psts) -{ - std::vector posts; - std::vector comments; - std::vector votes; - - rsGxsChannels->getChannelAllContent( groupId(),posts,comments,votes ); - - psts.clear(); - - for(auto& post: posts) - psts.push_back(new RsGxsChannelPost(post)); -} - -bool GxsChannelPostsWidget::getGroupData(RsGxsGenericGroupData *& data) -{ - if(groupId().isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " Trying to get data about null group!!" << std::endl; - return false; - } - std::vector groups; - - if(rsGxsChannels->getChannelsInfo(std::list({groupId()}),groups) && groups.size()==1) - { - data = new RsGxsChannelGroup(groups[0]); - - mGroup = groups[0]; // make a local copy to pass on to items - return true; - } - else - { - RsGxsChannelGroup distant_group; - - if(rsGxsChannels->retrieveDistantGroup(groupId(),distant_group)) - { - insertChannelDetails(distant_group); - data = new RsGxsChannelGroup(distant_group); - mGroup = distant_group; // make a local copy to pass on to items - return true ; - } - } - - return false; -} - -#ifdef TODO void GxsChannelPostsWidget::insertAllPosts(const std::vector& posts, GxsMessageFramePostThread *thread) { std::vector cposts; @@ -897,7 +874,6 @@ void GxsChannelPostsWidget::insertAllPosts(const std::vector& posts) { @@ -908,6 +884,7 @@ void GxsChannelPostsWidget::insertPosts(const std::vector& insertChannelPosts(cposts); } +#endif class GxsChannelPostsReadData { @@ -940,14 +917,14 @@ static void setAllMessagesReadCallback(FeedItem *feedItem, void *data) rsGxsChannels->setMessageReadStatus(readData->mLastToken, msgPair, readData->mRead); } -void GxsChannelPostsWidget::setAllMessagesReadDo(bool read, uint32_t &token) +void GxsChannelPostsWidgetWithModel::setAllMessagesReadDo(bool read, uint32_t &token) { - if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(subscribeFlags())) { + if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) { return; } GxsChannelPostsReadData data(read); - ui->feedWidget->withAll(setAllMessagesReadCallback, &data); + //ui->feedWidget->withAll(setAllMessagesReadCallback, &data); token = data.mLastToken; } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h index 31fe597a1..64478a112 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h @@ -28,7 +28,7 @@ #include "gui/feeds/FeedHolder.h" namespace Ui { -class GxsChannelPostsWidget; +class GxsChannelPostsWidgetWithModel; } class GxsChannelPostItem; @@ -36,7 +36,7 @@ class QTreeWidgetItem; class FeedItem; class RsGxsChannelPostsModel; -class GxsChannelPostsWidgetWithModel: public QWidget, public GxsMessageFrameWidget +class GxsChannelPostsWidgetWithModel: public GxsMessageFrameWidget { Q_OBJECT @@ -56,17 +56,19 @@ public: /* GxsMessageFrameWidget */ virtual QIcon groupIcon(); - virtual void groupIdChanged() override; + virtual void groupIdChanged() { updateDisplay(true); } virtual QString groupName(bool) override; virtual bool navigate(const RsGxsMessageId&) override; + void updateDisplay(bool complete); + #ifdef TODO /* FeedHolder */ virtual QScrollArea *getScrollArea(); virtual void deleteFeedItem(FeedItem *feedItem, uint32_t type); virtual void openChat(const RsPeerId& peerId); - virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &msg_versions, const RsGxsMessageId &msgId, const QString &title); #endif + virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &msg_versions, const RsGxsMessageId &msgId, const QString &title); protected: /* GxsMessageFramePostWidget */ @@ -74,10 +76,7 @@ protected: #ifdef TODO virtual bool insertGroupData(const RsGxsGenericGroupData *data) override; #endif - virtual void clearPosts(); virtual bool useThread() { return mUseThread; } - virtual void fillThreadCreatePost(const QVariant &post, bool related, int current, int count); - virtual bool navigatePostItem(const RsGxsMessageId& msgId); virtual void blank() ; #ifdef TODO @@ -92,6 +91,7 @@ protected: virtual void setAllMessagesReadDo(bool read, uint32_t &token); private slots: + void updateGroupData(); void createMsg(); void toggleAutoDownload(); void subscribeGroup(bool subscribe); @@ -108,9 +108,6 @@ private: int viewMode(); void insertChannelDetails(const RsGxsChannelGroup &group); - void insertChannelPosts(std::vector &posts, GxsMessageFramePostThread *thread, bool related); - - void createPostItem(const RsGxsChannelPost &post, bool related); void handleEvent_main_thread(std::shared_ptr event); private: @@ -124,7 +121,7 @@ private: UIStateHelper *mStateHelper; /* UI - from Designer */ - Ui::GxsChannelPostsWidget *ui; + Ui::GxsChannelPostsWidgetWithModel *ui; }; #endif diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 02eb74334..5e7e481b3 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -498,6 +498,7 @@ void GxsForumThreadWidget::recursRestoreExpandedItems(const QModelIndex& /*index ui->threadTreeWidget->setExpanded( mThreadProxyModel->mapFromSource(mThreadModel->getIndexOfMessage(*it)) ,true) ; } + void GxsForumThreadWidget::updateDisplay(bool complete) { #ifdef DEBUG_FORUMS