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 <tobias.hunger@qt.io>
This commit is contained in:
hjk
2018-03-14 14:40:47 +01:00
parent e3918b563f
commit e20d620043
22 changed files with 42 additions and 175 deletions

View File

@@ -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();

View File

@@ -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;

View File

@@ -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<IosRunConfiguration *>(rc);
return iosRc && iosRc->profilePath() == n;
}
} // namespace Internal
} // namespace Ios

View File

@@ -26,17 +26,11 @@
#pragma once
#include <projectexplorer/runconfiguration.h>
#include <qmakeprojectmanager/qmakerunconfigurationfactory.h>
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<ProjectExplorer::RunConfigurationCreationInfo>
availableCreators(ProjectExplorer::Target *parent) const override;
bool hasRunConfigForProFile(ProjectExplorer::RunConfiguration *rc, const Utils::FileName &n) const override;
};
} // namespace Internal

View File

@@ -2969,10 +2969,17 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
pn = const_cast<ProjectNode*>(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<RunConfiguration *> runConfigs = pn->runConfigurations();
QList<RunConfiguration *> 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()));

View File

@@ -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<RunConfiguration *> ProjectNode::runConfigurations() const
{
return QList<RunConfiguration *>();
}
ProjectNode *ProjectNode::projectNode(const Utils::FileName &file) const
{
for (Node *node : m_nodes) {

View File

@@ -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<RunConfiguration *> runConfigurations() const;
ProjectNode *projectNode(const Utils::FileName &file) const;
ProjectNode *asProjectNode() final { return this; }

View File

@@ -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<IRunConfigurationAspect *(RunConfiguration *)>;
template <class T> static void registerAspect()

View File

@@ -429,24 +429,6 @@ bool QbsProductNode::renameFile(const QString &filePath, const QString &newFileP
return prjNode->project()->renameFileInProduct(filePath, newFilePath, m_qbsProductData, grp);
}
QList<ProjectExplorer::RunConfiguration *> QbsProductNode::runConfigurations() const
{
QList<ProjectExplorer::RunConfiguration *> result;
auto pn = dynamic_cast<const QbsProjectNode *>(managingProject());
if (!isEnabled() || !pn || m_qbsProductData.targetExecutable().isEmpty())
return result;
foreach (ProjectExplorer::RunConfiguration *rc, pn->project()->activeTarget()->runConfigurations()) {
QbsRunConfiguration *qbsRc = qobject_cast<QbsRunConfiguration *>(rc);
if (!qbsRc)
continue;
if (qbsRc->uniqueProductName() == QbsProject::uniqueProductName(qbsProductData()))
result << qbsRc;
}
return result;
}
// --------------------------------------------------------------------
// QbsProjectNode:
// --------------------------------------------------------------------

View File

@@ -110,8 +110,6 @@ public:
const qbs::ProductData qbsProductData() const { return m_qbsProductData; }
QList<ProjectExplorer::RunConfiguration *> runConfigurations() const override;
private:
const qbs::ProductData m_qbsProductData;
};

View File

@@ -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
{

View File

@@ -25,7 +25,9 @@
#include "qbsrunconfiguration.h"
#include "qbsnodes.h"
#include "qbsprojectmanagerconstants.h"
#include "qbsproject.h"
#include <coreplugin/messagemanager.h>
#include <coreplugin/variablechooser.h>
@@ -304,6 +306,14 @@ void QbsRunConfiguration::handleBuildSystemDataUpdated()
emit enabledChanged();
}
bool QbsRunConfiguration::canRunForNode(const Node *node) const
{
if (auto pn = dynamic_cast<const QbsProductNode *>(node))
return m_uniqueProductName == QbsProject::uniqueProductName(pn->qbsProductData());
return false;
}
// --------------------------------------------------------------------
// QbsRunConfigurationFactory:
// --------------------------------------------------------------------

View File

@@ -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();

View File

@@ -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<QmakeProject *>(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<DesktopQmakeRunConfiguration *>(rc);
return qmakeRc && qmakeRc->proFilePath() == n;
}
} // namespace Internal
} // namespace QmakeProjectManager

View File

@@ -25,8 +25,7 @@
#pragma once
#include <qmakeprojectmanager/qmakerunconfigurationfactory.h>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runnables.h>
#include <utils/fileutils.h>
@@ -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<ProjectExplorer::RunConfigurationCreationInfo>
availableCreators(ProjectExplorer::Target *parent) const override;
bool hasRunConfigForProFile(ProjectExplorer::RunConfiguration *rc, const Utils::FileName &n) const override;
};
} // namespace Internal

View File

@@ -25,7 +25,6 @@
#include "qmakenodes.h"
#include "qmakeproject.h"
#include "qmakerunconfigurationfactory.h"
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/target.h>
@@ -38,26 +37,6 @@ using namespace Utils;
namespace QmakeProjectManager {
static QList<RunConfiguration *> qmakeRunConfigurationsForNode(Target *t, const Node *node)
{
QList<RunConfiguration *> 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<QmakeRunConfigurationFactory *>(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<RunConfiguration *> 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;

View File

@@ -64,7 +64,6 @@ public:
AddNewInformation addNewInformation(const QStringList &files, Node *context) const override;
bool deploysFolder(const QString &folder) const override;
QList<ProjectExplorer::RunConfiguration *> runConfigurations() const override;
QmakeProFileNode *proFileNode() const;

View File

@@ -28,7 +28,6 @@
#include "qmakeproject.h"
#include "qmakeprojectmanagerconstants.h"
#include "qmakebuildconfiguration.h"
#include "qmakerunconfigurationfactory.h"
#include <coreplugin/dialogs/readonlyfilesdialog.h>
#include <coreplugin/documentmanager.h>

View File

@@ -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 \

View File

@@ -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",

View File

@@ -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

View File

@@ -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 <projectexplorer/runconfiguration.h>
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