From dcc023917a4ff66f218169081044752377ab76d8 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Wed, 21 Aug 2024 19:52:10 +0200 Subject: [PATCH] CMakePM: Add support for "add_subdirectory" operations This means support for context menu and then "Add Existing Projects..." and "New Subproject..." Fixes: QTCREATORBUG-30471 Fixes: QTCREATORBUG-30818 Change-Id: Iffb0c4be744352c8acf1d9ee0bc58602af4426ba Reviewed-by: Marcus Tillmanns --- .../cmakeprojectmanager/cmakebuildsystem.cpp | 6 ++ .../cmakeprojectmanager/cmakeprojectnodes.cpp | 67 +++++++++++++++++++ .../cmakeprojectmanager/cmakeprojectnodes.h | 8 +++ 3 files changed, 81 insertions(+) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index 596b11e45b1..320f286036d 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -234,6 +234,12 @@ bool CMakeBuildSystem::supportsAction(Node *context, ProjectAction action, const || action == ProjectAction::Rename || action == ProjectAction::RemoveFile; } + const auto cmakeProject = dynamic_cast(context); + const auto cmakeListsNode = dynamic_cast(context); + if (cmakeProject || cmakeListsNode) + return action == ProjectAction::AddSubProject + || action == ProjectAction::AddExistingProject; + return BuildSystem::supportsAction(context, action, node); } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp index bb58db95e36..238d7862dd0 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp @@ -9,6 +9,8 @@ #include +#include + #include #include @@ -16,11 +18,44 @@ #include +#include + using namespace ProjectExplorer; using namespace Utils; namespace CMakeProjectManager::Internal { +static QString quoteString(const QString &str) +{ + return str.contains(QChar::Space) ? ("\"" + str + "\"") : str; +} + +static bool addSubdirectory(const Utils::FilePath &projectPathDir, const Utils::FilePath & subProjectFilePath) +{ + TextEditor::BaseTextEditor *editor = qobject_cast( + Core::EditorManager::openEditorAt( + {projectPathDir.pathAppended(Constants::CMAKE_LISTS_TXT)}, + Constants::CMAKE_EDITOR_ID, + Core::EditorManager::DoNotMakeVisible | Core::EditorManager::DoNotChangeCurrentEditor)); + if (!editor) + return false; + + const QString subDirectory = subProjectFilePath.relativeChildPath(projectPathDir).parentDir().path(); + if (subDirectory.isEmpty()) + return false; + + QTextCursor cursor = editor->textCursor(); + cursor.movePosition(QTextCursor::End); + if (!cursor.block().text().isEmpty()) + cursor.insertText("\n"); + cursor.insertText(QString("add_subdirectory(%1)").arg(quoteString(subDirectory))); + + if (!Core::DocumentManager::saveDocument(editor->document())) + return false; + + return true; +} + CMakeInputsNode::CMakeInputsNode(const FilePath &cmakeLists) : ProjectExplorer::ProjectNode(cmakeLists) { @@ -58,6 +93,22 @@ std::optional CMakeListsNode::visibleAfterAddFileAction() const return filePath().pathAppended(Constants::CMAKE_LISTS_TXT); } +bool CMakeListsNode::canAddSubProject(const Utils::FilePath &subProjectFilePath) const +{ + return subProjectFilePath != filePath().pathAppended(Constants::CMAKE_LISTS_TXT) + && subProjectFilePath.isChildOf(filePath()); +} + +bool CMakeListsNode::addSubProject(const Utils::FilePath &subProjectFilePath) +{ + return addSubdirectory(filePath(), subProjectFilePath); +} + +QStringList CMakeListsNode::subProjectFileNamePatterns() const +{ + return {Constants::CMAKE_LISTS_TXT}; +} + CMakeProjectNode::CMakeProjectNode(const FilePath &directory) : ProjectExplorer::ProjectNode(directory) { @@ -66,6 +117,22 @@ CMakeProjectNode::CMakeProjectNode(const FilePath &directory) : setListInProject(false); } +bool CMakeProjectNode::canAddSubProject(const Utils::FilePath &subProjectFilePath) const +{ + return subProjectFilePath != filePath().pathAppended(Constants::CMAKE_LISTS_TXT) + && subProjectFilePath.isChildOf(filePath()); +} + +bool CMakeProjectNode::addSubProject(const Utils::FilePath &subProjectFilePath) +{ + return addSubdirectory(filePath(), subProjectFilePath); +} + +QStringList CMakeProjectNode::subProjectFileNamePatterns() const +{ + return {Constants::CMAKE_LISTS_TXT}; +} + QString CMakeProjectNode::tooltip() const { return QString(); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h index 57b180bbba3..e9aa548e054 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h @@ -28,6 +28,10 @@ public: bool showInSimpleTree() const final; std::optional visibleAfterAddFileAction() const override; + + bool canAddSubProject(const Utils::FilePath &subProjectFilePath) const override; + bool addSubProject(const Utils::FilePath &subProjectFilePath) override; + QStringList subProjectFileNamePatterns() const override; }; class CMakeProjectNode : public ProjectExplorer::ProjectNode @@ -35,6 +39,10 @@ class CMakeProjectNode : public ProjectExplorer::ProjectNode public: CMakeProjectNode(const Utils::FilePath &directory); + bool canAddSubProject(const Utils::FilePath &subProjectFilePath) const override; + bool addSubProject(const Utils::FilePath &subProjectFilePath) override; + QStringList subProjectFileNamePatterns() const override; + QString tooltip() const final; };