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()
{
disconnect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*,Core::IMode*)),
this, SLOT(currentModeChanged(Core::IMode*,Core::IMode*)));
ProjectTree::aboutToShutDown();
dd->m_proWindow->aboutToShutdown(); // disconnect from session
SessionManager::closeAllProjects();
dd->m_projectsMode = 0;
......
......@@ -43,6 +43,7 @@
#include <coreplugin/vcsmanager.h>
#include <QApplication>
#include <QTimer>
namespace {
const char EXTERNAL_FILE_WARNING[] = "ExternalFile";
......@@ -73,28 +74,50 @@ ProjectTree::ProjectTree(QObject *parent)
this, &ProjectTree::projectRemoved);
NodesWatcher *watcher = new NodesWatcher(this);
SessionManager::sessionNode()->registerWatcher(watcher);
m_watcher = new NodesWatcher(this);
SessionManager::sessionNode()->registerWatcher(m_watcher);
connect(watcher, &NodesWatcher::foldersAboutToBeRemoved,
connect(m_watcher, &NodesWatcher::foldersAboutToBeRemoved,
this, &ProjectTree::foldersAboutToBeRemoved);
connect(watcher, &NodesWatcher::foldersRemoved,
connect(m_watcher, &NodesWatcher::foldersRemoved,
this, &ProjectTree::foldersRemoved);
connect(watcher, &NodesWatcher::filesAboutToBeRemoved,
connect(m_watcher, &NodesWatcher::filesAboutToBeRemoved,
this, &ProjectTree::filesAboutToBeRemoved);
connect(watcher, &NodesWatcher::filesRemoved,
connect(m_watcher, &NodesWatcher::filesRemoved,
this, &ProjectTree::filesRemoved);
connect(watcher, &NodesWatcher::foldersAdded,
connect(m_watcher, &NodesWatcher::foldersAdded,
this, &ProjectTree::nodesAdded);
connect(watcher, &NodesWatcher::filesAdded,
connect(m_watcher, &NodesWatcher::filesAdded,
this, &ProjectTree::nodesAdded);
connect(qApp, &QApplication::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()
{
return s_instance;
......@@ -266,10 +289,12 @@ void ProjectTree::foldersAboutToBeRemoved(FolderNode *, const QList<FolderNode*>
void ProjectTree::foldersRemoved()
{
QTimer::singleShot(0, [this]() {
if (m_resetCurrentNodeFolder) {
updateFromFocus(true);
m_resetCurrentNodeFolder = false;
}
});
}
void ProjectTree::filesAboutToBeRemoved(FolderNode *, const QList<FileNode*> &list)
......@@ -281,10 +306,12 @@ void ProjectTree::filesAboutToBeRemoved(FolderNode *, const QList<FileNode*> &li
void ProjectTree::filesRemoved()
{
QTimer::singleShot(0, [this]() {
if (m_resetCurrentNodeFile) {
updateFromFocus(true);
m_resetCurrentNodeFile = false;
}
});
}
void ProjectTree::aboutToRemoveProject(Project *project)
......@@ -295,16 +322,20 @@ void ProjectTree::aboutToRemoveProject(Project *project)
void ProjectTree::projectRemoved()
{
QTimer::singleShot(0, [this]() {
updateFromFocus(true);
m_resetCurrentNodeProject = false;
});
}
void ProjectTree::nodesAdded()
{
QTimer::singleShot(0, [this]() {
if (Utils::anyOf(m_projectTreeWidgets, &ProjectTreeWidget::hasFocus))
return;
updateFromDocumentManager();
});
}
void ProjectTree::updateExternalFileWarning()
......
......@@ -39,6 +39,7 @@ namespace ProjectExplorer {
class FileNode;
class FolderNode;
class Node;
class NodesWatcher;
class Project;
namespace Internal { class ProjectTreeWidget; }
......@@ -58,14 +59,15 @@ public:
static void registerWidget(Internal::ProjectTreeWidget *widget);
static void unregisterWidget(Internal::ProjectTreeWidget *widget);
static void nodeChanged(Internal::ProjectTreeWidget *widget);
static void focusChanged();
static Project *projectForNode(Node *node);
static void aboutToShutDown();
signals:
void currentProjectChanged(ProjectExplorer::Project *project);
void currentNodeChanged(ProjectExplorer::Node *node, ProjectExplorer::Project *project);
private:
void focusChanged();
void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget);
void documentManagerCurrentFileChanged();
void updateFromDocumentManager(bool invalidCurrentNode = false);
......@@ -95,6 +97,7 @@ private:
bool m_resetCurrentNodeFile;
bool m_resetCurrentNodeProject;
Core::Context m_lastProjectContext;
NodesWatcher *m_watcher;
};
}
......
......@@ -243,15 +243,15 @@ Node *ProjectTreeWidget::nodeForFile(const QString &fileName)
foreach (Node *node, SessionManager::nodesForFile(fileName)) {
if (!bestNode) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode());
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (node->nodeType() < bestNode->nodeType()) {
bestNode = node;
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode());
bestNodeExpandCount = ProjectTreeWidget::expandedCount(node);
} else if (node->nodeType() == bestNode->nodeType()) {
int nodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode());
int nodeExpandCount = ProjectTreeWidget::expandedCount(node);
if (nodeExpandCount < bestNodeExpandCount) {
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