From b242394c0f9c24ca8f9bbced44076abbcd274fee Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Mon, 4 Jan 2021 19:37:20 +0100 Subject: Keep track of expanded items in the view instead of the models. --- src/modlistbypriorityproxy.cpp | 32 --------------------- src/modlistbypriorityproxy.h | 13 +-------- src/modlistview.cpp | 63 +++++++++++++++++++++--------------------- src/modlistview.h | 11 ++++++-- src/qtgroupingproxy.cpp | 24 ---------------- src/qtgroupingproxy.h | 17 ------------ 6 files changed, 40 insertions(+), 120 deletions(-) (limited to 'src') diff --git a/src/modlistbypriorityproxy.cpp b/src/modlistbypriorityproxy.cpp index bf3c2d09..6f549d91 100644 --- a/src/modlistbypriorityproxy.cpp +++ b/src/modlistbypriorityproxy.cpp @@ -88,20 +88,6 @@ void ModListByPriorityProxy::buildTree() m_Root.children.push_back(std::move(overwrite)); endResetModel(); - - // restore expand-state - expandItems(QModelIndex()); -} - -void ModListByPriorityProxy::expandItems(const QModelIndex& index) const -{ - for (int row = 0; row < rowCount(index); row++) { - QModelIndex idx = this->index(row, 0, index); - if (!m_CollapsedItems.contains(idx.data(Qt::DisplayRole).toString())) { - emit expandItem(idx); - } - expandItems(idx); - } } void ModListByPriorityProxy::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles) @@ -334,21 +320,3 @@ void ModListByPriorityProxy::onDropEnter(const QMimeData*, ModListView::DropPosi { m_dropPosition = dropPosition; } - -void ModListByPriorityProxy::refreshExpandedItems() const -{ - expandItems(QModelIndex()); -} - -void ModListByPriorityProxy::expanded(const QModelIndex& index) -{ - auto it = m_CollapsedItems.find(index.data(Qt::DisplayRole).toString()); - if (it != m_CollapsedItems.end()) { - m_CollapsedItems.erase(it); - } -} - -void ModListByPriorityProxy::collapsed(const QModelIndex& index) -{ - m_CollapsedItems.insert(index.data(Qt::DisplayRole).toString()); -} diff --git a/src/modlistbypriorityproxy.h b/src/modlistbypriorityproxy.h index e5a8adff..6b48678a 100644 --- a/src/modlistbypriorityproxy.h +++ b/src/modlistbypriorityproxy.h @@ -44,28 +44,17 @@ public: QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override; QModelIndex mapToSource(const QModelIndex& proxyIndex) const override; - // check the internal state for expanded/collapse items and emit a expandItem - // signal for each of the expanded item, useful to refresh the tree state after - // layout modification - void refreshExpandedItems() const; - -signals: - void expandItem(const QModelIndex& index) const; - public slots: void onDropEnter(const QMimeData* data, ModListView::DropPosition dropPosition); - void expanded(const QModelIndex& index); - void collapsed(const QModelIndex& index); -protected: +protected slots: void modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles = QVector()); private: void buildTree(); - void expandItems(const QModelIndex& index) const; struct TreeItem { ModInfo::Ptr mod; diff --git a/src/modlistview.cpp b/src/modlistview.cpp index 6399e910..67dc1c02 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -360,15 +360,14 @@ void ModListView::setSelected(const QModelIndex& current, const QModelIndexList& } } -void ModListView::expandItem(const QModelIndex& index) +void ModListView::refreshExpandedItems() { - // the group proxy (QtGroupingProxy and ModListByPriorityProxy) emit - // those with their own index, so we need to do this manually - if (index.model() == m_sortProxy->sourceModel()) { - setExpanded(m_sortProxy->mapFromSource(index), true); - } - else if (index.model() == model()) { - setExpanded(index, true); + auto* model = m_sortProxy->sourceModel(); + for (auto i = 0; i < model->rowCount(); ++i) { + auto idx = model->index(i, 0); + if (!m_collapsed[model].contains(idx.data(Qt::DisplayRole).toString())) { + setExpanded(m_sortProxy->mapFromSource(idx), true); + } } } @@ -631,18 +630,6 @@ bool ModListView::toggleSelectionState() return m_core->modList()->toggleState(indexViewToModel(selectionModel()->selectedRows())); } -// helper function because QtGroupingProxy and ModListByPriorityProxy -// have similar methods but do not share a common parent class -template -void setProxy(OrganizerCore* core, QTreeView* view, ModListSortProxy* sortProxy, Proxy* proxy) -{ - proxy->setSourceModel(core->modList()); - sortProxy->setSourceModel(proxy); - QObject::connect(view, &QTreeView::expanded, proxy, &Proxy::expanded); - QObject::connect(view, &QTreeView::collapsed, proxy, &Proxy::collapsed); - proxy->refreshExpandedItems(); -} - void ModListView::updateGroupByProxy(int groupIndex) { // if the index is -1, we do not refresh unless we are grouping @@ -655,21 +642,29 @@ void ModListView::updateGroupByProxy(int groupIndex) } auto* previousModel = m_sortProxy->sourceModel(); + QAbstractProxyModel* nextProxy = nullptr; if (groupIndex == GroupBy::CATEGORY) { - setProxy(m_core, this, m_sortProxy, m_byCategoryProxy); + nextProxy = m_byCategoryProxy; } else if (groupIndex == GroupBy::NEXUS_ID) { - setProxy(m_core, this, m_sortProxy, m_byNexusIdProxy); + nextProxy = m_byNexusIdProxy; } else if (m_core->settings().interface().collapsibleSeparators() && m_sortProxy->sortColumn() == ModList::COL_PRIORITY && m_sortProxy->sortOrder() == Qt::AscendingOrder) { - setProxy(m_core, this, m_sortProxy, m_byPriorityProxy); + nextProxy = m_byPriorityProxy; } - else { - m_sortProxy->setSourceModel(m_core->modList()); + + QAbstractItemModel* nextModel = m_core->modList(); + if (nextProxy) { + nextProxy->setSourceModel(m_core->modList()); + nextModel = nextProxy; } + m_sortProxy->setSourceModel(nextModel); + + // expand items previously expanded + refreshExpandedItems(); if (hasCollapsibleSeparators()) { ui.filterSeparators->setCurrentIndex(ModListSortProxy::SeparatorFilter); @@ -682,11 +677,8 @@ void ModListView::updateGroupByProxy(int groupIndex) // reset the source model of the old proxy because we do not want to // react to signals // - // also stop notifying the old proxy when items are expanded - // if (auto* proxy = qobject_cast(previousModel)) { proxy->setSourceModel(nullptr); - disconnect(this, nullptr, proxy, nullptr); } } @@ -709,12 +701,19 @@ void ModListView::setup(OrganizerCore& core, CategoryFactory& factory, MainWindo connect(core.modList(), &ModList::modelReset, [=] { clearOverwriteMarkers(); }); m_byPriorityProxy = new ModListByPriorityProxy(core.currentProfile(), core, this); - connect(m_byPriorityProxy, &ModListByPriorityProxy::expandItem, [=](auto&& index) { expandItem(index); }); m_byCategoryProxy = new QtGroupingProxy(QModelIndex(), ModList::COL_CATEGORY, ModList::GroupingRole, 0, ModList::AggrRole); - connect(m_byCategoryProxy, &QtGroupingProxy::expandItem, [=](auto&& index) { expandItem(index); }); m_byNexusIdProxy = new QtGroupingProxy(QModelIndex(), ModList::COL_MODID, ModList::GroupingRole, QtGroupingProxy::FLAG_NOGROUPNAME | QtGroupingProxy::FLAG_NOSINGLE, ModList::AggrRole); - connect(m_byNexusIdProxy, &QtGroupingProxy::expandItem, [=](auto&& index) { expandItem(index); }); + + QObject::connect(this, &QTreeView::expanded, [=](const QModelIndex& index) { + auto it = m_collapsed[m_sortProxy->sourceModel()].find(index.data(Qt::DisplayRole).toString()); + if (it != m_collapsed[m_sortProxy->sourceModel()].end()) { + m_collapsed[m_sortProxy->sourceModel()].erase(it); + } + }); + QObject::connect(this, &QTreeView::collapsed, [=](const QModelIndex& index) { + m_collapsed[m_sortProxy->sourceModel()].insert(index.data(Qt::DisplayRole).toString()); + }); m_sortProxy = new ModListSortProxy(core.currentProfile(), &core); setModel(m_sortProxy); @@ -810,7 +809,7 @@ void ModListView::setup(OrganizerCore& core, CategoryFactory& factory, MainWindo }); connect(m_sortProxy, &ModListSortProxy::filterInvalidated, [=]() { if (hasCollapsibleSeparators()) { - m_byPriorityProxy->refreshExpandedItems(); + refreshExpandedItems(); } }); } diff --git a/src/modlistview.h b/src/modlistview.h index faa33b6a..ed4ad2d0 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -1,6 +1,8 @@ #ifndef MODLISTVIEW_H #define MODLISTVIEW_H +#include +#include #include #include @@ -203,10 +205,9 @@ private: std::pair selected() const; void setSelected(const QModelIndex& current, const QModelIndexList& selected); - // call expand() after fixing the index if it comes from the source - // of the proxy + // refresh stored expanded items for the current intermediate proxy // - void expandItem(const QModelIndex& index); + void refreshExpandedItems(); // refresh the group-by proxy, if the index is -1 will refresh the // current one (e.g. when changing the sort column) @@ -249,6 +250,10 @@ private: QtGroupingProxy* m_byCategoryProxy; QtGroupingProxy* m_byNexusIdProxy; + // maintain collapsed items for each proxy to avoid + // losing them on model reset + std::map> m_collapsed; + struct MarkerInfos { // conflicts std::set overwrite; diff --git a/src/qtgroupingproxy.cpp b/src/qtgroupingproxy.cpp index 3daa66ba..a8c7ce1d 100644 --- a/src/qtgroupingproxy.cpp +++ b/src/qtgroupingproxy.cpp @@ -213,19 +213,6 @@ QtGroupingProxy::buildTree() } endResetModel(); - - // restore expand-state - refreshExpandedItems(); -} - -void QtGroupingProxy::refreshExpandedItems() const -{ - for (int row = 0; row < rowCount(); row++) { - QModelIndex idx = index(row, 0, QModelIndex()); - if (m_expandedItems.contains(idx.data(Qt::UserRole).toString())) { - emit expandItem(idx); - } - } } QList @@ -1049,14 +1036,3 @@ QtGroupingProxy::dumpGroups() const log::debug("{}", s); } - - -void QtGroupingProxy::expanded(const QModelIndex &index) -{ - m_expandedItems.insert(index.data(Qt::UserRole).toString()); -} - -void QtGroupingProxy::collapsed(const QModelIndex &index) -{ - m_expandedItems.remove(index.data(Qt::UserRole).toString()); -} diff --git a/src/qtgroupingproxy.h b/src/qtgroupingproxy.h index 131f33dc..c4459297 100644 --- a/src/qtgroupingproxy.h +++ b/src/qtgroupingproxy.h @@ -80,22 +80,6 @@ public: virtual QModelIndex addEmptyGroup( const RowData &data ); virtual bool removeGroup( const QModelIndex &idx ); - void refreshExpandedItems() const ; - -signals: - void expandItem(const QModelIndex &index) const; - -public slots: - /** - * @brief update expanded state - * @param index index of the expanded/collapsed item (from the base model!) - */ - void expanded(const QModelIndex &index); - /** - * @brief update expanded state - * @param index index of the expanded/collapsed item (from the base model!) - */ - void collapsed(const QModelIndex &index); protected slots: virtual void buildTree(); @@ -159,7 +143,6 @@ protected: void dumpGroups() const; private: - QSet m_expandedItems; unsigned int m_flags; int m_groupedRole; -- cgit v1.3.1