diff options
author | Tobias Hunger <tobias.hunger@qt.io> | 2019-06-12 16:18:08 +0200 |
---|---|---|
committer | Tobias Hunger <tobias.hunger@qt.io> | 2019-06-13 12:27:44 +0000 |
commit | 023d9954601cca13e15848dbb8fad4cc66501b64 (patch) | |
tree | f99310d1afbf813e8c2a4e0421fa4a683ab05b5e /src/plugins/cmakeprojectmanager/projecttreehelper.cpp | |
parent | a56d32145b4b2adab096ca55102c1c24a580acd2 (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.cpp | 204 |
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 |