aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/cmakeprojectmanager/projecttreehelper.cpp
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@qt.io>2019-06-12 16:18:08 +0200
committerTobias Hunger <tobias.hunger@qt.io>2019-06-13 12:27:44 +0000
commit023d9954601cca13e15848dbb8fad4cc66501b64 (patch)
treef99310d1afbf813e8c2a4e0421fa4a683ab05b5e /src/plugins/cmakeprojectmanager/projecttreehelper.cpp
parenta56d32145b4b2adab096ca55102c1c24a580acd2 (diff)
CMake: Move some code out of the ServerModeReader
... so that it can get re-used in the to-be-written fileapi reader. Change-Id: I2693e6bb102d910eb505882bf3468c34272a5d04 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/plugins/cmakeprojectmanager/projecttreehelper.cpp')
-rw-r--r--src/plugins/cmakeprojectmanager/projecttreehelper.cpp204
1 files changed, 204 insertions, 0 deletions
diff --git a/src/plugins/cmakeprojectmanager/projecttreehelper.cpp b/src/plugins/cmakeprojectmanager/projecttreehelper.cpp
new file mode 100644
index 00000000000..c1a3abaaaef
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/projecttreehelper.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "projecttreehelper.h"
+
+#include <coreplugin/fileiconprovider.h>
+#include <projectexplorer/projectexplorerconstants.h>
+
+#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
+
+using namespace ProjectExplorer;
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+void addCMakeVFolder(FolderNode *base,
+ const Utils::FilePath &basePath,
+ int priority,
+ const QString &displayName,
+ std::vector<std::unique_ptr<FileNode>> &&files)
+{
+ if (files.size() == 0)
+ return;
+ FolderNode *folder = base;
+ if (!displayName.isEmpty()) {
+ auto newFolder = std::make_unique<VirtualFolderNode>(basePath);
+ newFolder->setPriority(priority);
+ newFolder->setDisplayName(displayName);
+ folder = newFolder.get();
+ base->addNode(std::move(newFolder));
+ }
+ folder->addNestedNodes(std::move(files));
+ for (FolderNode *fn : folder->folderNodes())
+ fn->compress();
+}
+
+std::vector<std::unique_ptr<FileNode>> &&removeKnownNodes(
+ const QSet<Utils::FilePath> &knownFiles, std::vector<std::unique_ptr<FileNode>> &&files)
+{
+ Utils::erase(files, [&knownFiles](const std::unique_ptr<FileNode> &n) {
+ return knownFiles.contains(n->filePath());
+ });
+ return std::move(files);
+}
+
+void addCMakeInputs(FolderNode *root,
+ const Utils::FilePath &sourceDir,
+ const Utils::FilePath &buildDir,
+ std::vector<std::unique_ptr<FileNode>> &&sourceInputs,
+ std::vector<std::unique_ptr<FileNode>> &&buildInputs,
+ std::vector<std::unique_ptr<FileNode>> &&rootInputs)
+{
+ std::unique_ptr<ProjectNode> cmakeVFolder = std::make_unique<CMakeInputsNode>(root->filePath());
+
+ QSet<Utils::FilePath> knownFiles;
+ root->forEachGenericNode([&knownFiles](const Node *n) {
+ if (n->listInProject())
+ knownFiles.insert(n->filePath());
+ });
+
+ addCMakeVFolder(cmakeVFolder.get(),
+ sourceDir,
+ 1000,
+ QString(),
+ removeKnownNodes(knownFiles, std::move(sourceInputs)));
+ addCMakeVFolder(cmakeVFolder.get(),
+ buildDir,
+ 100,
+ QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader",
+ "<Build Directory>"),
+ removeKnownNodes(knownFiles, std::move(buildInputs)));
+ addCMakeVFolder(cmakeVFolder.get(),
+ Utils::FilePath(),
+ 10,
+ QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader",
+ "<Other Locations>"),
+ removeKnownNodes(knownFiles, std::move(rootInputs)));
+
+ root->addNode(std::move(cmakeVFolder));
+}
+QHash<Utils::FilePath, ProjectNode *> addCMakeLists(
+ CMakeProjectNode *root, std::vector<std::unique_ptr<FileNode>> &&cmakeLists)
+{
+ QHash<Utils::FilePath, ProjectNode *> cmakeListsNodes;
+ cmakeListsNodes.insert(root->filePath(), root);
+
+ const QSet<Utils::FilePath> cmakeDirs
+ = Utils::transform<QSet>(cmakeLists, [](const std::unique_ptr<FileNode> &n) {
+ return n->filePath().parentDir();
+ });
+ root->addNestedNodes(std::move(cmakeLists),
+ Utils::FilePath(),
+ [&cmakeDirs, &cmakeListsNodes](const Utils::FilePath &fp)
+ -> std::unique_ptr<ProjectExplorer::FolderNode> {
+ if (cmakeDirs.contains(fp)) {
+ auto fn = std::make_unique<CMakeListsNode>(fp);
+ cmakeListsNodes.insert(fp, fn.get());
+ return std::move(fn);
+ }
+
+ return std::make_unique<FolderNode>(fp);
+ });
+ root->compress();
+ return cmakeListsNodes;
+}
+
+void createProjectNode(const QHash<Utils::FilePath, ProjectNode *> &cmakeListsNodes,
+ const Utils::FilePath &dir,
+ const QString &displayName)
+{
+ ProjectNode *cmln = cmakeListsNodes.value(dir);
+ QTC_ASSERT(cmln, return );
+
+ const Utils::FilePath projectName = dir.pathAppended(".project::" + displayName);
+
+ ProjectNode *pn = cmln->projectNode(projectName);
+ if (!pn) {
+ auto newNode = std::make_unique<CMakeProjectNode>(projectName);
+ pn = newNode.get();
+ cmln->addNode(std::move(newNode));
+ }
+ pn->setDisplayName(displayName);
+}
+
+CMakeTargetNode *createTargetNode(const QHash<Utils::FilePath, ProjectNode *> &cmakeListsNodes,
+ const Utils::FilePath &dir,
+ const QString &displayName)
+{
+ ProjectNode *cmln = cmakeListsNodes.value(dir);
+ QTC_ASSERT(cmln, return nullptr);
+
+ QString targetId = CMakeTargetNode::generateId(dir, displayName);
+
+ CMakeTargetNode *tn = static_cast<CMakeTargetNode *>(
+ cmln->findNode([&targetId](const Node *n) { return n->buildKey() == targetId; }));
+ if (!tn) {
+ auto newNode = std::make_unique<CMakeTargetNode>(dir, displayName);
+ tn = newNode.get();
+ cmln->addNode(std::move(newNode));
+ }
+ tn->setDisplayName(displayName);
+ return tn;
+}
+
+void addHeaderNodes(ProjectNode *root,
+ const QList<FileNode *> knownHeaders,
+ const QList<const FileNode *> &allFiles)
+{
+ if (root->isEmpty())
+ return;
+
+ static QIcon headerNodeIcon = Core::FileIconProvider::directoryIcon(
+ ProjectExplorer::Constants::FILEOVERLAY_H);
+ auto headerNode = std::make_unique<VirtualFolderNode>(root->filePath());
+ headerNode->setPriority(Node::DefaultPriority - 5);
+ headerNode->setDisplayName(
+ QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", "<Headers>"));
+ headerNode->setIcon(headerNodeIcon);
+
+ // knownHeaders are already listed in their targets:
+ QSet<Utils::FilePath> seenHeaders = Utils::transform<QSet>(knownHeaders, &FileNode::filePath);
+
+ // Add scanned headers:
+ for (const FileNode *fn : allFiles) {
+ if (fn->fileType() != FileType::Header || !fn->filePath().isChildOf(root->filePath()))
+ continue;
+ const int count = seenHeaders.count();
+ seenHeaders.insert(fn->filePath());
+ if (seenHeaders.count() != count) {
+ std::unique_ptr<FileNode> node(fn->clone());
+ node->setEnabled(false);
+ headerNode->addNestedNode(std::move(node));
+ }
+ }
+
+ if (!headerNode->isEmpty())
+ root->addNode(std::move(headerNode));
+}
+
+} // namespace Internal
+} // namespace CMakeProjectManager