fixed crash in NewFeed when attempting to find a widget using its identifier

This commit is contained in:
csoler 2020-01-16 20:33:34 +01:00
parent c552890459
commit 5df7f7667f
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
7 changed files with 44 additions and 35 deletions

View File

@ -49,7 +49,7 @@ public:
const RsPostedPost &getPost() const; const RsPostedPost &getPost() const;
RsPostedPost &post(); RsPostedPost &post();
uint64_t uniqueIdentifier() const override { return hash_64bits("PostedItem " + mMessageId.toStdString()); } uint64_t uniqueIdentifier() const override { return hash_64bits("PostedItem " + messageId().toStdString()); }
protected: protected:
/* FeedItem */ /* FeedItem */
virtual void doExpand(bool open); virtual void doExpand(bool open);

View File

@ -379,11 +379,10 @@ FeedItem *RSFeedWidget::feedItem(int index)
void RSFeedWidget::removeFeedItem(FeedItem *feedItem) void RSFeedWidget::removeFeedItem(FeedItem *feedItem)
{ {
if (!feedItem) { if (!feedItem)
return; return;
}
QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem->uniqueIdentifier()); QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem);// WARNING: do not use the other function based on identifier here, because some items change their identifier when loading.
if (treeItem) if (treeItem)
{ {
@ -391,7 +390,7 @@ void RSFeedWidget::removeFeedItem(FeedItem *feedItem)
if(treeItem_index < 0) if(treeItem_index < 0)
{ {
std::cerr << "(EE) Cannot remove designated item \"" << feedItem->uniqueIdentifier() << "\": not found!" << std::endl; std::cerr << "(EE) Cannot remove designated item \"" << (void*)feedItem << "\": not found!" << std::endl;
return ; return ;
} }
@ -431,6 +430,26 @@ void RSFeedWidget::feedItemDestroyed(qulonglong id)
emit feedCountChanged(); emit feedCountChanged();
} }
QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(const FeedItem *w)
{
QTreeWidgetItemIterator it(ui->treeWidget);
QTreeWidgetItem *treeItem=NULL;
// this search could probably be automatised by giving the tree items the identifier as data for some specific role, then calling QTreeWidget::findItems()
#warning TODO
while (*it)
{
FeedItem *feedItem = feedItemFromTreeItem(*it);
if (feedItem == w)
return *it;
++it;
}
return NULL;
}
QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(uint64_t identifier) QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(uint64_t identifier)
{ {
QList<QTreeWidgetItem*> list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER); QList<QTreeWidgetItem*> list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER);
@ -483,27 +502,21 @@ void RSFeedWidget::withAll(RSFeedWidgetCallbackFunction callback, void *data)
FeedItem *RSFeedWidget::findFeedItem(uint64_t identifier) FeedItem *RSFeedWidget::findFeedItem(uint64_t identifier)
{ {
QTreeWidgetItemIterator it(ui->treeWidget); QList<QTreeWidgetItem*> list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER);
QTreeWidgetItem *treeItem=NULL;
// this search could probably be automatised by giving the tree items the identifier as data for some specific role, then calling QTreeWidget::findItems() if(list.empty())
#warning TODO return nullptr;
while ((treeItem = *it) != NULL) { else if(list.size() == 1)
++it; return feedItemFromTreeItem(list.front());
else
FeedItem *feedItem = feedItemFromTreeItem(treeItem); {
if (!feedItem) std::cerr << "(EE) More than a single item with identifier \"" << identifier << "\" in the feed tree widget. This shouldn't happen!" << std::endl;
continue; return nullptr;
}
uint64_t id = feedItem->uniqueIdentifier();
if (id == identifier)
return feedItem;
}
return NULL;
} }
void RSFeedWidget::selectedFeedItems(QList<FeedItem*> &feedItems) void RSFeedWidget::selectedFeedItems(QList<FeedItem*> &feedItems)
{ {
foreach (QTreeWidgetItem *treeItem, ui->treeWidget->selectedItems()) { foreach (QTreeWidgetItem *treeItem, ui->treeWidget->selectedItems()) {

View File

@ -98,6 +98,7 @@ private:
void disconnectSignals(FeedItem *feedItem); void disconnectSignals(FeedItem *feedItem);
FeedItem *feedItemFromTreeItem(QTreeWidgetItem *treeItem); FeedItem *feedItemFromTreeItem(QTreeWidgetItem *treeItem);
QTreeWidgetItem *findTreeWidgetItem(uint64_t identifier); QTreeWidgetItem *findTreeWidgetItem(uint64_t identifier);
QTreeWidgetItem *findTreeWidgetItem(const FeedItem *w);
void filterItems(); void filterItems();
void filterItem(QTreeWidgetItem *treeItem, FeedItem *feedItem); void filterItem(QTreeWidgetItem *treeItem, FeedItem *feedItem);

View File

@ -69,13 +69,5 @@ void FeedItem::removeItem()
#endif #endif
mFeedHolder->deleteFeedItem(this,0); mFeedHolder->deleteFeedItem(this,0);
// mFeedHolder->lockLayout(this, true);
// hide();
//
// if (mFeedHolder)
// mFeedHolder->deleteFeedItem(this, mFeedId);
//
// mFeedHolder->lockLayout(this, false);
} }

View File

@ -46,12 +46,14 @@
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) : GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate) GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate)
{ {
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
init(messageId,older_versions) ; init(messageId,older_versions) ;
} }
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) : GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate) GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
{ {
mPost.mMeta.mMsgId.clear(); // security
init(post.mMeta.mMsgId,older_versions) ; init(post.mMeta.mMsgId,older_versions) ;
mPost = post ; mPost = post ;
} }
@ -71,7 +73,6 @@ void GxsChannelPostItem::init(const RsGxsMessageId& messageId,const std::set<RsG
setup(); setup();
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
mLoaded = false ; mLoaded = false ;
} }
@ -326,12 +327,14 @@ void GxsChannelPostItem::loadMessage(const uint32_t &token)
if (posts.size() == 1) if (posts.size() == 1)
{ {
std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl;
setPost(posts[0]); setPost(posts[0]);
} }
else if (cmts.size() == 1) else if (cmts.size() == 1)
{ {
RsGxsComment cmt = cmts[0]; RsGxsComment cmt = cmts[0];
std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl;
ui->newCommentLabel->show(); ui->newCommentLabel->show();
ui->commLabel->show(); ui->commLabel->show();
ui->commLabel->setText(QString::fromUtf8(cmt.mComment.c_str())); ui->commLabel->setText(QString::fromUtf8(cmt.mComment.c_str()));

View File

@ -53,7 +53,7 @@ public:
//GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate); //GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate);
virtual ~GxsChannelPostItem(); virtual ~GxsChannelPostItem();
uint64_t uniqueIdentifier() const override { hash_64bits("GxsChannelPostItem " + mPost.mMeta.mMsgId.toStdString()) ; } uint64_t uniqueIdentifier() const override { hash_64bits("GxsChannelPostItem " + messageId().toStdString()) ; }
bool setGroup(const RsGxsChannelGroup &group, bool doFill = true); bool setGroup(const RsGxsChannelGroup &group, bool doFill = true);
bool setPost(const RsGxsChannelPost &post, bool doFill = true); bool setPost(const RsGxsChannelPost &post, bool doFill = true);
@ -66,7 +66,7 @@ public:
bool isUnread() const ; bool isUnread() const ;
static uint64_t computeIdentifier(const RsGxsMessageId& msgid) { hash64("GxsChannelPostItem " + msgid.toStdString()) ; } static uint64_t computeIdentifier(const RsGxsMessageId& msgid) { return hash64("GxsChannelPostItem " + msgid.toStdString()) ; }
protected: protected:
void init(const RsGxsMessageId& messageId,const std::set<RsGxsMessageId>& older_versions); void init(const RsGxsMessageId& messageId,const std::set<RsGxsMessageId>& older_versions);

View File

@ -43,7 +43,7 @@ public:
bool setGroup(const RsGxsForumGroup &group, bool doFill = true); bool setGroup(const RsGxsForumGroup &group, bool doFill = true);
bool setMessage(const RsGxsForumMsg &msg, bool doFill = true); bool setMessage(const RsGxsForumMsg &msg, bool doFill = true);
uint64_t uniqueIdentifier() const override { return hash_64bits("GxsForumMsgItem " + mMessage.mMeta.mMsgId.toStdString()) ; } uint64_t uniqueIdentifier() const override { return hash_64bits("GxsForumMsgItem " + messageId().toStdString()) ; }
protected: protected:
/* FeedItem */ /* FeedItem */
virtual void doExpand(bool open); virtual void doExpand(bool open);