From e20d6200436da24bfed43f0738c94e4bc3ce751b Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 14 Mar 2018 14:40:47 +0100 Subject: [PATCH] ProjectExplorer: Let RunConfiguration declare what nodes it belongs to This feature in question is the availability of the "Run" button in the context menu of certain project nodes in the project tree to run something presumably related to/build from that (sub)project. Previously, the decision was made for certain qmake based projects (those targeting Desktop, iOS and VxWorks) by some indirection through the corresponding RunConfigurationFactories. The patch lets the RunConfigurations decide themselves directly and removes the indirection, potentially opening the feature for other qmake based RCs, as well as other combinations (e.g. PythonRunConfiguration could be associated with its .py file, without the need to have a dummy project) Change-Id: Ic489bd1dfa25fcd9102ffa4fa30125565dd2e40e Reviewed-by: Tobias Hunger --- src/plugins/ios/iosrunconfiguration.cpp | 5 ++ src/plugins/ios/iosrunconfiguration.h | 1 + src/plugins/ios/iosrunfactories.cpp | 6 --- src/plugins/ios/iosrunfactories.h | 10 +--- .../projectexplorer/projectexplorer.cpp | 11 ++++- src/plugins/projectexplorer/projectnodes.cpp | 10 ---- src/plugins/projectexplorer/projectnodes.h | 3 -- .../projectexplorer/runconfiguration.h | 2 + src/plugins/qbsprojectmanager/qbsnodes.cpp | 18 -------- src/plugins/qbsprojectmanager/qbsnodes.h | 2 - src/plugins/qbsprojectmanager/qbsproject.h | 2 - .../qbsprojectmanager/qbsrunconfiguration.cpp | 10 ++++ .../qbsprojectmanager/qbsrunconfiguration.h | 1 + .../desktopqmakerunconfiguration.cpp | 11 ++--- .../desktopqmakerunconfiguration.h | 9 ++-- .../qmakeprojectmanager/qmakenodes.cpp | 32 ++----------- src/plugins/qmakeprojectmanager/qmakenodes.h | 1 - .../qmakeprojectmanager/qmakeparsernodes.cpp | 1 - .../qmakeprojectmanager.pro | 2 - .../qmakeprojectmanager.qbs | 1 - .../qmakerunconfigurationfactory.cpp | 33 ------------- .../qmakerunconfigurationfactory.h | 46 ------------------- 22 files changed, 42 insertions(+), 175 deletions(-) delete mode 100644 src/plugins/qmakeprojectmanager/qmakerunconfigurationfactory.cpp delete mode 100644 src/plugins/qmakeprojectmanager/qmakerunconfigurationfactory.h diff --git a/src/plugins/ios/iosrunconfiguration.cpp b/src/plugins/ios/iosrunconfiguration.cpp index 703461266b4..09a3feebde4 100644 --- a/src/plugins/ios/iosrunconfiguration.cpp +++ b/src/plugins/ios/iosrunconfiguration.cpp @@ -157,6 +157,11 @@ void IosRunConfiguration::updateEnabledState() return RunConfiguration::updateEnabledState(); } +bool IosRunConfiguration::canRunForNode(const Node *node) const +{ + return node->filePath() == m_profilePath; +} + IosDeployStep *IosRunConfiguration::deployStep() const { DeployConfiguration *config = target()->activeDeployConfiguration(); diff --git a/src/plugins/ios/iosrunconfiguration.h b/src/plugins/ios/iosrunconfiguration.h index 6e40b66573e..4bdf92f046a 100644 --- a/src/plugins/ios/iosrunconfiguration.h +++ b/src/plugins/ios/iosrunconfiguration.h @@ -74,6 +74,7 @@ private: friend class IosRunConfigurationWidget; void updateDisplayNames(); void updateEnabledState() final; + bool canRunForNode(const ProjectExplorer::Node *node) const final; Utils::FileName m_profilePath; IosDeviceType m_deviceType; diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp index e626e8ac96d..2faa99afbaf 100644 --- a/src/plugins/ios/iosrunfactories.cpp +++ b/src/plugins/ios/iosrunfactories.cpp @@ -59,11 +59,5 @@ IosRunConfigurationFactory::availableCreators(Target *parent) const ProjectType::SharedLibraryTemplate}); } -bool IosRunConfigurationFactory::hasRunConfigForProFile(RunConfiguration *rc, const Utils::FileName &n) const -{ - auto iosRc = qobject_cast(rc); - return iosRc && iosRc->profilePath() == n; -} - } // namespace Internal } // namespace Ios diff --git a/src/plugins/ios/iosrunfactories.h b/src/plugins/ios/iosrunfactories.h index 08159b2456f..0f2b53b02be 100644 --- a/src/plugins/ios/iosrunfactories.h +++ b/src/plugins/ios/iosrunfactories.h @@ -26,17 +26,11 @@ #pragma once #include -#include - -namespace ProjectExplorer { -class Target; -class Node; -} // namespace ProjectExplorer namespace Ios { namespace Internal { -class IosRunConfigurationFactory : public QmakeProjectManager::QmakeRunConfigurationFactory +class IosRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory { Q_OBJECT @@ -45,8 +39,6 @@ public: QList availableCreators(ProjectExplorer::Target *parent) const override; - - bool hasRunConfigForProFile(ProjectExplorer::RunConfiguration *rc, const Utils::FileName &n) const override; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index b4fab761f57..4c632abf8bf 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2969,10 +2969,17 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions() pn = const_cast(currentNode->asProjectNode()); if (pn) { - if (ProjectTree::currentProject() && pn == ProjectTree::currentProject()->rootProjectNode()) { + Project *project = ProjectTree::currentProject(); + if (project && pn == project->rootProjectNode()) { m_runActionContextMenu->setVisible(true); } else { - QList runConfigs = pn->runConfigurations(); + QList runConfigs; + if (Target *t = project->activeTarget()) { + for (RunConfiguration *rc : t->runConfigurations()) { + if (rc->canRunForNode(pn)) + runConfigs.append(rc); + } + } if (runConfigs.count() == 1) { m_runActionContextMenu->setVisible(true); m_runActionContextMenu->setData(QVariant::fromValue(runConfigs.first())); diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index f5e03c31443..3a6a4862887 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -846,16 +846,6 @@ bool ProjectNode::deploysFolder(const QString &folder) const return false; } -/*! - \function bool ProjectNode::runConfigurations() const - - Returns a list of \c RunConfiguration suitable for this node. - */ -QList ProjectNode::runConfigurations() const -{ - return QList(); -} - ProjectNode *ProjectNode::projectNode(const Utils::FileName &file) const { for (Node *node : m_nodes) { diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index 09792a2a36f..76eedf6a538 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -41,7 +41,6 @@ namespace Core { class IVersionControl; } namespace ProjectExplorer { class Project; -class RunConfiguration; enum class NodeType : quint16 { File = 1, @@ -333,8 +332,6 @@ public: // by default returns false virtual bool deploysFolder(const QString &folder) const; - virtual QList runConfigurations() const; - ProjectNode *projectNode(const Utils::FileName &file) const; ProjectNode *asProjectNode() final { return this; } diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 18f7d866450..cbbe52d7293 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -48,6 +48,7 @@ namespace ProjectExplorer { class Abi; class BuildConfiguration; class IRunConfigurationAspect; +class Node; class RunConfigurationFactory; class RunConfiguration; class RunConfigurationCreationInfo; @@ -251,6 +252,7 @@ public: void addExtraAspect(IRunConfigurationAspect *aspect); static RunConfiguration *startupRunConfiguration(); + virtual bool canRunForNode(const ProjectExplorer::Node *) const { return false; } using AspectFactory = std::function; template static void registerAspect() diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp index 37da6326ab9..9bdb87d9eb4 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp @@ -429,24 +429,6 @@ bool QbsProductNode::renameFile(const QString &filePath, const QString &newFileP return prjNode->project()->renameFileInProduct(filePath, newFilePath, m_qbsProductData, grp); } -QList QbsProductNode::runConfigurations() const -{ - QList result; - auto pn = dynamic_cast(managingProject()); - if (!isEnabled() || !pn || m_qbsProductData.targetExecutable().isEmpty()) - return result; - - foreach (ProjectExplorer::RunConfiguration *rc, pn->project()->activeTarget()->runConfigurations()) { - QbsRunConfiguration *qbsRc = qobject_cast(rc); - if (!qbsRc) - continue; - if (qbsRc->uniqueProductName() == QbsProject::uniqueProductName(qbsProductData())) - result << qbsRc; - } - - return result; -} - // -------------------------------------------------------------------- // QbsProjectNode: // -------------------------------------------------------------------- diff --git a/src/plugins/qbsprojectmanager/qbsnodes.h b/src/plugins/qbsprojectmanager/qbsnodes.h index f6d02f16b57..45a7bb4a3a5 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.h +++ b/src/plugins/qbsprojectmanager/qbsnodes.h @@ -110,8 +110,6 @@ public: const qbs::ProductData qbsProductData() const { return m_qbsProductData; } - QList runConfigurations() const override; - private: const qbs::ProductData m_qbsProductData; }; diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h index a30c33e30f6..c45a595dff5 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.h +++ b/src/plugins/qbsprojectmanager/qbsproject.h @@ -45,13 +45,11 @@ namespace Core { class IDocument; } namespace CppTools { class CppProjectUpdater; } -namespace ProjectExplorer { class BuildConfiguration; } namespace QbsProjectManager { namespace Internal { class QbsProjectParser; -class QbsBuildConfiguration; class QbsProject : public ProjectExplorer::Project { diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp index 790b9ef5cae..e8da9cded2f 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp @@ -25,7 +25,9 @@ #include "qbsrunconfiguration.h" +#include "qbsnodes.h" #include "qbsprojectmanagerconstants.h" +#include "qbsproject.h" #include #include @@ -304,6 +306,14 @@ void QbsRunConfiguration::handleBuildSystemDataUpdated() emit enabledChanged(); } +bool QbsRunConfiguration::canRunForNode(const Node *node) const +{ + if (auto pn = dynamic_cast(node)) + return m_uniqueProductName == QbsProject::uniqueProductName(pn->qbsProductData()); + + return false; +} + // -------------------------------------------------------------------- // QbsRunConfigurationFactory: // -------------------------------------------------------------------- diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h index c6098f9f1da..0e76c9cb2bc 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h @@ -70,6 +70,7 @@ private: bool fromMap(const QVariantMap &map) final; QString extraId() const final; void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &rci) final; + bool canRunForNode(const ProjectExplorer::Node *node) const final; QString baseWorkingDirectory() const; QString defaultDisplayName(); diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp index d2c54dc65d6..78305d31dd8 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp @@ -350,6 +350,11 @@ Utils::FileName DesktopQmakeRunConfiguration::proFilePath() const return m_proFilePath; } +bool DesktopQmakeRunConfiguration::canRunForNode(const Node *node) const +{ + return node->filePath() == m_proFilePath; +} + QmakeProject *DesktopQmakeRunConfiguration::qmakeProject() const { return static_cast(target()->project()); @@ -450,11 +455,5 @@ DesktopQmakeRunConfigurationFactory::availableCreators(Target *parent) const return project->runConfigurationCreators(this); } -bool DesktopQmakeRunConfigurationFactory::hasRunConfigForProFile(RunConfiguration *rc, const Utils::FileName &n) const -{ - auto qmakeRc = qobject_cast(rc); - return qmakeRc && qmakeRc->proFilePath() == n; -} - } // namespace Internal } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h index c938031dea6..9a86a166f49 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h @@ -25,8 +25,7 @@ #pragma once -#include - +#include #include #include @@ -45,7 +44,6 @@ class QmakeProFile; class QmakeProject; namespace Internal { -class DesktopQmakeRunConfigurationFactory; class DesktopQmakeRunConfiguration : public ProjectExplorer::RunConfiguration { @@ -98,6 +96,7 @@ private: bool isConsoleApplication() const; QmakeProject *qmakeProject() const; QmakeProFile *proFile() const; + bool canRunForNode(const ProjectExplorer::Node *node) const final; void updateTarget(); Utils::FileName m_proFilePath; // Full path to the Application Pro File @@ -131,7 +130,7 @@ private: QLineEdit *m_qmlDebugPort = nullptr; }; -class DesktopQmakeRunConfigurationFactory : public QmakeRunConfigurationFactory +class DesktopQmakeRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory { Q_OBJECT @@ -142,8 +141,6 @@ public: QList availableCreators(ProjectExplorer::Target *parent) const override; - - bool hasRunConfigForProFile(ProjectExplorer::RunConfiguration *rc, const Utils::FileName &n) const override; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 787dc4304d6..5d71c39c64f 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -25,7 +25,6 @@ #include "qmakenodes.h" #include "qmakeproject.h" -#include "qmakerunconfigurationfactory.h" #include #include @@ -38,26 +37,6 @@ using namespace Utils; namespace QmakeProjectManager { -static QList qmakeRunConfigurationsForNode(Target *t, const Node *node) -{ - QList result; - if (!t) - return result; // Project was not set up yet. - - const FileName file = node->filePath(); - for (auto factory : RunConfigurationFactory::allRunConfigurationFactories()) { - if (auto qmakeFactory = qobject_cast(factory)) { - if (qmakeFactory->canHandle(t)) { - result.append(Utils::filtered(t->runConfigurations(), [qmakeFactory, file](RunConfiguration *rc) { - return qmakeFactory->hasRunConfigForProFile(rc, file); - })); - } - } - } - - return result; -} - /*! \class QmakePriFileNode Implements abstract ProjectNode class @@ -86,11 +65,6 @@ bool QmakePriFileNode::deploysFolder(const QString &folder) const return pri ? pri->deploysFolder(folder) : false; } -QList QmakePriFileNode::runConfigurations() const -{ - return qmakeRunConfigurationsForNode(m_project->activeTarget(), this); -} - QmakeProFileNode *QmakePriFileNode::proFileNode() const { return m_qmakeProFileNode; @@ -157,7 +131,11 @@ bool QmakePriFileNode::supportsAction(ProjectAction action, const Node *node) co } if (action == HasSubProjectRunConfigurations) { - return !qmakeRunConfigurationsForNode(m_project->activeTarget(), node).isEmpty(); + if (Target *t = m_project->activeTarget()) { + auto canRunForNode = [node](RunConfiguration *rc) { return rc->canRunForNode(node); }; + if (Utils::anyOf(t->runConfigurations(), canRunForNode)) + return true; + } } return false; diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index 56a2b6be622..57f1b7bec84 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -64,7 +64,6 @@ public: AddNewInformation addNewInformation(const QStringList &files, Node *context) const override; bool deploysFolder(const QString &folder) const override; - QList runConfigurations() const override; QmakeProFileNode *proFileNode() const; diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 4c47e34d2f2..6a62d98fb9a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -28,7 +28,6 @@ #include "qmakeproject.h" #include "qmakeprojectmanagerconstants.h" #include "qmakebuildconfiguration.h" -#include "qmakerunconfigurationfactory.h" #include #include diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro index 765b12b515a..d2da5d86b94 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro @@ -10,7 +10,6 @@ HEADERS += \ qmakekitconfigwidget.h \ qmakeparsernodes.h \ qmakeprojectimporter.h \ - qmakerunconfigurationfactory.h \ qmakeprojectmanagerplugin.h \ qmakeprojectmanager.h \ qmakeproject.h \ @@ -51,7 +50,6 @@ SOURCES += \ qmakekitinformation.cpp \ qmakeparsernodes.cpp \ qmakeprojectimporter.cpp \ - qmakerunconfigurationfactory.cpp \ qmakeprojectmanagerplugin.cpp \ qmakeprojectmanager.cpp \ qmakeproject.cpp \ diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs index 829d1eb4934..ddeeb8c53a2 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs @@ -42,7 +42,6 @@ Project { "qmakeparser.cpp", "qmakeparser.h", "qmakeparsernodes.cpp", "qmakeparsernodes.h", "qmakeprojectimporter.cpp", "qmakeprojectimporter.h", - "qmakerunconfigurationfactory.cpp", "qmakerunconfigurationfactory.h", "qmakestep.cpp", "qmakestep.h", "qmakestep.ui", "qmakebuildconfiguration.cpp", "qmakebuildconfiguration.h", "qmakenodes.cpp", "qmakenodes.h", diff --git a/src/plugins/qmakeprojectmanager/qmakerunconfigurationfactory.cpp b/src/plugins/qmakeprojectmanager/qmakerunconfigurationfactory.cpp deleted file mode 100644 index 2c100d122eb..00000000000 --- a/src/plugins/qmakeprojectmanager/qmakerunconfigurationfactory.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/**************************************************************************** -** -** 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 "qmakerunconfigurationfactory.h" - -namespace QmakeProjectManager { - -QmakeRunConfigurationFactory::QmakeRunConfigurationFactory() -{ } - -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakerunconfigurationfactory.h b/src/plugins/qmakeprojectmanager/qmakerunconfigurationfactory.h deleted file mode 100644 index 6a9ebe842f9..00000000000 --- a/src/plugins/qmakeprojectmanager/qmakerunconfigurationfactory.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "qmakeprojectmanager_global.h" - -#include - -namespace Utils { class FileName; } - -namespace QmakeProjectManager { - -class QMAKEPROJECTMANAGER_EXPORT QmakeRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory -{ - Q_OBJECT - -public: - QmakeRunConfigurationFactory(); - - virtual bool hasRunConfigForProFile(ProjectExplorer::RunConfiguration *rc, const Utils::FileName &n) const = 0; -}; - -} // namespace QmakeProjectManager