From 69627e494ba539c1463b511fdc898ff95f550b51 Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@theqtcompany.com>
Date: Fri, 30 Sep 2016 20:33:34 +0200
Subject: [PATCH] Add helper code to generate trees of project nodes
Add helper code to FolderNode that enables the creation of a tree
of File- and FolderNodes from a FolderNode and a list of FileNodes.
Change-Id: Iba4b6a768fc3d0501851f141372e7e34913ba518
Reviewed-by: hjk <hjk@qt.io>
---
.../cmakeprojectmanager/cmakeproject.cpp | 102 +-----------------
.../cmakeprojectmanager/cmakeproject.h | 3 -
.../cmakeprojectmanager/cmakeprojectnodes.cpp | 4 +-
.../cmakeprojectmanager/cmakeprojectnodes.h | 2 +-
src/plugins/projectexplorer/projectnodes.cpp | 95 +++++++++++++++-
src/plugins/projectexplorer/projectnodes.h | 7 +-
6 files changed, 106 insertions(+), 107 deletions(-)
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index dc2e7fbf7ff..1f2d1f42124 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -91,7 +91,7 @@ CMakeProject::CMakeProject(CMakeManager *manager, const FileName &fileName)
setProjectManager(manager);
setDocument(new Internal::CMakeFile(this, fileName));
- setRootProjectNode(new CMakeProjectNode(fileName));
+ setRootProjectNode(new CMakeProjectNode(Utils::FileName::fromString(fileName.toFileInfo().absolutePath())));
setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT));
setProjectLanguages(Core::Context(ProjectExplorer::Constants::LANG_CXX));
@@ -244,7 +244,8 @@ void CMakeProject::updateProjectData()
m_watchedFiles.insert(cm);
}
- buildTree(static_cast<CMakeProjectNode *>(rootProjectNode()), bdm->files());
+ QList<FileNode *> fileNodes = bdm->files();
+ rootProjectNode()->buildTree(fileNodes);
bdm->clearFiles(); // Some of the FileNodes in files() were deleted!
updateApplicationAndDeploymentTargets();
@@ -416,98 +417,6 @@ bool CMakeProject::hasBuildTarget(const QString &title) const
return Utils::anyOf(buildTargets(), [title](const CMakeBuildTarget &ct) { return ct.title == title; });
}
-void CMakeProject::gatherFileNodes(ProjectExplorer::FolderNode *parent, QList<ProjectExplorer::FileNode *> &list) const
-{
- foreach (ProjectExplorer::FolderNode *folder, parent->subFolderNodes())
- gatherFileNodes(folder, list);
- foreach (ProjectExplorer::FileNode *file, parent->fileNodes())
- list.append(file);
-}
-
-bool sortNodesByPath(Node *a, Node *b)
-{
- return a->filePath() < b->filePath();
-}
-
-void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> newList)
-{
- // Gather old list
- QList<ProjectExplorer::FileNode *> oldList;
- gatherFileNodes(rootNode, oldList);
- Utils::sort(oldList, sortNodesByPath);
- Utils::sort(newList, sortNodesByPath);
-
- QList<ProjectExplorer::FileNode *> added;
- QList<ProjectExplorer::FileNode *> deleted;
-
- ProjectExplorer::compareSortedLists(oldList, newList, deleted, added, sortNodesByPath);
-
- qDeleteAll(ProjectExplorer::subtractSortedList(newList, added, sortNodesByPath));
-
- QHash<ProjectExplorer::FolderNode *, QList<ProjectExplorer::FileNode *> > addedFolderMapping;
- QHash<ProjectExplorer::FolderNode *, QList<ProjectExplorer::FileNode *> > deletedFolderMapping;
-
- // add added nodes
- foreach (ProjectExplorer::FileNode *fn, added) {
- // Get relative path to rootNode
- QString parentDir = fn->filePath().toFileInfo().absolutePath();
- ProjectExplorer::FolderNode *folder = findOrCreateFolder(rootNode, parentDir);
- addedFolderMapping[folder] << fn;
- }
-
- for (auto i = addedFolderMapping.constBegin(); i != addedFolderMapping.constEnd(); ++i)
- i.key()->addFileNodes(i.value());
-
- // remove old file nodes and check whether folder nodes can be removed
- foreach (ProjectExplorer::FileNode *fn, deleted)
- deletedFolderMapping[fn->parentFolderNode()] << fn;
-
- for (auto i = deletedFolderMapping.constBegin(); i != deletedFolderMapping.constEnd(); ++i) {
- ProjectExplorer::FolderNode *parent = i.key();
- parent->removeFileNodes(i.value());
- // Check for empty parent
- while (parent->subFolderNodes().isEmpty() && parent->fileNodes().isEmpty()) {
- ProjectExplorer::FolderNode *grandparent = parent->parentFolderNode();
- grandparent->removeFolderNodes(QList<ProjectExplorer::FolderNode *>() << parent);
- parent = grandparent;
- if (parent == rootNode)
- break;
- }
- }
-}
-
-ProjectExplorer::FolderNode *CMakeProject::findOrCreateFolder(CMakeProjectNode *rootNode, QString directory)
-{
- FileName path = rootNode->filePath().parentDir();
- QDir rootParentDir(path.toString());
- QString relativePath = rootParentDir.relativeFilePath(directory);
- if (relativePath == QLatin1String("."))
- relativePath.clear();
- QStringList parts = relativePath.split(QLatin1Char('/'), QString::SkipEmptyParts);
- ProjectExplorer::FolderNode *parent = rootNode;
- foreach (const QString &part, parts) {
- path.appendPath(part);
- // Find folder in subFolders
- bool found = false;
- foreach (ProjectExplorer::FolderNode *folder, parent->subFolderNodes()) {
- if (folder->filePath() == path) {
- // yeah found something :)
- parent = folder;
- found = true;
- break;
- }
- }
- if (!found) {
- // No FolderNode yet, so create it
- auto tmp = new ProjectExplorer::FolderNode(path);
- tmp->setDisplayName(part);
- parent->addFolderNodes(QList<ProjectExplorer::FolderNode *>() << tmp);
- parent = tmp;
- }
- }
- return parent;
-}
-
QString CMakeProject::displayName() const
{
return rootProjectNode()->displayName();
@@ -515,9 +424,8 @@ QString CMakeProject::displayName() const
QStringList CMakeProject::files(FilesMode fileMode) const
{
- QList<FileNode *> nodes;
- gatherFileNodes(rootProjectNode(), nodes);
- nodes = Utils::filtered(nodes, [fileMode](const FileNode *fn) {
+ const QList<FileNode *> nodes = Utils::filtered(rootProjectNode()->recursiveFileNodes(),
+ [fileMode](const FileNode *fn) {
const bool isGenerated = fn->isGenerated();
switch (fileMode)
{
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h
index f214592d8fd..334cca4f6c7 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.h
@@ -118,9 +118,6 @@ private:
void updateProjectData();
void updateQmlJSCodeModel();
- void buildTree(Internal::CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list);
- void gatherFileNodes(ProjectExplorer::FolderNode *parent, QList<ProjectExplorer::FileNode *> &list) const;
- ProjectExplorer::FolderNode *findOrCreateFolder(Internal::CMakeProjectNode *rootNode, QString directory);
void createGeneratedCodeModelSupport();
QStringList filesGeneratedFrom(const QString &sourceFile) const final;
void updateTargetRunConfigurations(ProjectExplorer::Target *t);
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
index 73c6378ca9e..f42d08c6278 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
@@ -28,8 +28,8 @@
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
-CMakeProjectNode::CMakeProjectNode(const Utils::FileName &fileName)
- : ProjectExplorer::ProjectNode(fileName)
+CMakeProjectNode::CMakeProjectNode(const Utils::FileName &dirName)
+ : ProjectExplorer::ProjectNode(dirName)
{
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
index 9dcb720767f..34a2e73619a 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
@@ -35,7 +35,7 @@ namespace Internal {
class CMakeProjectNode : public ProjectExplorer::ProjectNode
{
public:
- CMakeProjectNode(const Utils::FileName &fileName);
+ CMakeProjectNode(const Utils::FileName &dirName);
bool showInSimpleTree() const override;
QList<ProjectExplorer::ProjectAction> supportedActions(Node *node) const override;
};
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index eb110272cc9..9d97dff9413 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -269,11 +269,102 @@ QList<FileNode*> FolderNode::fileNodes() const
return m_fileNodes;
}
+QList<FileNode *> FolderNode::recursiveFileNodes() const
+{
+ QList<FileNode *> result = fileNodes();
+ foreach (ProjectExplorer::FolderNode *folder, subFolderNodes())
+ result.append(folder->recursiveFileNodes());
+ return result;
+}
+
QList<FolderNode*> FolderNode::subFolderNodes() const
{
return m_subFolderNodes;
}
+FolderNode *FolderNode::findOrCreateSubFolderNode(const QString &directory)
+{
+ Utils::FileName path = filePath();
+ QDir parentDir(path.toString());
+ QString relativePath = parentDir.relativeFilePath(directory);
+ if (relativePath == ".")
+ relativePath.clear();
+ QStringList parts = relativePath.split('/', QString::SkipEmptyParts);
+ ProjectExplorer::FolderNode *parent = this;
+ foreach (const QString &part, parts) {
+ path.appendPath(part);
+ // Find folder in subFolders
+ bool found = false;
+ foreach (ProjectExplorer::FolderNode *folder, parent->subFolderNodes()) {
+ if (folder->filePath() == path) {
+ // yeah found something :)
+ parent = folder;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // No FolderNode yet, so create it
+ auto tmp = new ProjectExplorer::FolderNode(path);
+ tmp->setDisplayName(part);
+ parent->addFolderNodes(QList<ProjectExplorer::FolderNode *>({ tmp }));
+ parent = tmp;
+ }
+ }
+ return parent;
+}
+
+static bool sortNodesByPath(Node *a, Node *b)
+{
+ return a->filePath() < b->filePath();
+}
+
+void FolderNode::buildTree(QList<FileNode *> &files)
+{
+ // Gather old list
+ QList<ProjectExplorer::FileNode *> oldFiles = recursiveFileNodes();
+ Utils::sort(oldFiles, sortNodesByPath);
+ Utils::sort(files, sortNodesByPath);
+
+ QList<ProjectExplorer::FileNode *> added;
+ QList<ProjectExplorer::FileNode *> deleted;
+
+ ProjectExplorer::compareSortedLists(oldFiles, files, deleted, added, sortNodesByPath);
+
+ qDeleteAll(ProjectExplorer::subtractSortedList(files, added, sortNodesByPath));
+
+ QHash<ProjectExplorer::FolderNode *, QList<ProjectExplorer::FileNode *> > addedFolderMapping;
+ QHash<ProjectExplorer::FolderNode *, QList<ProjectExplorer::FileNode *> > deletedFolderMapping;
+
+ // add added nodes
+ foreach (ProjectExplorer::FileNode *fn, added) {
+ // Get relative path to rootNode
+ QString parentDir = fn->filePath().toFileInfo().absolutePath();
+ ProjectExplorer::FolderNode *folder = findOrCreateSubFolderNode(parentDir);
+ addedFolderMapping[folder] << fn;
+ }
+
+ for (auto i = addedFolderMapping.constBegin(); i != addedFolderMapping.constEnd(); ++i)
+ i.key()->addFileNodes(i.value());
+
+ // remove old file nodes and check whether folder nodes can be removed
+ foreach (ProjectExplorer::FileNode *fn, deleted)
+ deletedFolderMapping[fn->parentFolderNode()] << fn;
+
+ for (auto i = deletedFolderMapping.constBegin(); i != deletedFolderMapping.constEnd(); ++i) {
+ ProjectExplorer::FolderNode *parent = i.key();
+ parent->removeFileNodes(i.value());
+ // Check for empty parent
+ while (parent->subFolderNodes().isEmpty() && parent->fileNodes().isEmpty()) {
+ ProjectExplorer::FolderNode *grandparent = parent->parentFolderNode();
+ grandparent->removeFolderNodes(QList<ProjectExplorer::FolderNode *>() << parent);
+ parent = grandparent;
+ if (parent == this)
+ break;
+ }
+ }
+}
+
void FolderNode::accept(NodesVisitor *visitor)
{
visitor->visitFolderNode(this);
@@ -707,7 +798,7 @@ ProjectNode *ProjectNode::asProjectNode()
*/
SessionNode::SessionNode() :
- FolderNode(Utils::FileName::fromString(QLatin1String("session")), SessionNodeType)
+ FolderNode(Utils::FileName::fromString("session"), SessionNodeType)
{ }
QList<ProjectAction> SessionNode::supportedActions(Node *node) const
@@ -747,7 +838,7 @@ QList<ProjectNode*> SessionNode::projectNodes() const
QString SessionNode::addFileFilter() const
{
- return QLatin1String("*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; *.h; *.hh; *.hpp; *.hxx;");
+ return QString::fromLatin1("*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; *.h; *.hh; *.hpp; *.hxx;");
}
void SessionNode::addProjectNodes(const QList<ProjectNode*> &projectNodes)
diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h
index de7bf243898..a4b4ea47654 100644
--- a/src/plugins/projectexplorer/projectnodes.h
+++ b/src/plugins/projectexplorer/projectnodes.h
@@ -172,8 +172,11 @@ public:
QString displayName() const override;
QIcon icon() const;
- QList<FileNode*> fileNodes() const;
- QList<FolderNode*> subFolderNodes() const;
+ QList<FileNode *> fileNodes() const;
+ QList<FileNode *> recursiveFileNodes() const;
+ QList<FolderNode *> subFolderNodes() const;
+ FolderNode *findOrCreateSubFolderNode(const QString &directory);
+ void buildTree(QList<FileNode *> &files);
virtual void accept(NodesVisitor *visitor);
--
GitLab