From 97eec512770a1960072c222418352b0f16ab80d9 Mon Sep 17 00:00:00 2001 From: cristian64 Date: Mon, 27 May 2024 21:38:33 +0100 Subject: [PATCH 1/3] Add expansion state to watch nodes. Only applicable to group nodes. --- Source/MemoryWatch/MemWatchTreeNode.cpp | 8 ++++++++ Source/MemoryWatch/MemWatchTreeNode.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/Source/MemoryWatch/MemWatchTreeNode.cpp b/Source/MemoryWatch/MemWatchTreeNode.cpp index 89a2a71..8b3e9b0 100644 --- a/Source/MemoryWatch/MemWatchTreeNode.cpp +++ b/Source/MemoryWatch/MemWatchTreeNode.cpp @@ -152,6 +152,10 @@ void MemWatchTreeNode::readFromJson(const QJsonObject& json, MemWatchTreeNode* p { m_isGroup = true; m_groupName = json["groupName"].toString(); + if (json.contains("expanded")) + { + m_expanded = json["expanded"].toBool(); + } QJsonArray groupEntries = json["groupEntries"].toArray(); for (auto i : groupEntries) { @@ -200,6 +204,10 @@ void MemWatchTreeNode::writeToJson(QJsonObject& json) const if (isGroup()) { json["groupName"] = m_groupName; + if (m_expanded) + { + json["expanded"] = m_expanded; + } QJsonArray entries; for (MemWatchTreeNode* const child : m_children) { diff --git a/Source/MemoryWatch/MemWatchTreeNode.h b/Source/MemoryWatch/MemWatchTreeNode.h index 1dc6a1f..fd3aaa4 100644 --- a/Source/MemoryWatch/MemWatchTreeNode.h +++ b/Source/MemoryWatch/MemWatchTreeNode.h @@ -19,6 +19,8 @@ class MemWatchTreeNode MemWatchTreeNode& operator=(MemWatchTreeNode&&) = delete; bool isGroup() const; + bool isExpanded() const { return m_expanded; } + void setExpanded(const bool expanded) { m_expanded = expanded; }; QString getGroupName() const; void setGroupName(const QString& groupName); MemWatchEntry* getEntry() const; @@ -46,6 +48,7 @@ class MemWatchTreeNode private: bool m_isGroup; + bool m_expanded{}; bool m_isValueEditing = false; QString m_groupName; MemWatchEntry* m_entry; From eec4356dc7812b3de6f71c356fa4dcb4afb06823 Mon Sep 17 00:00:00 2001 From: cristian64 Date: Mon, 27 May 2024 22:14:23 +0100 Subject: [PATCH 2/3] Favor constant references in return types in `MemWatchTreeNode`. A number of rich items were being passed by value unnecessarily. --- Source/MemoryWatch/MemWatchTreeNode.cpp | 4 ++-- Source/MemoryWatch/MemWatchTreeNode.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/MemoryWatch/MemWatchTreeNode.cpp b/Source/MemoryWatch/MemWatchTreeNode.cpp index 8b3e9b0..0f6623b 100644 --- a/Source/MemoryWatch/MemWatchTreeNode.cpp +++ b/Source/MemoryWatch/MemWatchTreeNode.cpp @@ -46,7 +46,7 @@ void MemWatchTreeNode::setValueEditing(const bool valueEditing) m_isValueEditing = valueEditing; } -QString MemWatchTreeNode::getGroupName() const +const QString& MemWatchTreeNode::getGroupName() const { return m_groupName; } @@ -67,7 +67,7 @@ void MemWatchTreeNode::setEntry(MemWatchEntry* entry) m_entry = entry; } -QVector MemWatchTreeNode::getChildren() const +const QVector& MemWatchTreeNode::getChildren() const { return m_children; } diff --git a/Source/MemoryWatch/MemWatchTreeNode.h b/Source/MemoryWatch/MemWatchTreeNode.h index fd3aaa4..47173c9 100644 --- a/Source/MemoryWatch/MemWatchTreeNode.h +++ b/Source/MemoryWatch/MemWatchTreeNode.h @@ -21,11 +21,11 @@ class MemWatchTreeNode bool isGroup() const; bool isExpanded() const { return m_expanded; } void setExpanded(const bool expanded) { m_expanded = expanded; }; - QString getGroupName() const; + const QString& getGroupName() const; void setGroupName(const QString& groupName); MemWatchEntry* getEntry() const; void setEntry(MemWatchEntry* entry); - QVector getChildren() const; + const QVector& getChildren() const; void setChildren(QVector children); MemWatchTreeNode* getParent() const; void setParent(MemWatchTreeNode* parent); From 5e87af3fc7217cbd9ce30abb346648f97db01c66 Mon Sep 17 00:00:00 2001 From: cristian64 Date: Mon, 27 May 2024 22:51:34 +0100 Subject: [PATCH 3/3] Restore expansion state when save file is loaded. Also when pasted rows are inserted. --- Source/GUI/MemWatcher/MemWatchWidget.cpp | 60 +++++++++++++++++++++++- Source/GUI/MemWatcher/MemWatchWidget.h | 3 ++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/Source/GUI/MemWatcher/MemWatchWidget.cpp b/Source/GUI/MemWatcher/MemWatchWidget.cpp index 0c5bb74..47397fb 100644 --- a/Source/GUI/MemWatcher/MemWatchWidget.cpp +++ b/Source/GUI/MemWatcher/MemWatchWidget.cpp @@ -65,6 +65,8 @@ void MemWatchWidget::initialiseWidgets() &MemWatchWidget::onMemWatchContextMenuRequested); connect(m_watchView, &QAbstractItemView::doubleClicked, this, &MemWatchWidget::onWatchDoubleClicked); + connect(m_watchView, &QTreeView::collapsed, this, &MemWatchWidget::onCollapsed); + connect(m_watchView, &QTreeView::expanded, this, &MemWatchWidget::onExpanded); m_watchView->setItemDelegate(m_watchDelegate); m_watchView->setModel(m_watchModel); @@ -651,7 +653,34 @@ void MemWatchWidget::onRowsInserted(const QModelIndex& parent, const int first, selectionModel->select(selection, QItemSelectionModel::ClearAndSelect); selectionModel->setCurrentIndex(lastIndex, QItemSelectionModel::Current); - QTimer::singleShot(0, [this, lastIndex] { m_watchView->scrollTo(lastIndex); }); + QTimer::singleShot(0, [this, parent, first, last, lastIndex] { + for (int i{first}; i <= last; ++i) + { + const MemWatchTreeNode* const node{ + MemWatchModel::getTreeNodeFromIndex(m_watchModel->index(i, 0, parent))}; + updateExpansionState(node); + } + + m_watchView->scrollTo(lastIndex); + }); +} + +void MemWatchWidget::onCollapsed(const QModelIndex& index) +{ + MemWatchTreeNode* const node{MemWatchModel::getTreeNodeFromIndex(index)}; + if (!node) + return; + node->setExpanded(false); + m_hasUnsavedChanges = true; +} + +void MemWatchWidget::onExpanded(const QModelIndex& index) +{ + MemWatchTreeNode* const node{MemWatchModel::getTreeNodeFromIndex(index)}; + if (!node) + return; + node->setExpanded(true); + m_hasUnsavedChanges = true; } QTimer* MemWatchWidget::getUpdateTimer() const @@ -704,6 +733,7 @@ void MemWatchWidget::openWatchFile() watchFile.close(); QJsonDocument loadDoc(QJsonDocument::fromJson(bytes)); m_watchModel->loadRootFromJsonRecursive(loadDoc.object()); + updateExpansionState(); m_watchListFile = fileName; m_hasUnsavedChanges = false; } @@ -897,6 +927,7 @@ void MemWatchWidget::restoreWatchModel(const QString& json) { const QJsonDocument loadDoc(QJsonDocument::fromJson(json.toUtf8())); m_watchModel->loadRootFromJsonRecursive(loadDoc.object()); + updateExpansionState(); } QString MemWatchWidget::saveWatchModel() @@ -906,3 +937,30 @@ QString MemWatchWidget::saveWatchModel() QJsonDocument saveDoc(root); return saveDoc.toJson(); } + +void MemWatchWidget::updateExpansionState(const MemWatchTreeNode* const node) +{ + QSignalBlocker signalBlocker(*m_watchView); + + std::vector nodes; + nodes.push_back(node ? node : m_watchModel->getRootNode()); + + while (!nodes.empty()) + { + const MemWatchTreeNode* const node{nodes.back()}; + nodes.pop_back(); + + if (!node) + continue; + + if (node->isExpanded()) + { + m_watchView->setExpanded(m_watchModel->getIndexFromTreeNode(node), true); + } + + for (const MemWatchTreeNode* const child : node->getChildren()) + { + nodes.push_back(child); + } + } +} diff --git a/Source/GUI/MemWatcher/MemWatchWidget.h b/Source/GUI/MemWatcher/MemWatchWidget.h index cb8098d..194500d 100644 --- a/Source/GUI/MemWatcher/MemWatchWidget.h +++ b/Source/GUI/MemWatcher/MemWatchWidget.h @@ -31,6 +31,8 @@ class MemWatchWidget : public QWidget void onDeleteSelection(); void onDropSucceeded(); void onRowsInserted(const QModelIndex& parent, int first, int last); + void onCollapsed(const QModelIndex& index); + void onExpanded(const QModelIndex& index); void openWatchFile(); void setSelectedWatchesBase(MemWatchEntry* entry, Common::MemBase base); void groupCurrentSelection(); @@ -55,6 +57,7 @@ class MemWatchWidget : public QWidget private: void initialiseWidgets(); void makeLayouts(); + void updateExpansionState(const MemWatchTreeNode* node = nullptr); QTreeView* m_watchView{}; MemWatchModel* m_watchModel{};