restore expand state after item is no longer filtered out, fixes #1262

This commit is contained in:
Martin Rotter 2024-04-10 12:18:21 +02:00
parent 895be5a92b
commit 527987b0dc
4 changed files with 56 additions and 16 deletions

View File

@ -322,6 +322,25 @@ bool FeedsProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right
bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const {
bool should_show = filterAcceptsRowInternal(source_row, source_parent);
if (should_show && m_hiddenIndices.contains(QPair<int, QModelIndex>(source_row, source_parent))) {
qDebugNN << LOGSEC_CORE << "Item"
<< QUOTE_W_SPACE(m_sourceModel
->data(m_sourceModel->index(source_row, 0, source_parent), Qt::ItemDataRole::EditRole)
.toString())
<< "was previously hidden and now shows up, expand.";
const_cast<FeedsProxyModel*>(this)->m_hiddenIndices.removeAll(QPair<int, QModelIndex>(source_row, source_parent));
// Now, item now should be displayed and previously it was not.
// Expand!
emit indexNotFilteredOutAnymore(m_sourceModel->index(source_row, 0, source_parent));
}
if (!should_show) {
const_cast<FeedsProxyModel*>(this)->m_hiddenIndices.append(QPair<int, QModelIndex>(source_row, source_parent));
}
return should_show;
}

View File

@ -56,7 +56,7 @@ class FeedsProxyModel : public QSortFilterProxyModel {
void invalidateReadFeedsFilter(bool set_new_value = false, bool show_unread_only = false);
signals:
void expandAfterFilterIn(QModelIndex source_idx) const;
void indexNotFilteredOutAnymore(QModelIndex source_idx) const;
// There was some drag/drop operation, notify view about this.
void requireItemValidationAfterDragDrop(const QModelIndex& source_index);
@ -79,6 +79,7 @@ class FeedsProxyModel : public QSortFilterProxyModel {
bool m_showNodeLabels;
bool m_showNodeImportant;
QList<RootItem::Kind> m_priorities;
QList<QPair<int, QModelIndex>> m_hiddenIndices;
};
#endif // FEEDSPROXYMODEL_H

View File

@ -42,6 +42,7 @@ FeedsView::FeedsView(QWidget* parent)
m_proxyModel->setView(this);
// Connections.
connect(&m_expansionDelayer, &QTimer::timeout, this, &FeedsView::reloadDelayedExpansions);
connect(m_sourceModel, &FeedsModel::itemExpandRequested, this, &FeedsView::onItemExpandRequested);
connect(m_sourceModel, &FeedsModel::itemExpandStateSaveRequested, this, &FeedsView::onItemExpandStateSaveRequested);
connect(header(), &QHeaderView::sortIndicatorChanged, this, &FeedsView::saveSortState);
@ -49,7 +50,7 @@ FeedsView::FeedsView(QWidget* parent)
&FeedsProxyModel::requireItemValidationAfterDragDrop,
this,
&FeedsView::validateItemAfterDragDrop);
connect(m_proxyModel, &FeedsProxyModel::expandAfterFilterIn, this, &FeedsView::expandItemDelayed);
connect(m_proxyModel, &FeedsProxyModel::indexNotFilteredOutAnymore, this, &FeedsView::reloadItemExpandState);
connect(this, &FeedsView::expanded, this, &FeedsView::onIndexExpanded);
connect(this, &FeedsView::collapsed, this, &FeedsView::onIndexCollapsed);
@ -818,6 +819,24 @@ void FeedsView::onIndexCollapsed(const QModelIndex& idx) {
}
}
void FeedsView::reloadDelayedExpansions() {
qDebugNN << LOGSEC_GUI << "Reloading delayed feed list expansions.";
m_expansionDelayer.stop();
m_dontSaveExpandState = true;
for (const QPair<QModelIndex, bool>& exp : m_delayedItemExpansions) {
auto idx = m_proxyModel->mapFromSource(exp.first);
if (idx.isValid()) {
setExpanded(idx, exp.second);
}
}
m_dontSaveExpandState = false;
m_delayedItemExpansions.clear();
}
void FeedsView::onItemExpandStateSaveRequested(RootItem* item) {
saveExpandStates(item);
}
@ -862,25 +881,22 @@ void FeedsView::loadAllExpandStates() {
.toInt()));
}
void FeedsView::expandItemDelayed(const QModelIndex& source_idx) {
// QTimer::singleShot(100, this, [=] {
void FeedsView::reloadItemExpandState(const QModelIndex& source_idx) {
// Model requests to expand some items as they are visible and there is
// a filter active, so they maybe were not visible before.
QModelIndex pidx = m_proxyModel->mapFromSource(source_idx);
// NOTE: These changes are caused by filtering mechanisms
// and we don't want to store the values.
m_dontSaveExpandState = true;
RootItem* it = m_sourceModel->itemForIndex(source_idx);
#if QT_VERSION >= 0x050D00 // Qt >= 5.13.0
expandRecursively(pidx);
#else
setExpanded(pidx, true);
#endif
if (it == nullptr) {
return;
}
m_dontSaveExpandState = false;
const QString setting_name = it->hashCode();
const bool expand =
qApp->settings()->value(GROUP(CategoriesExpandStates), setting_name, it->childCount() > 0).toBool();
//});
m_delayedItemExpansions.append({source_idx, expand});
m_expansionDelayer.start(300);
}
QMenu* FeedsView::initializeContextMenuCategories(RootItem* clicked_item) {

View File

@ -8,6 +8,7 @@
#include "gui/toolbars/feedstoolbar.h"
#include <QStyledItemDelegate>
#include <QTimer>
class FeedsProxyModel;
class Feed;
@ -107,7 +108,8 @@ class RSSGUARD_DLLSPEC FeedsView : public BaseTreeView {
void onIndexExpanded(const QModelIndex& idx);
void onIndexCollapsed(const QModelIndex& idx);
void expandItemDelayed(const QModelIndex& source_idx);
void reloadDelayedExpansions();
void reloadItemExpandState(const QModelIndex& source_idx);
void markSelectedItemReadStatus(RootItem::ReadStatus read);
void markAllItemsReadStatus(RootItem::ReadStatus read);
@ -146,6 +148,8 @@ class RSSGUARD_DLLSPEC FeedsView : public BaseTreeView {
FeedsModel* m_sourceModel;
FeedsProxyModel* m_proxyModel;
bool m_dontSaveExpandState;
QList<QPair<QModelIndex, bool>> m_delayedItemExpansions;
QTimer m_expansionDelayer;
// QTreeView interface
protected: