summaryrefslogtreecommitdiff
path: root/src/plugins/projectexplorer/projectmodels.cpp
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2017-04-04 14:36:03 +0200
committerhjk <hjk@qt.io>2017-04-05 13:44:27 +0000
commit8d1f4834b6fe79f992b3a46f8973d32dbc0dddb2 (patch)
tree8516f8b6d06d0720752f5765e023071214ae46fd /src/plugins/projectexplorer/projectmodels.cpp
parent8cdeed86333c94042bcd3cfa618c6dd2c9686d3a (diff)
downloadqt-creator-8d1f4834b6fe79f992b3a46f8973d32dbc0dddb2.tar.gz
ProjectExplorer: Don't rebuild all projects' tree when one is closed
Removes some quadratic-in-number-of-projects behavior on session close/switch. Change-Id: If93bb9a67b0bebddda5319a7594a99ae66f50f5a Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/plugins/projectexplorer/projectmodels.cpp')
-rw-r--r--src/plugins/projectexplorer/projectmodels.cpp102
1 files changed, 65 insertions, 37 deletions
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index a733c9ae17..9a5bb11407 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()