forked from qt-creator/qt-creator
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: Eike Ziller <eike.ziller@theqtcompany.com>
This commit is contained in:
committed by
Eike Ziller
parent
beb0797008
commit
5d2d37b794
@@ -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 @@
|
|||||||
#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)
|
|||||||
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*>
|
|||||||
|
|
||||||
void ProjectTree::foldersRemoved()
|
void ProjectTree::foldersRemoved()
|
||||||
{
|
{
|
||||||
|
QTimer::singleShot(0, [this]() {
|
||||||
if (m_resetCurrentNodeFolder) {
|
if (m_resetCurrentNodeFolder) {
|
||||||
updateFromFocus(true);
|
updateFromFocus(true);
|
||||||
m_resetCurrentNodeFolder = false;
|
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
|
|||||||
|
|
||||||
void ProjectTree::filesRemoved()
|
void ProjectTree::filesRemoved()
|
||||||
{
|
{
|
||||||
|
QTimer::singleShot(0, [this]() {
|
||||||
if (m_resetCurrentNodeFile) {
|
if (m_resetCurrentNodeFile) {
|
||||||
updateFromFocus(true);
|
updateFromFocus(true);
|
||||||
m_resetCurrentNodeFile = false;
|
m_resetCurrentNodeFile = false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectTree::aboutToRemoveProject(Project *project)
|
void ProjectTree::aboutToRemoveProject(Project *project)
|
||||||
@@ -295,16 +322,20 @@ void ProjectTree::aboutToRemoveProject(Project *project)
|
|||||||
|
|
||||||
void ProjectTree::projectRemoved()
|
void ProjectTree::projectRemoved()
|
||||||
{
|
{
|
||||||
|
QTimer::singleShot(0, [this]() {
|
||||||
updateFromFocus(true);
|
updateFromFocus(true);
|
||||||
m_resetCurrentNodeProject = false;
|
m_resetCurrentNodeProject = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectTree::nodesAdded()
|
void ProjectTree::nodesAdded()
|
||||||
{
|
{
|
||||||
|
QTimer::singleShot(0, [this]() {
|
||||||
if (Utils::anyOf(m_projectTreeWidgets, &ProjectTreeWidget::hasFocus))
|
if (Utils::anyOf(m_projectTreeWidgets, &ProjectTreeWidget::hasFocus))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
updateFromDocumentManager();
|
updateFromDocumentManager();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectTree::updateExternalFileWarning()
|
void ProjectTree::updateExternalFileWarning()
|
||||||
|
|||||||
@@ -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:
|
|||||||
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:
|
|||||||
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)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user