forked from qt-creator/qt-creator
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 <eike.ziller@qt.io>
This commit is contained in:
@@ -527,29 +527,33 @@ void Project::setRootProjectNode(ProjectNode *root)
|
|||||||
root = nullptr;
|
root = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectTree::applyTreeManager(root);
|
if (root) {
|
||||||
|
ProjectTree::applyTreeManager(root);
|
||||||
|
root->setParentFolderNode(d->m_containerNode.get());
|
||||||
|
}
|
||||||
|
|
||||||
ProjectNode *oldNode = d->m_rootProjectNode;
|
ProjectNode *oldNode = d->m_rootProjectNode;
|
||||||
|
|
||||||
d->m_rootProjectNode = root;
|
d->m_rootProjectNode = root;
|
||||||
if (root) {
|
if (oldNode || root)
|
||||||
QVector<const Node *> nodeList;
|
handleSubTreeChanged(d->m_containerNode.get());
|
||||||
root->forEachGenericNode([&nodeList](const Node *n) {
|
|
||||||
|
delete oldNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Project::handleSubTreeChanged(FolderNode *node)
|
||||||
|
{
|
||||||
|
QVector<const Node *> nodeList;
|
||||||
|
if (d->m_rootProjectNode) {
|
||||||
|
d->m_rootProjectNode->forEachGenericNode([&nodeList](const Node *n) {
|
||||||
nodeList.append(n);
|
nodeList.append(n);
|
||||||
});
|
});
|
||||||
Utils::sort(nodeList, &nodeLessThan);
|
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)
|
Target *Project::restoreTarget(const QVariantMap &data)
|
||||||
|
@@ -48,6 +48,7 @@ namespace ProjectExplorer {
|
|||||||
class BuildInfo;
|
class BuildInfo;
|
||||||
class ContainerNode;
|
class ContainerNode;
|
||||||
class EditorConfiguration;
|
class EditorConfiguration;
|
||||||
|
class FolderNode;
|
||||||
class NamedWidget;
|
class NamedWidget;
|
||||||
class Node;
|
class Node;
|
||||||
class ProjectConfiguration;
|
class ProjectConfiguration;
|
||||||
@@ -241,10 +242,12 @@ protected:
|
|||||||
virtual void projectLoaded(); // Called when the project is fully loaded.
|
virtual void projectLoaded(); // Called when the project is fully loaded.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void handleSubTreeChanged(FolderNode *node);
|
||||||
void setActiveTarget(Target *target);
|
void setActiveTarget(Target *target);
|
||||||
ProjectPrivate *d;
|
ProjectPrivate *d;
|
||||||
|
|
||||||
friend class Session;
|
friend class Session;
|
||||||
|
friend class ContainerNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -628,7 +628,7 @@ bool FolderNode::replaceSubtree(Node *oldNode, Node *newNode)
|
|||||||
}
|
}
|
||||||
QTimer::singleShot(0, [oldNode]() { delete oldNode; });
|
QTimer::singleShot(0, [oldNode]() { delete oldNode; });
|
||||||
}
|
}
|
||||||
ProjectTree::emitSubtreeChanged(this);
|
handleSubTreeChanged(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -879,6 +879,12 @@ bool FolderNode::isEmpty() const
|
|||||||
return m_nodes.isEmpty();
|
return m_nodes.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FolderNode::handleSubTreeChanged(FolderNode *node)
|
||||||
|
{
|
||||||
|
if (FolderNode *parent = parentFolderNode())
|
||||||
|
parent->handleSubTreeChanged(node);
|
||||||
|
}
|
||||||
|
|
||||||
ContainerNode::ContainerNode(Project *project)
|
ContainerNode::ContainerNode(Project *project)
|
||||||
: FolderNode(project->projectDirectory(), NodeType::Project), m_project(project)
|
: FolderNode(project->projectDirectory(), NodeType::Project), m_project(project)
|
||||||
{}
|
{}
|
||||||
@@ -915,4 +921,9 @@ void ContainerNode::removeAllChildren()
|
|||||||
m_nodes.clear();
|
m_nodes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContainerNode::handleSubTreeChanged(FolderNode *node)
|
||||||
|
{
|
||||||
|
m_project->handleSubTreeChanged(node);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -294,6 +294,8 @@ public:
|
|||||||
const FolderNode *asFolderNode() const override { return this; }
|
const FolderNode *asFolderNode() const override { return this; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void handleSubTreeChanged(FolderNode *node);
|
||||||
|
|
||||||
QList<Node *> m_nodes;
|
QList<Node *> m_nodes;
|
||||||
QList<LocationInfo> m_locations;
|
QList<LocationInfo> m_locations;
|
||||||
|
|
||||||
@@ -361,6 +363,8 @@ public:
|
|||||||
void removeAllChildren();
|
void removeAllChildren();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void handleSubTreeChanged(FolderNode *node) final;
|
||||||
|
|
||||||
Project *m_project;
|
Project *m_project;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user