diff --git a/src/librssguard/core/feedsproxymodel.h b/src/librssguard/core/feedsproxymodel.h index 780236045..bcea633df 100644 --- a/src/librssguard/core/feedsproxymodel.h +++ b/src/librssguard/core/feedsproxymodel.h @@ -36,7 +36,7 @@ class FeedsProxyModel : public QSortFilterProxyModel { void invalidateReadFeedsFilter(bool set_new_value = false, bool show_unread_only = false); signals: - void expandAfterFilterIn(QModelIndex idx) const; + void expandAfterFilterIn(QModelIndex source_idx) const; private: diff --git a/src/librssguard/gui/feedmessageviewer.cpp b/src/librssguard/gui/feedmessageviewer.cpp index 43add0ad0..1c2733ccc 100644 --- a/src/librssguard/gui/feedmessageviewer.cpp +++ b/src/librssguard/gui/feedmessageviewer.cpp @@ -86,7 +86,7 @@ FeedsToolBar* FeedMessageViewer::feedsToolBar() const { void FeedMessageViewer::saveSize() { Settings* settings = qApp->settings(); - m_feedsView->saveAllExpandStates(); + //m_feedsView->saveAllExpandStates(); // Store offsets of splitters. settings->setValue(GROUP(GUI), GUI::SplitterFeeds, toVariant(m_feedSplitter->sizes())); @@ -357,10 +357,11 @@ void FeedMessageViewer::refreshVisualProperties() { if (icon_size > 0) { m_toolBarFeeds->setIconSize({ icon_size, icon_size }); - m_toolBarMessages->setIconSize({ icon_size, icon_size }); } else { m_toolBarFeeds->setIconSize({ qApp->style()->pixelMetric(QStyle::PM_ToolBarIconSize), qApp->style()->pixelMetric(QStyle::PM_ToolBarIconSize) }); } + + m_toolBarMessages->setIconSize(m_toolBarFeeds->iconSize()); } diff --git a/src/librssguard/gui/feedsview.cpp b/src/librssguard/gui/feedsview.cpp index 0ba1968d1..beda61599 100644 --- a/src/librssguard/gui/feedsview.cpp +++ b/src/librssguard/gui/feedsview.cpp @@ -30,7 +30,7 @@ FeedsView::FeedsView(QWidget* parent) : BaseTreeView(parent), m_contextMenuService(nullptr), m_contextMenuBin(nullptr), m_contextMenuCategories(nullptr), m_contextMenuFeeds(nullptr), m_contextMenuImportant(nullptr), m_contextMenuEmptySpace(nullptr), m_contextMenuOtherItems(nullptr), - m_contextMenuLabel(nullptr) { + m_contextMenuLabel(nullptr), m_isFiltering(false) { setObjectName(QSL("FeedsView")); // Allocate models. @@ -44,8 +44,12 @@ FeedsView::FeedsView(QWidget* parent) connect(m_sourceModel, &FeedsModel::itemExpandRequested, this, &FeedsView::onItemExpandRequested); connect(m_sourceModel, &FeedsModel::itemExpandStateSaveRequested, this, &FeedsView::onItemExpandStateSaveRequested); connect(header(), &QHeaderView::sortIndicatorChanged, this, &FeedsView::saveSortState); + connect(m_proxyModel, &FeedsProxyModel::expandAfterFilterIn, this, &FeedsView::expandItemDelayed); + connect(this, &FeedsView::expanded, this, &FeedsView::onIndexExpanded); + connect(this, &FeedsView::collapsed, this, &FeedsView::onIndexCollapsed); + setModel(m_proxyModel); setupAppearance(); } @@ -88,60 +92,6 @@ RootItem* FeedsView::selectedItem() const { } } -void FeedsView::onItemExpandStateSaveRequested(RootItem* item) { - saveExpandStates(item); -} - -void FeedsView::saveAllExpandStates() { - saveExpandStates(sourceModel()->rootItem()); -} - -void FeedsView::saveExpandStates(RootItem* item) { - Settings* settings = qApp->settings(); - QList items = item->getSubTree(RootItem::Kind::Category | - RootItem::Kind::ServiceRoot | - RootItem::Kind::Labels); - - // Iterate all categories and save their expand statuses. - for (const RootItem* it : items) { - const QString setting_name = it->hashCode(); - QModelIndex source_index = sourceModel()->indexForItem(it); - QModelIndex visible_index = model()->mapFromSource(source_index); - - // TODO: Think. - - /* - if (isRowHidden(visible_index.row(), visible_index.parent())) { - continue; - } - */ - - settings->setValue(GROUP(CategoriesExpandStates), - setting_name, - isExpanded(visible_index)); - } -} - -void FeedsView::loadAllExpandStates() { - const Settings* settings = qApp->settings(); - QList expandable_items; - - expandable_items.append(sourceModel()->rootItem()->getSubTree(RootItem::Kind::Category | - RootItem::Kind::ServiceRoot | - RootItem::Kind::Labels)); - - // Iterate all categories and save their expand statuses. - for (const RootItem* item : expandable_items) { - const QString setting_name = item->hashCode(); - - setExpanded(model()->mapFromSource(sourceModel()->indexForItem(item)), - settings->value(GROUP(CategoriesExpandStates), setting_name, item->childCount() > 0).toBool()); - } - - sortByColumn(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortColumnFeeds)).toInt(), - static_cast(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortOrderFeeds)).toInt())); -} - void FeedsView::copyUrlOfSelectedFeeds() const { auto feeds = selectedFeeds(); QStringList urls; @@ -525,18 +475,6 @@ void FeedsView::switchVisibility() { setVisible(!isVisible()); } -void FeedsView::filterItems(const QString& pattern) { -#if QT_VERSION < 0x050C00 // Qt < 5.12.0 - m_proxyModel->setFilterRegExp(pattern.toLower()); -#else - m_proxyModel->setFilterRegularExpression(pattern.toLower()); -#endif - - if (!pattern.simplified().isEmpty()) { - expandAll(); - } -} - void FeedsView::drawBranches(QPainter* painter, const QRect& rect, const QModelIndex& index) const { if (!rootIsDecorated()) { painter->save(); @@ -558,12 +496,135 @@ void FeedsView::focusInEvent(QFocusEvent* event) { } } -void FeedsView::expandItemDelayed(const QModelIndex& idx) { - QTimer::singleShot(100, this, [=] { - QModelIndex pidx = m_proxyModel->mapFromSource(idx); +void FeedsView::filterItems(const QString& pattern) { + m_isFiltering = !pattern.isEmpty(); + +#if QT_VERSION < 0x050C00 // Qt < 5.12.0 + m_proxyModel->setFilterRegExp(pattern.toLower()); +#else + m_proxyModel->setFilterRegularExpression(pattern.toLower()); +#endif + + if (pattern.isEmpty()) { + loadAllExpandStates(); + } + else { + expandAll(); + } +} + +void FeedsView::onIndexExpanded(const QModelIndex& idx) { + qDebugNN << LOGSEC_GUI << "Feed list item expanded - " << m_proxyModel->data(idx).toString(); + + if (m_isFiltering) { + return; + } + + const RootItem* it = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(idx)); + + if (it != nullptr && (int(it->kind()) & int(RootItem::Kind::Category | + RootItem::Kind::ServiceRoot | + RootItem::Kind::Labels)) > 0) { + const QString setting_name = it->hashCode(); + + qApp->settings()->setValue(GROUP(CategoriesExpandStates), + setting_name, + true); + } +} + +void FeedsView::onIndexCollapsed(const QModelIndex& idx) { + qDebugNN << LOGSEC_GUI << "Feed list item collapsed - " << m_proxyModel->data(idx).toString(); + + if (m_isFiltering) { + return; + } + + RootItem* it = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(idx)); + + if (it != nullptr && (int(it->kind()) & int(RootItem::Kind::Category | + RootItem::Kind::ServiceRoot | + RootItem::Kind::Labels)) > 0) { + const QString setting_name = it->hashCode(); + + qApp->settings()->setValue(GROUP(CategoriesExpandStates), + setting_name, + false); + } +} + +void FeedsView::onItemExpandStateSaveRequested(RootItem* item) { + saveExpandStates(item); +} + +void FeedsView::saveAllExpandStates() { + saveExpandStates(sourceModel()->rootItem()); +} + +void FeedsView::saveExpandStates(RootItem* item) { + Settings* settings = qApp->settings(); + QList items = item->getSubTree(RootItem::Kind::Category | + RootItem::Kind::ServiceRoot | + RootItem::Kind::Labels); + + // Iterate all categories and save their expand statuses. + for (const RootItem* it : items) { + const QString setting_name = it->hashCode(); + QModelIndex source_index = sourceModel()->indexForItem(it); + QModelIndex visible_index = model()->mapFromSource(source_index); + + // TODO: Think. + + /* + if (isRowHidden(visible_index.row(), visible_index.parent())) { + continue; + } + */ + + settings->setValue(GROUP(CategoriesExpandStates), + setting_name, + isExpanded(visible_index)); + } +} + +bool FeedsView::isFiltering() const +{ + return m_isFiltering; +} + +void FeedsView::setIsFiltering(bool newIsFiltering) +{ + m_isFiltering = newIsFiltering; +} + +void FeedsView::loadAllExpandStates() { + const Settings* settings = qApp->settings(); + QList expandable_items; + + expandable_items.append(sourceModel()->rootItem()->getSubTree(RootItem::Kind::Category | + RootItem::Kind::ServiceRoot | + RootItem::Kind::Labels)); + + // Iterate all categories and save their expand statuses. + for (const RootItem* item : expandable_items) { + const QString setting_name = item->hashCode(); + + setExpanded(model()->mapFromSource(sourceModel()->indexForItem(item)), + settings->value(GROUP(CategoriesExpandStates), setting_name, item->childCount() > 0).toBool()); + } + + sortByColumn(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortColumnFeeds)).toInt(), + static_cast(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortOrderFeeds)).toInt())); +} + +void FeedsView::expandItemDelayed(const QModelIndex& source_idx) { + if (m_isFiltering) { + QTimer::singleShot(100, this, [=] { + QModelIndex pidx = m_proxyModel->mapFromSource(source_idx); - setExpanded(pidx, true); - }); + setExpanded(pidx, true); + }); + } } QMenu* FeedsView::initializeContextMenuCategories(RootItem* clicked_item) { diff --git a/src/librssguard/gui/feedsview.h b/src/librssguard/gui/feedsview.h index 046df78c7..ec2293162 100644 --- a/src/librssguard/gui/feedsview.h +++ b/src/librssguard/gui/feedsview.h @@ -39,6 +39,9 @@ class RSSGUARD_DLLSPEC FeedsView : public BaseTreeView { void saveAllExpandStates(); void loadAllExpandStates(); + bool isFiltering() const; + void setIsFiltering(bool newIsFiltering); + public slots: void copyUrlOfSelectedFeeds() const; void sortByColumn(int column, Qt::SortOrder order); @@ -91,7 +94,10 @@ class RSSGUARD_DLLSPEC FeedsView : public BaseTreeView { void mouseDoubleClickEvent(QMouseEvent* event); private slots: - void expandItemDelayed(const QModelIndex& idx); + void onIndexExpanded(const QModelIndex& idx); + void onIndexCollapsed(const QModelIndex& idx); + + void expandItemDelayed(const QModelIndex& source_idx); void markSelectedItemReadStatus(RootItem::ReadStatus read); void markAllItemsReadStatus(RootItem::ReadStatus read); @@ -127,6 +133,7 @@ class RSSGUARD_DLLSPEC FeedsView : public BaseTreeView { QMenu* m_contextMenuLabel; FeedsModel* m_sourceModel; FeedsProxyModel* m_proxyModel; + bool m_isFiltering; }; inline FeedsProxyModel* FeedsView::model() const {