diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index c5f185ab356..1f7e655f17c 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1886,7 +1886,7 @@ void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node if (node) filePath = pathFor(node); else - node = SessionManager::nodeForFile(filePath, project); + node = ProjectTreeWidget::nodeForFile(filePath, project); bool projectChanged = false; if (d->m_currentProject != project) { diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp index ba32273f3a4..ee10347456f 100644 --- a/src/plugins/projectexplorer/projecttreewidget.cpp +++ b/src/plugins/projectexplorer/projecttreewidget.cpp @@ -43,6 +43,7 @@ #include #include +#include #include #include @@ -57,6 +58,8 @@ using namespace Core; using namespace ProjectExplorer; using namespace ProjectExplorer::Internal; +QList ProjectTreeWidget::m_projectTreeWidgets; + namespace { class ProjectTreeItemDelegate : public QStyledItemDelegate @@ -178,6 +181,59 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) connect(m_toggleSync, SIGNAL(clicked(bool)), this, SLOT(toggleAutoSynchronization())); setAutoSynchronization(true); + + m_projectTreeWidgets << this; +} + +ProjectTreeWidget::~ProjectTreeWidget() +{ + m_projectTreeWidgets.removeOne(this); +} + +// returns how many nodes need to be expanded to make node visible +int ProjectTreeWidget::expandedCount(Node *node) +{ + if (m_projectTreeWidgets.isEmpty()) + return 0; + FlatModel *model = m_projectTreeWidgets.first()->m_model; + QModelIndex index = model->indexForNode(node); + if (!index.isValid()) + return 0; + + int count = 0; + foreach (ProjectTreeWidget *tree, m_projectTreeWidgets) { + QModelIndex idx = index; + while (idx.isValid() && idx != tree->m_view->rootIndex()) { + if (!tree->m_view->isExpanded(idx)) + ++count; + idx = model->parent(idx); + } + } + return count; +} + +Node *ProjectTreeWidget::nodeForFile(const QString &fileName, Project *project) +{ + Node *bestNode = 0; + int bestNodeExpandCount = INT_MAX; + + foreach (Node *node, SessionManager::nodesForFile(fileName, project)) { + if (!bestNode) { + bestNode = node; + bestNodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode()); + } else if (node->nodeType() < bestNode->nodeType()) { + bestNode = node; + bestNodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode()); + } else if (node->nodeType() == bestNode->nodeType()) { + int nodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode()); + if (nodeExpandCount < bestNodeExpandCount) { + bestNode = node; + bestNodeExpandCount = ProjectTreeWidget::expandedCount(node->parentFolderNode()); + } + } + } + + return bestNode; } void ProjectTreeWidget::disableAutoExpand() diff --git a/src/plugins/projectexplorer/projecttreewidget.h b/src/plugins/projectexplorer/projecttreewidget.h index c78131e2de8..70c9d12cd26 100644 --- a/src/plugins/projectexplorer/projecttreewidget.h +++ b/src/plugins/projectexplorer/projecttreewidget.h @@ -54,6 +54,7 @@ class ProjectTreeWidget : public QWidget Q_OBJECT public: explicit ProjectTreeWidget(QWidget *parent = 0); + ~ProjectTreeWidget(); bool autoSynchronization() const; void setAutoSynchronization(bool sync, bool syncNow = true); @@ -61,6 +62,8 @@ public: bool generatedFilesFilter(); QToolButton *toggleSync(); + static Node *nodeForFile(const QString &fileName, Project *project); + public slots: void toggleAutoSynchronization(); void editCurrentItem(); @@ -88,6 +91,7 @@ private slots: private: void recursiveLoadExpandData(const QModelIndex &index, const QSet &data); void recursiveSaveExpandData(const QModelIndex &index, QStringList *data); + static int expandedCount(Node *node); ProjectExplorerPlugin *m_explorer; QTreeView *m_view; FlatModel *m_model; @@ -99,6 +103,8 @@ private: QString m_modelId; bool m_autoSync; bool m_autoExpand; + + static QList m_projectTreeWidgets; friend class ProjectTreeWidgetFactory; }; diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index b882f1779cb..9ca7f20d84a 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -518,23 +519,30 @@ Project *SessionManager::projectForNode(Node *node) return 0; } -Node *SessionManager::nodeForFile(const QString &fileName, Project *project) +QList SessionManager::nodesForFile(const QString &fileName, Project *project) { - Node *node = 0; if (!project) project = projectForFile(fileName); if (project) { FindNodesForFileVisitor findNodes(fileName); project->rootProjectNode()->accept(&findNodes); - - foreach (Node *n, findNodes.nodes()) { - // prefer file nodes - if (!node || (node->nodeType() != FileNodeType && n->nodeType() == FileNodeType)) - node = n; - } + return findNodes.nodes(); } + return QList(); +} + +// node for file returns a randomly selected node if there are multiple +// prefer to use nodesForFile and figure out which node you want +Node *SessionManager::nodeForFile(const QString &fileName, Project *project) +{ + Node *node = 0; + foreach (Node *n, nodesForFile(fileName, project)) { + // prefer file nodes + if (!node || (node->nodeType() != FileNodeType && n->nodeType() == FileNodeType)) + node = n; + } return node; } diff --git a/src/plugins/projectexplorer/session.h b/src/plugins/projectexplorer/session.h index 08a770d9cfe..cca7e65df11 100644 --- a/src/plugins/projectexplorer/session.h +++ b/src/plugins/projectexplorer/session.h @@ -116,6 +116,7 @@ public: static SessionNode *sessionNode(); static Project *projectForNode(ProjectExplorer::Node *node); + static QList nodesForFile(const QString &fileName, Project *project = 0); static Node *nodeForFile(const QString &fileName, Project *project = 0); static Project *projectForFile(const QString &fileName);