diff --git a/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp b/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp index e827a2fbb..d4a81a3f6 100644 --- a/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp +++ b/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp @@ -223,12 +223,10 @@ void RsPostedPostsModel::setFilter(const QStringList& strings, uint32_t& count) std::cerr << "After filtering: " << count << " posts remain." << std::endl; - if (rowCount()>0) - { - beginInsertRows(QModelIndex(),0,rowCount()-1); - endInsertRows(); - } - + // No beginInsertRows() here: the filtered set is rebuilt from scratch above, so + // the surrounding reset + postMods() (layoutChanged) refresh the view. Faking a + // row insertion with a mismatched range is a lie to the view (same anti-pattern + // that could blank the channels grid) and is not needed. postMods(); } @@ -572,12 +570,9 @@ void RsPostedPostsModel::setPosts(const RsPostedGroup& group, std::vector0) - { - beginInsertRows(QModelIndex(),0,rowCount()-1); - endInsertRows(); - } - + // No beginInsertRows() here: setFilter() above already reset and repopulated the + // model, so postMods() (layoutChanged) is enough. Faking a row insertion with a + // mismatched range is the same anti-pattern that could blank the channels grid. postMods(); emit boardPostsLoaded(); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp index 22d1dbcba..7124d0317 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp @@ -75,6 +75,15 @@ void RsGxsChannelPostsModel::initEmptyHierarchy() mPosts.clear(); mFilteredPosts.clear(); + // Reset the active filter on every (re)load. initEmptyHierarchy() is run by + // setPosts(), and the widget clears the search box silently (whileBlocking) + // without notifying the model; a filter left over from a previously viewed + // channel would otherwise be re-applied by updateFilter() on the next incoming + // post and could hide every post. Doing it here keeps the fix independent of + // how setPosts() is implemented. + mFilteredStrings.clear(); + mFilterUnread = false; + endResetModel(); } @@ -147,12 +156,12 @@ void RsGxsChannelPostsModel::updateFilter(uint32_t& count) count = mFilteredPosts.size(); - if (rowCount()>0) - { - beginInsertRows(QModelIndex(),0,rowCount()-1); - endInsertRows(); - } - + // The row<->post mapping is fully rebuilt above (posts may have been added, + // removed or reordered by the caller), so we signal a layout change through the + // preMods()/postMods() pair rather than faking a row insertion. Emitting + // beginInsertRows() with a range that does not match a real insertion left the + // attached view inconsistent and could randomly blank the grid right after a + // post was added (only a full channel reload fixed it). postMods(); } @@ -461,7 +470,10 @@ void RsGxsChannelPostsModel::updateSinglePost(const RsGxsChannelPost& post,std:: added_files.clear(); removed_files.clear(); - emit layoutAboutToBeChanged(); + // NB: no emit layoutAboutToBeChanged() here. The single balanced layout-change + // signal is emitted by updateFilter() below (preMods()/postMods()). Opening a + // second, unmatched layoutAboutToBeChanged() here left the view stuck in a + // "layout changing" state and could randomly blank the grid after a new post. // linear search. Not good at all, but normally this is just for a single post.