diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index dc2e7fbf7ff178081c4a62838d5f7bbe9ffa45bf..1f2d1f42124129f10a8da9a7bba08f30087a0e0a 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 f214592d8fdcdcdfcc73eb43556e10712507b40a..334cca4f6c778e98cdbec80b8e6449f922c9b095 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 73c6378ca9e9aaae55d74bc41d7bc14f469586ee..f42d08c6278cf4ec7f2b1accff5e3213a41a8b26 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 9dcb720767f9dac376fa42e2ee39227223e08985..34a2e73619ad1eaf89b753a83ec47616022bda19 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 eb110272cc9a143c84abd888a8b6173ecada3509..9d97dff94134b1e0d79ca07140989c6fa7ad43ab 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 de7bf243898bf32b266673bf4f868b613c0583cf..a4b4ea47654e01ab7c3177100ecfc5479314308e 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);