Commit 5d2d37b7 authored by Daniel Teske's avatar Daniel Teske Committed by Eike Ziller
Browse files

Fix crash in ProjectTree on restoring a session



On adding nodes to the node structure, both the FlatModel::nodesAdded
and ProjectTree::nodesAdded code is run. We need to ensure that
FlatModel::nodesAdded is run first though, as we need that information
in the ProjectTree.

Task-number: QTCREATORBUG-13667
Change-Id: I0b4b41ed6036cfdef668c16689d25611633ab0c9
Reviewed-by: default avatarEike Ziller <eike.ziller@theqtcompany.com>
parent beb07970
...@@ -1392,6 +1392,7 @@ ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown() ...@@ -1392,6 +1392,7 @@ ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown()
{ {
disconnect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*,Core::IMode*)), disconnect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*,Core::IMode*)),
this, SLOT(currentModeChanged(Core::IMode*,Core::IMode*))); this, SLOT(currentModeChanged(Core::IMode*,Core::IMode*)));
ProjectTree::aboutToShutDown();
dd->m_proWindow->aboutToShutdown(); // disconnect from session dd->m_proWindow->aboutToShutdown(); // disconnect from session
SessionManager::closeAllProjects(); SessionManager::closeAllProjects();
dd->m_projectsMode = 0; dd->m_projectsMode = 0;
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <coreplugin/vcsmanager.h> #include <coreplugin/vcsmanager.h>
#include <QApplication> #include <QApplication>
#include <QTimer>
namespace { namespace {
const char EXTERNAL_FILE_WARNING[] = "ExternalFile"; const char EXTERNAL_FILE_WARNING[] = "ExternalFile";
...@@ -73,28 +74,50 @@ ProjectTree::ProjectTree(QObject *parent) ...@@ -73,28 +74,50 @@ ProjectTree::ProjectTree(QObject *parent)
this, &ProjectTree::projectRemoved); this, &ProjectTree::projectRemoved);
NodesWatcher *watcher = new NodesWatcher(this); m_watcher = new NodesWatcher(this);
SessionManager::sessionNode()->registerWatcher(watcher); SessionManager::sessionNode()->registerWatcher(m_watcher);
connect(watcher, &NodesWatcher::foldersAboutToBeRemoved, connect(m_watcher, &NodesWatcher::foldersAboutToBeRemoved,
this, &ProjectTree::foldersAboutToBeRemoved); this, &ProjectTree::foldersAboutToBeRemoved);
connect(watcher, &NodesWatcher::foldersRemoved, connect(m_watcher, &NodesWatcher::foldersRemoved,
this, &ProjectTree::foldersRemoved); this, &ProjectTree::foldersRemoved);
connect(watcher, &NodesWatcher::filesAboutToBeRemoved, connect(m_watcher, &NodesWatcher::filesAboutToBeRemoved,
this, &ProjectTree::filesAboutToBeRemoved); this, &ProjectTree::filesAboutToBeRemoved);
connect(watcher, &NodesWatcher::filesRemoved, connect(m_watcher, &NodesWatcher::filesRemoved,
this, &ProjectTree::filesRemoved); this, &ProjectTree::filesRemoved);
connect(watcher, &NodesWatcher::foldersAdded, connect(m_watcher, &NodesWatcher::foldersAdded,
this, &ProjectTree::nodesAdded); this, &ProjectTree::nodesAdded);
connect(watcher, &NodesWatcher::filesAdded, connect(m_watcher, &NodesWatcher::filesAdded,
this, &ProjectTree::nodesAdded); this, &ProjectTree::nodesAdded);
connect(qApp, &QApplication::focusChanged, connect(qApp, &QApplication::focusChanged,
this, &ProjectTree::focusChanged); this, &ProjectTree::focusChanged);
} }
void ProjectTree::aboutToShutDown()
{
disconnect(s_instance->m_watcher, &NodesWatcher::foldersAboutToBeRemoved,
s_instance, &ProjectTree::foldersAboutToBeRemoved);
disconnect(s_instance->m_watcher, &NodesWatcher::foldersRemoved,
s_instance, &ProjectTree::foldersRemoved);
disconnect(s_instance->m_watcher, &NodesWatcher::filesAboutToBeRemoved,
s_instance, &ProjectTree::filesAboutToBeRemoved);
disconnect(s_instance->m_watcher, &NodesWatcher::filesRemoved,
s_instance, &ProjectTree::filesRemoved);
disconnect(s_instance->m_watcher, &NodesWatcher::foldersAdded,
s_instance, &ProjectTree::nodesAdded);
disconnect(s_instance->m_watcher, &NodesWatcher::filesAdded,
s_instance, &ProjectTree::nodesAdded);
disconnect(qApp, &QApplication::focusChanged,
s_instance, &ProjectTree::focusChanged);
s_instance->update(0, 0);
}
ProjectTree *ProjectTree::instance() ProjectTree *ProjectTree::instance()
{ {
return s_instance; return s_instance;
...@@ -266,10 +289,12 @@ void ProjectTree::foldersAboutToBeRemoved(FolderNode *, const QList<FolderNode*> ...@@ -266,10 +289,12 @@ void ProjectTree::foldersAboutToBeRemoved(FolderNode *, const QList<FolderNode*>
void ProjectTree::foldersRemoved() void ProjectTree::foldersRemoved()
{ {
if (m_resetCurrentNodeFolder) { QTimer::singleShot(0, [this]() {
updateFromFocus(true); if (m_resetCurrentNodeFolder) {
m_resetCurrentNodeFolder = false; updateFromFocus(true);
} m_resetCurrentNodeFolder = false;
}
});
} }
void ProjectTree::filesAboutToBeRemoved(FolderNode *, const QList<FileNode*> &list) void ProjectTree::filesAboutToBeRemoved(FolderNode *, const QList<FileNode*> &list)
...@@ -281,10 +306,12 @@ void ProjectTree::filesAboutToBeRemoved(FolderNode *, const QList<FileNode*> &li ...@@ -281,10 +306,12 @@ void ProjectTree::filesAboutToBeRemoved(FolderNode *, const QList<FileNode*> &li
void ProjectTree::filesRemoved() void ProjectTree::filesRemoved()
{ {
if (m_resetCurrentNodeFile) { QTimer::singleShot(0, [this]() {
updateFromFocus(true); if (m_resetCurrentNodeFile) {
m_resetCurrentNodeFile = false; updateFromFocus(true);
} m_resetCurrentNodeFile = false;
}
});
} }
void ProjectTree::aboutToRemoveProject(Project *project) void ProjectTree::aboutToRemoveProject(Project *project)
...@@ -295,16 +322,20 @@ void ProjectTree::aboutToRemoveProject(Project *project) ...@@ -295,16 +322,20 @@ void ProjectTree::aboutToRemoveProject(Project *project)
void ProjectTree::projectRemoved() void ProjectTree::projectRemoved()
{ {
updateFromFocus(true); QTimer::singleShot(0, [this]() {
m_resetCurrentNodeProject = false; updateFromFocus(true);
m_resetCurrentNodeProject = false;
});
} }
void ProjectTree::nodesAdded() void ProjectTree::nodesAdded()
{ {
if (Utils::anyOf(m_projectTreeWidgets, &ProjectTreeWidget::hasFocus)) QTimer::singleShot(0, [this]() {
return; if (Utils::anyOf(m_projectTreeWidgets, &ProjectTreeWidget::hasFocus))
return;
updateFromDocumentManager(); updateFromDocumentManager();
});
} }
void ProjectTree::updateExternalFileWarning() void ProjectTree::updateExternalFileWarning()
......
...@@ -39,6 +39,7 @@ namespace ProjectExplorer { ...@@ -39,6 +39,7 @@ namespace ProjectExplorer {
class FileNode; class FileNode;
class FolderNode; class FolderNode;
class Node; class Node;
class NodesWatcher;
class Project; class Project;
namespace Internal { class ProjectTreeWidget; } namespace Internal { class ProjectTreeWidget; }
...@@ -58,14 +59,15 @@ public: ...@@ -58,14 +59,15 @@ public:
static void registerWidget(Internal::ProjectTreeWidget *widget); static void registerWidget(Internal::ProjectTreeWidget *widget);
static void unregisterWidget(Internal::ProjectTreeWidget *widget); static void unregisterWidget(Internal::ProjectTreeWidget *widget);
static void nodeChanged(Internal::ProjectTreeWidget *widget); static void nodeChanged(Internal::ProjectTreeWidget *widget);
static void focusChanged();
static Project *projectForNode(Node *node); static Project *projectForNode(Node *node);
static void aboutToShutDown();
signals: signals:
void currentProjectChanged(ProjectExplorer::Project *project); void currentProjectChanged(ProjectExplorer::Project *project);
void currentNodeChanged(ProjectExplorer::Node *node, ProjectExplorer::Project *project); void currentNodeChanged(ProjectExplorer::Node *node, ProjectExplorer::Project *project);
private: private:
void focusChanged();
void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget); void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget);
void documentManagerCurrentFileChanged(); void documentManagerCurrentFileChanged();
void updateFromDocumentManager(bool invalidCurrentNode = false); void updateFromDocumentManager(bool invalidCurrentNode = false);
...@@ -95,6 +97,7 @@ private: ...@@ -95,6 +97,7 @@ private:
bool m_resetCurrentNodeFile; bool m_resetCurrentNodeFile;
bool m_resetCurrentNodeProject; bool m_resetCurrentNodeProject;
Core::Context m_lastProjectContext; Core::Context m_lastProjectContext;
NodesWatcher *m_watcher;
}; };
} }
......
...@@ -243,15 +243,15 @@ Node *ProjectTreeWidget::nodeForFile(const QString &fileName) ...@@ -243,15 +243,15 @@ Node *ProjectTreeWidget::nodeForFile(const QString &fileName)
foreach (Node *node, SessionManager::nodesForFile(fileName)) { foreach (Node *node, SessionManager::nodesForFile(fileName)) {
if (!bestNode) { if (!bestNode) {
bestNode = node; bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode()); bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (node->nodeType() < bestNode->nodeType()) { } else if (node->nodeType() < bestNode->nodeType()) {
bestNode = node; bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode()); bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (node->nodeType() == bestNode->nodeType()) { } else if (node->nodeType() == bestNode->nodeType()) {
int nodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode()); int nodeExpandCount = ProjectTreeWidget::expandedCount(node);
if (nodeExpandCount < bestNodeExpandCount) { if (nodeExpandCount < bestNodeExpandCount) {
bestNode = node; bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode()); bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} }
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment