From 034f0209b01c3c774995e790c099bf7e422953e6 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 19 Jan 2018 11:55:28 +0100 Subject: [PATCH] ProjectTree: Fix crash working with resources Fix the notification of subtree changes to keep the project in the loop, so that it can adjust its list of known files. Ignoring that will cause crashes, e.g. when the ResourceEditor updates its subtree of the project. Task-number: QTCREATORBUG-19613 Change-Id: Ib7bb9afe48eb248cdf675ba2093b266fd728d7b2 Reviewed-by: Eike Ziller --- src/plugins/projectexplorer/project.cpp | 34 +++++++++++--------- src/plugins/projectexplorer/project.h | 3 ++ src/plugins/projectexplorer/projectnodes.cpp | 13 +++++++- src/plugins/projectexplorer/projectnodes.h | 4 +++ 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index a291ef212bd..f2704e6119e 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -527,29 +527,33 @@ void Project::setRootProjectNode(ProjectNode *root) root = nullptr; } - ProjectTree::applyTreeManager(root); + if (root) { + ProjectTree::applyTreeManager(root); + root->setParentFolderNode(d->m_containerNode.get()); + } ProjectNode *oldNode = d->m_rootProjectNode; + d->m_rootProjectNode = root; - if (root) { - QVector nodeList; - root->forEachGenericNode([&nodeList](const Node *n) { + if (oldNode || root) + handleSubTreeChanged(d->m_containerNode.get()); + + delete oldNode; +} + +void Project::handleSubTreeChanged(FolderNode *node) +{ + QVector nodeList; + if (d->m_rootProjectNode) { + d->m_rootProjectNode->forEachGenericNode([&nodeList](const Node *n) { nodeList.append(n); }); Utils::sort(nodeList, &nodeLessThan); - d->m_sortedNodeList = nodeList; - root->setParentFolderNode(d->m_containerNode.get()); - // Only announce non-null root, null is only used when project is destroyed. - // In that case SessionManager::projectRemoved() triggers the update. - ProjectTree::emitSubtreeChanged(root); - emit fileListChanged(); - } else { - d->m_sortedNodeList.clear(); - if (oldNode != nullptr) - emit fileListChanged(); } + d->m_sortedNodeList = nodeList; - delete oldNode; + ProjectTree::emitSubtreeChanged(node); + emit fileListChanged(); } Target *Project::restoreTarget(const QVariantMap &data) diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 845b3c2b42b..28b50551895 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -48,6 +48,7 @@ namespace ProjectExplorer { class BuildInfo; class ContainerNode; class EditorConfiguration; +class FolderNode; class NamedWidget; class Node; class ProjectConfiguration; @@ -241,10 +242,12 @@ protected: virtual void projectLoaded(); // Called when the project is fully loaded. private: + void handleSubTreeChanged(FolderNode *node); void setActiveTarget(Target *target); ProjectPrivate *d; friend class Session; + friend class ContainerNode; }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 25df41102db..ea4b780cabe 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -628,7 +628,7 @@ bool FolderNode::replaceSubtree(Node *oldNode, Node *newNode) } QTimer::singleShot(0, [oldNode]() { delete oldNode; }); } - ProjectTree::emitSubtreeChanged(this); + handleSubTreeChanged(this); return true; } @@ -879,6 +879,12 @@ bool FolderNode::isEmpty() const return m_nodes.isEmpty(); } +void FolderNode::handleSubTreeChanged(FolderNode *node) +{ + if (FolderNode *parent = parentFolderNode()) + parent->handleSubTreeChanged(node); +} + ContainerNode::ContainerNode(Project *project) : FolderNode(project->projectDirectory(), NodeType::Project), m_project(project) {} @@ -915,4 +921,9 @@ void ContainerNode::removeAllChildren() m_nodes.clear(); } +void ContainerNode::handleSubTreeChanged(FolderNode *node) +{ + m_project->handleSubTreeChanged(node); +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index ddd828ee97a..34ad086a182 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -294,6 +294,8 @@ public: const FolderNode *asFolderNode() const override { return this; } protected: + virtual void handleSubTreeChanged(FolderNode *node); + QList m_nodes; QList m_locations; @@ -361,6 +363,8 @@ public: void removeAllChildren(); private: + void handleSubTreeChanged(FolderNode *node) final; + Project *m_project; };