diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h index 0f01cc69c5d..2d4cd089a0c 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h @@ -62,6 +62,8 @@ const char CMAKE_FEATURE_ID[] = "CMakeProjectManager.Wizard.FeatureCMake"; // Tool const char TOOL_ID[] = "CMakeProjectManager.CMakeKitInformation"; +// Data +const char BUILD_FOLDER_ROLE[] = "CMakeProjectManager.data.buildFolder"; } // namespace Constants } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp index cd300916253..36016aa0c94 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp @@ -108,6 +108,9 @@ QVariant CMakeTargetNode::data(Id role) const return {}; }; + if (role == Constants::BUILD_FOLDER_ROLE) + return m_buildDirectory.toVariant(); + if (role == Android::Constants::AndroidAbi) return value(Android::Constants::ANDROID_ABI); diff --git a/src/plugins/mcusupport/CMakeLists.txt b/src/plugins/mcusupport/CMakeLists.txt index 57b12dd1b04..778f0a70394 100644 --- a/src/plugins/mcusupport/CMakeLists.txt +++ b/src/plugins/mcusupport/CMakeLists.txt @@ -22,6 +22,7 @@ add_qtc_plugin(McuSupport mcutargetdescription.h mcuhelpers.cpp mcuhelpers.h settingshandler.cpp settingshandler.h + mcuqmlprojectnode.cpp mcuqmlprojectnode.h ) add_subdirectory(test) diff --git a/src/plugins/mcusupport/mcuqmlprojectnode.cpp b/src/plugins/mcusupport/mcuqmlprojectnode.cpp new file mode 100644 index 00000000000..9b1c1caf89d --- /dev/null +++ b/src/plugins/mcusupport/mcuqmlprojectnode.cpp @@ -0,0 +1,96 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "mcuqmlprojectnode.h" + +#include + +namespace McuSupport::Internal { + +using namespace ProjectExplorer; +using namespace Utils; + +McuQmlProjectNode::McuQmlProjectNode(const FilePath &projectFolder, const FilePath &inputsJsonFile) + : FolderNode(projectFolder) +{ + setDisplayName("QmlProject"); + setIcon(DirectoryIcon(":/projectexplorer/images/fileoverlay_qml.png")); + setIsGenerated(false); + setPriority(Node::DefaultProjectPriority); + setFilePath(projectFolder); + setListInProject(true); + + const expected_str expectedJsonContent = inputsJsonFile.fileContents(); + if (!expectedJsonContent) + return; + + const QJsonDocument inputDoc = QJsonDocument::fromJson(*expectedJsonContent); + const QVariantMap mainProjectObject = inputDoc.object().toVariantMap(); + const FilePath mainProjectFilePath = FilePath::fromUserInput( + mainProjectObject.value("qmlProjectFile", "").toString()); + + auto mainFileNode = std::make_unique(mainProjectFilePath, + FileNode::fileTypeForFileName( + mainProjectFilePath)); + mainFileNode->setPriority(100); + addNestedNode(std::move(mainFileNode)); + + this->populateModuleNode(this, mainProjectObject); + + auto modulesNode = std::make_unique(filePath()); + modulesNode->setDisplayName("QmlProject Modules"); + modulesNode->setIcon(DirectoryIcon(":/projectexplorer/images/fileoverlay_modules.png")); + modulesNode->setPriority(10); + for (QVariant moduleVariant : mainProjectObject.value("modulesDependencies", {}).toList()) { + const QVariantMap moduleObject = moduleVariant.toMap(); + auto moduleNode = std::make_unique(filePath()); + moduleNode->setIcon(DirectoryIcon(":/projectexplorer/images/fileoverlay_qml.png")); + moduleNode->setDisplayName( + FilePath::fromUserInput(moduleObject.value("qmlProjectFile", "module").toString()) + .baseName()); + populateModuleNode(moduleNode.get(), moduleObject); + modulesNode->addNode(std::move(moduleNode)); + } + addNode(std::move(modulesNode)); +} + +bool McuQmlProjectNode::populateModuleNode(FolderNode *moduleNode, const QVariantMap &moduleObject) +{ + if (!moduleNode) + return false; + + const static int NODES_COUNT = 6; + const static QString nodes[NODES_COUNT] = {"QmlFiles", + "ImageFiles", + "InterfaceFiles", + "FontFiles", + "TranslationFiles", + "ModuleFiles"}; + const static QString icons[NODES_COUNT] = {":/projectexplorer/images/fileoverlay_qml.png", + ":/projectexplorer/images/fileoverlay_qrc.png", + ":/projectexplorer/images/fileoverlay_h.png", + ":/projectexplorer/images/fileoverlay_qrc.png", + ":/projectexplorer/images/fileoverlay_qrc.png", + ":/projectexplorer/images/fileoverlay_qml.png"}; + const static int priorities[NODES_COUNT] = {70, 60, 50, 40, 30, 20}; + + for (int i = 0; i < NODES_COUNT; i++) { + const QString &node = nodes[i]; + const QString &icon = icons[i]; + const int &p = priorities[i]; + auto foldernode = std::make_unique(filePath()); + foldernode->setShowWhenEmpty(false); + foldernode->setDisplayName(node); + foldernode->setIcon(DirectoryIcon(icon)); + foldernode->setPriority(p); + const auto nodeFiles = moduleObject.value(node, {}).toStringList(); + for (auto p : nodeFiles) { + const FilePath nodePath = FilePath::fromUserInput(p); + foldernode->addNestedNode( + std::make_unique(nodePath, FileNode::fileTypeForFileName(nodePath))); + } + moduleNode->addNode(std::move(foldernode)); + } + return true; +} +} // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcuqmlprojectnode.h b/src/plugins/mcusupport/mcuqmlprojectnode.h new file mode 100644 index 00000000000..2a06e5cde55 --- /dev/null +++ b/src/plugins/mcusupport/mcuqmlprojectnode.h @@ -0,0 +1,47 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "mcuqmlprojectnode.h" +#include "mcusupport_global.h" +#include "mcusupportplugin.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace McuSupport::Internal { + +using namespace ProjectExplorer; +using namespace Utils; + +class McuQmlProjectFolderNode : public FolderNode +{ +public: + explicit McuQmlProjectFolderNode(const FilePath &path) + : FolderNode(path) + {} + bool showInSimpleTree() const override { return true; } +}; + +class McuQmlProjectNode : public FolderNode +{ +public: + explicit McuQmlProjectNode(const FilePath &projectFolder, const FilePath &inputsJsonFile); + bool showInSimpleTree() const override { return true; } + bool populateModuleNode(FolderNode *moduleNode, const QVariantMap &moduleObject); +}; +}; // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcusupport.qbs b/src/plugins/mcusupport/mcusupport.qbs index efd14b453b0..e6aec151a06 100644 --- a/src/plugins/mcusupport/mcusupport.qbs +++ b/src/plugins/mcusupport/mcusupport.qbs @@ -37,6 +37,8 @@ QtcPlugin { "mcusupportoptions.h", "mcukitmanager.cpp", "mcukitmanager.h", + "mcuqmlprojectnode.cpp", + "mcuqmlprojectnode.h", "mcusupportoptionspage.cpp", "mcusupportoptionspage.h", "mcusupportplugin.cpp", diff --git a/src/plugins/mcusupport/mcusupportplugin.cpp b/src/plugins/mcusupport/mcusupportplugin.cpp index 835e619a3ce..8e873785916 100644 --- a/src/plugins/mcusupport/mcusupportplugin.cpp +++ b/src/plugins/mcusupport/mcusupportplugin.cpp @@ -5,6 +5,7 @@ #include "mcukitinformation.h" #include "mcukitmanager.h" +#include "mcuqmlprojectnode.h" #include "mcusupportconstants.h" #include "mcusupportdevice.h" #include "mcusupportoptions.h" @@ -24,8 +25,15 @@ #include #include #include +#include #include +#include +#include +#include +#include + +#include #include #include @@ -49,6 +57,42 @@ void printMessage(const QString &message, bool important) Core::MessageManager::writeSilently(displayMessage); } +void updateMCUProjectTree(ProjectExplorer::Project *p) +{ + if (!p || !p->rootProjectNode()) + return; + ProjectExplorer::Target *target = p->activeTarget(); + if (!target || !target->kit() + || !target->kit()->hasValue(Constants::KIT_MCUTARGET_KITVERSION_KEY)) + return; + + p->rootProjectNode()->forEachProjectNode([](const ProjectNode *node) { + if (!node) + return; + + const FilePath projectBuildFolder = FilePath::fromVariant( + node->data(CMakeProjectManager::Constants::BUILD_FOLDER_ROLE)); + const QString targetName = node->displayName(); + if (targetName.isEmpty()) + return; + + const FilePath inputsJsonFile = projectBuildFolder / "CMakeFiles" / (targetName + ".dir") + / "config/input.json"; + + printMessage("found Input json file " + inputsJsonFile.absoluteFilePath().toString(), true); + + if (!inputsJsonFile.exists()) + return; + + auto qmlProjectNode = std::make_unique(FilePath(node->filePath()), + inputsJsonFile); + + auto qmlProjectNodePtr = qmlProjectNode.get(); + const_cast(node)->addNode(std::move(qmlProjectNode)); + ProjectExplorer::ProjectTree::emitSubtreeChanged(qmlProjectNodePtr); + }); +}; + class McuSupportPluginPrivate { public: @@ -74,6 +118,10 @@ void McuSupportPlugin::initialize() setObjectName("McuSupportPlugin"); dd = new McuSupportPluginPrivate; + connect(SessionManager::instance(), + &SessionManager::projectFinishedParsing, + updateMCUProjectTree); + dd->m_options.registerQchFiles(); dd->m_options.registerExamples(); ProjectExplorer::JsonWizardFactory::addWizardPath(":/mcusupport/wizards/");