diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index f1a55a50319..79223f0336e 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -395,31 +396,19 @@ void addProjects(const QHash &cmakeListsNodes, } } -QVector addSourceGroups(ProjectNode *targetRoot, - const TargetDetails &td, - const FilePath &sourceDirectory) +std::unique_ptr createSourceGroupNode(const QString &sourceGroupName, + const FilePath &sourceDirectory) { - QVector sourceGroupNodes; - if (td.sourceGroups.size() == 1) { - sourceGroupNodes.append( - targetRoot); // Only one source group, so do not bother to display any:-) - } else { - for (const QString &sg : td.sourceGroups) { - if (sg.isEmpty()) { - sourceGroupNodes.append(targetRoot); - } else { - auto sgNode = createCMakeVFolder(sourceDirectory, - Node::DefaultFolderPriority + 5, - sg); - sgNode->setListInProject(false); + if (sourceGroupName.isEmpty()) + return {}; - sourceGroupNodes.append(sgNode.get()); - targetRoot->addNode(std::move(sgNode)); - } - } - } + auto sgNode = createCMakeVFolder(sourceDirectory, + Node::DefaultFolderPriority + 5, + sourceGroupName); - return sourceGroupNodes; + sgNode->setListInProject(false); + sgNode->setIcon(QIcon::fromTheme("edit-copy", ::Utils::Icons::COPY.icon())); + return sgNode; } void addCompileGroups(ProjectNode *targetRoot, @@ -439,11 +428,11 @@ void addCompileGroups(ProjectNode *targetRoot, targetRoot->forEachGenericNode( [&alreadyListed](const Node *n) { alreadyListed.insert(n->filePath()); }); - QVector sourceGroupNodes = addSourceGroups(targetRoot, td, sourceDirectory); const QDir topSourceDir(topSourceDirectory.toString()); std::vector> buildFileNodes; std::vector> otherFileNodes; + std::vector>> sourceGroupFileNodes{td.sourceGroups.size()}; for (const SourceInfo &si : td.sources) { const FilePath sourcePath = FilePath::fromString( @@ -467,12 +456,34 @@ void addCompileGroups(ProjectNode *targetRoot, if (sourcePath.isChildOf(buildDirectory) && !inSourceBuild) { buildFileNodes.emplace_back(std::move(node)); } else if (sourcePath.isChildOf(sourceDirectory)) { - sourceGroupNodes[si.sourceGroup]->addNestedNode(std::move(node)); + sourceGroupFileNodes[si.sourceGroup].emplace_back(std::move(node)); } else { otherFileNodes.emplace_back(std::move(node)); } } + // Calculate base directory for source groups: + for (size_t i = 0; i < sourceGroupFileNodes.size(); ++i) { + std::vector> ¤t = sourceGroupFileNodes[i]; + FilePath baseDirectory; + // All the sourceGroupFileNodes are below sourceDirectory, so this is safe: + for (const std::unique_ptr &fn : current) { + if (baseDirectory.isEmpty()) { + baseDirectory = fn->filePath().parentDir(); + } else { + baseDirectory = Utils::FileUtils::commonPath(baseDirectory, fn->filePath()); + } + } + + FolderNode *insertNode = targetRoot; + if (auto sgNode = createSourceGroupNode(td.sourceGroups[i], baseDirectory)) { + insertNode = sgNode.get(); + targetRoot->addNode(std::move(sgNode)); + } + + insertNode->addNestedNodes(std::move(sourceGroupFileNodes[i])); + } + addCMakeVFolder(targetRoot, buildDirectory, 100,