diff --git a/src/librssguard/core/feedsproxymodel.cpp b/src/librssguard/core/feedsproxymodel.cpp index a60bf4193..53fc34397 100644 --- a/src/librssguard/core/feedsproxymodel.cpp +++ b/src/librssguard/core/feedsproxymodel.cpp @@ -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(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(this)->m_hiddenIndices.removeAll(QPair(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(this)->m_hiddenIndices.append(QPair(source_row, source_parent)); + } + return should_show; } diff --git a/src/librssguard/core/feedsproxymodel.h b/src/librssguard/core/feedsproxymodel.h index f38c92bd7..deac1b8db 100644 --- a/src/librssguard/core/feedsproxymodel.h +++ b/src/librssguard/core/feedsproxymodel.h @@ -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 m_priorities; + QList> m_hiddenIndices; }; #endif // FEEDSPROXYMODEL_H diff --git a/src/librssguard/gui/feedsview.cpp b/src/librssguard/gui/feedsview.cpp index 4aa5dbb39..816d25d86 100644 --- a/src/librssguard/gui/feedsview.cpp +++ b/src/librssguard/gui/feedsview.cpp @@ -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& 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) { diff --git a/src/librssguard/gui/feedsview.h b/src/librssguard/gui/feedsview.h index 9e4b8bc22..a57caee9f 100644 --- a/src/librssguard/gui/feedsview.h +++ b/src/librssguard/gui/feedsview.h @@ -8,6 +8,7 @@ #include "gui/toolbars/feedstoolbar.h" #include +#include 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> m_delayedItemExpansions; + QTimer m_expansionDelayer; // QTreeView interface protected: