diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 578cc033ec839da1697f95379afcf5230d40eede..c1caa1bd272d76c5beff820654b43661cd88da98 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -477,10 +477,13 @@ void Project::setRootProjectNode(ProjectNode *root) ProjectNode *oldNode = d->m_rootProjectNode; d->m_rootProjectNode = root; - if (root) + if (root) { root->setParentFolderNode(d->m_containerNode); - ProjectTree::emitSubtreeChanged(root); - emit fileListChanged(); + // 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(); + } delete oldNode; } diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index a733c9ae17849eac1dccdf079e984bc8146c58e7..9a5bb114073305b822368098fa6b0e99b426d468 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -74,15 +74,14 @@ FlatModel::FlatModel(QObject *parent) : TreeModel<WrapperNode, WrapperNode>(new WrapperNode(nullptr), parent) { ProjectTree *tree = ProjectTree::instance(); - connect(tree, &ProjectTree::subtreeChanged, this, &FlatModel::update); + connect(tree, &ProjectTree::subtreeChanged, this, &FlatModel::updateSubtree); SessionManager *sm = SessionManager::instance(); - connect(sm, &SessionManager::projectRemoved, this, &FlatModel::update); - connect(sm, &SessionManager::sessionLoaded, this, &FlatModel::loadExpandData); + connect(sm, &SessionManager::projectRemoved, this, &FlatModel::handleProjectRemoved); + connect(sm, &SessionManager::aboutToLoadSession, this, &FlatModel::loadExpandData); connect(sm, &SessionManager::aboutToSaveSession, this, &FlatModel::saveExpandData); connect(sm, &SessionManager::projectAdded, this, &FlatModel::handleProjectAdded); connect(sm, &SessionManager::startupProjectChanged, this, [this] { layoutChanged(); }); - update(); } QVariant FlatModel::data(const QModelIndex &index, int role) const @@ -170,42 +169,27 @@ bool FlatModel::setData(const QModelIndex &index, const QVariant &value, int rol return true; } -void FlatModel::update() +void FlatModel::addOrRebuildProjectModel(Project *project) { - rebuildModel(); -} - -void FlatModel::rebuildModel() -{ - QList<Project *> projects = SessionManager::projects(); - - Utils::sort(projects, [](Project *p1, Project *p2) { - const int displayNameResult = caseFriendlyCompare(p1->displayName(), p2->displayName()); - if (displayNameResult != 0) - return displayNameResult < 0; - return p1 < p2; // sort by pointer value - }); + WrapperNode *container = nodeForProject(project); + if (container) { + container->removeChildren(); + } else { + container = new WrapperNode(project->containerNode()); + rootItem()->appendChild(container); + } QSet<Node *> seen; - rootItem()->removeChildren(); - for (Project *project : projects) { - WrapperNode *container = new WrapperNode(project->containerNode()); - - ProjectNode *projectNode = project->rootProjectNode(); - if (projectNode) { - addFolderNode(container, projectNode, &seen); - } else { - FileNode *projectFileNode = new FileNode(project->projectFilePath(), FileType::Project, false); - seen.insert(projectFileNode); - container->appendChild(new WrapperNode(projectFileNode)); - } - - container->sortChildren(&sortWrapperNodes); - rootItem()->appendChild(container); + if (ProjectNode *projectNode = project->rootProjectNode()) { + addFolderNode(container, projectNode, &seen); + } else { + FileNode *projectFileNode = new FileNode(project->projectFilePath(), FileType::Project, false); + seen.insert(projectFileNode); + container->appendChild(new WrapperNode(projectFileNode)); } - forAllItems([this](WrapperNode *node) { + container->forAllChildren([this](WrapperNode *node) { if (node->m_node) { const QString path = node->m_node->filePath().toString(); const QString displayName = node->m_node->displayName(); @@ -216,6 +200,37 @@ void FlatModel::rebuildModel() emit requestExpansion(node->index()); } }); + + const QString path = container->m_node->filePath().toString(); + const QString displayName = container->m_node->displayName(); + ExpandData ed(path, displayName); + if (m_toExpand.contains(ed)) + emit requestExpansion(container->index()); +} + +void FlatModel::updateSubtree(FolderNode *node) +{ + // FIXME: This is still excessive, should be limited to the affected subtree. + while (FolderNode *parent = node->parentFolderNode()) + node = parent; + if (ContainerNode *container = node->asContainerNode()) + addOrRebuildProjectModel(container->project()); +} + +void FlatModel::rebuildModel() +{ + QList<Project *> projects = SessionManager::projects(); + QTC_CHECK(projects.size() == rootItem()->childCount()); + + Utils::sort(projects, [](Project *p1, Project *p2) { + const int displayNameResult = caseFriendlyCompare(p1->displayName(), p2->displayName()); + if (displayNameResult != 0) + return displayNameResult < 0; + return p1 < p2; // sort by pointer value + }); + + for (Project *project : projects) + addOrRebuildProjectModel(project); } void FlatModel::onCollapsed(const QModelIndex &idx) @@ -238,9 +253,22 @@ ExpandData FlatModel::expandDataForNode(const Node *node) const void FlatModel::handleProjectAdded(Project *project) { - Node *node = project->containerNode(); - m_toExpand.insert(expandDataForNode(node)); - update(); + addOrRebuildProjectModel(project); +} + +void FlatModel::handleProjectRemoved(Project *project) +{ + destroyItem(nodeForProject(project)); +} + +WrapperNode *FlatModel::nodeForProject(Project *project) +{ + QTC_ASSERT(project, return nullptr); + ContainerNode *containerNode = project->containerNode(); + QTC_ASSERT(containerNode, return nullptr); + return rootItem()->findFirstLevelChild([containerNode](WrapperNode *node) { + return node->m_node == containerNode; + }); } void FlatModel::loadExpandData() diff --git a/src/plugins/projectexplorer/projectmodels.h b/src/plugins/projectexplorer/projectmodels.h index b59e08e04fa557eeb8b754aa529c97a2e4214fd8..18129a7ddce7894c15213a5cb2a995c4bfd0a7d8 100644 --- a/src/plugins/projectexplorer/projectmodels.h +++ b/src/plugins/projectexplorer/projectmodels.h @@ -90,7 +90,7 @@ private: static const QLoggingCategory &logger(); - void update(); + void updateSubtree(FolderNode *node); void rebuildModel(); void addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen); @@ -98,6 +98,9 @@ private: void loadExpandData(); void saveExpandData(); void handleProjectAdded(Project *project); + void handleProjectRemoved(Project *project); + WrapperNode *nodeForProject(Project *project); + void addOrRebuildProjectModel(Project *project); QTimer m_timer; QSet<ExpandData> m_toExpand; diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index efb94d7079a08e20aaec5997a74082f5ed35bfb6..ac82e9b02c3b2e2a436a92c86281647bcd35821c 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -318,6 +318,7 @@ public: const ContainerNode *asContainerNode() const final { return this; } ProjectNode *rootProjectNode() const; + Project *project() const { return m_project; } private: Project *m_project;