aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/projectexplorer
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2017-11-29 12:28:40 +0100
committerhjk <hjk@qt.io>2017-12-08 11:17:55 +0000
commit53a151074ad37d12e730fbd85ec0e0675d00f6d0 (patch)
tree041526d48608270cad2db171696fa6cf7099a852 /src/plugins/projectexplorer
parent9d3c5c6ff5ba059f036efae5fd9572fe454b5d84 (diff)
ProjectExplorer/all: Re-organize BuildSteps/{Deploy,Build}Config setup
This follow the rough pattern of recent *RunConfigurationFactory changes for build and deploy configurations. - Collapse the two lines of constructors similar to what 890c1906e6fb2ec did for RunConfigurations * Deploy* was purely mechanical * Build* ctors are split in connects() in the ctor body to create "empty shell for clone" etc and build step additions in initialize() functions which are only used in the create() case. -- Allows to collapse the shared 'ctor()' functions, too. - Move FooBuildConfigurationFactory::create() implementations to FooBuildConfiguration() constructor. That was a strange and unneeded ping-pong between factories and objects, and furthermore allows one level less of indirection (and for a later, left out here, some reduction of the FooBuildConfiguration interfaces that were only used to accommodate the *Factory::create() functions. - Most {Build,Deploy}Configuration{,Factory} classes had a canHandle(), but there wasn't one in the base classses. Have one there. - Most canHandle() functions were checking simple restrictions on e.g. project or target types, specify those by setters in the constructors instead and check them in the base canHandle() - clone() is generally replaced by a creation of a "shell object" and a fromMap(source->toMap()), implemented in the base, there are two cases left for Android and Qbs that needed(?) some extra polish - generally use canHandle() in base implementation, instead of doing that in all Derived::canFoo() - as a result, canCreate/create/canClone/clone reimplementations are not needed anymore, keep the base implementation for now (could be inlined into their only users later), but de-virtualize them. - Combine Ios{Preset,DSym}BuildStepFactory. There was only one 'dsym' build step they could create. - Split the 'mangled' id into the ProjectConfiguration subtype specific constant identifier, and a QString extraId() bit. Only maintain the mangled id in saved settings. - Make ProjectConfiguration::m_id a constant member, adapt all constructors of derived classe. Not done in this patch: - Finish possible cosmetic changes on top - Add a way to specify restrictions to supported Qt versions (used in Android/Ios), as the base implementation does not depend on the qtsupport plugin - Combine the QList<X> availableFoo() + createFoo(X) function pairs to somthing like a direct QList<struct { X; std::function<X()>; }> fooCreators() to avoid e.g. the baseId.withSuffix() <-> id.suffixAfter(base) pingpong - Remove the *Factories from the global object pool - Do something about priority(). Falling back to plain qmake in android+qmake setup is not helpful. Change-Id: I2be7d88d554c5aa8b7db8edf5b93278e1ae0112a Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/plugins/projectexplorer')
-rw-r--r--src/plugins/projectexplorer/abstractprocessstep.cpp5
-rw-r--r--src/plugins/projectexplorer/abstractprocessstep.h1
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.cpp189
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.h61
-rw-r--r--src/plugins/projectexplorer/buildstep.cpp157
-rw-r--r--src/plugins/projectexplorer/buildstep.h68
-rw-r--r--src/plugins/projectexplorer/buildsteplist.cpp77
-rw-r--r--src/plugins/projectexplorer/buildsteplist.h6
-rw-r--r--src/plugins/projectexplorer/buildstepspage.cpp14
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.cpp13
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.h6
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.cpp262
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.h97
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp10
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h3
-rw-r--r--src/plugins/projectexplorer/processstep.cpp36
-rw-r--r--src/plugins/projectexplorer/processstep.h16
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.cpp46
-rw-r--r--src/plugins/projectexplorer/projectconfiguration.h20
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp76
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h33
-rw-r--r--src/plugins/projectexplorer/runsettingspropertiespage.cpp16
-rw-r--r--src/plugins/projectexplorer/target.cpp59
23 files changed, 723 insertions, 548 deletions
diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp
index 563cc4f97b..bfd7f0ef1d 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.cpp
+++ b/src/plugins/projectexplorer/abstractprocessstep.cpp
@@ -89,11 +89,6 @@ AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl, Core::Id id) :
connect(&m_timer, &QTimer::timeout, this, &AbstractProcessStep::checkForCancel);
}
-AbstractProcessStep::AbstractProcessStep(BuildStepList *bsl,
- AbstractProcessStep *bs) :
- BuildStep(bsl, bs), m_ignoreReturnValue(bs->m_ignoreReturnValue)
-{ }
-
/*!
Deletes all existing output parsers and starts a new chain with the
given parser.
diff --git a/src/plugins/projectexplorer/abstractprocessstep.h b/src/plugins/projectexplorer/abstractprocessstep.h
index d94734469a..1117996506 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.h
+++ b/src/plugins/projectexplorer/abstractprocessstep.h
@@ -65,7 +65,6 @@ public:
protected:
AbstractProcessStep(BuildStepList *bsl, Core::Id id);
- AbstractProcessStep(BuildStepList *bsl, AbstractProcessStep *bs);
virtual void processStarted();
virtual void processFinished(int exitCode, QProcess::ExitStatus status);
diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp
index 44f883f454..b1556595de 100644
--- a/src/plugins/projectexplorer/buildconfiguration.cpp
+++ b/src/plugins/projectexplorer/buildconfiguration.cpp
@@ -25,6 +25,7 @@
#include "buildconfiguration.h"
+#include "buildinfo.h"
#include "buildsteplist.h"
#include "projectexplorer.h"
#include "kitmanager.h"
@@ -43,6 +44,8 @@
#include <utils/qtcassert.h>
#include <utils/macroexpander.h>
#include <utils/algorithm.h>
+#include <utils/mimetypes/mimetype.h>
+#include <utils/mimetypes/mimedatabase.h>
#include <QDebug>
@@ -54,57 +57,13 @@ static const char BUILDDIRECTORY_KEY[] = "ProjectExplorer.BuildConfiguration.Bui
namespace ProjectExplorer {
-BuildConfiguration::BuildConfiguration(Target *target, Core::Id id) :
- ProjectConfiguration(target),
- m_clearSystemEnvironment(false)
-{
- initialize(id);
- Q_ASSERT(target);
- auto bsl = new BuildStepList(this, Core::Id(Constants::BUILDSTEPS_BUILD));
- //: Display name of the build build step list. Used as part of the labels in the project window.
- bsl->setDefaultDisplayName(tr("Build"));
- m_stepLists.append(bsl);
- bsl = new BuildStepList(this, Core::Id(Constants::BUILDSTEPS_CLEAN));
- //: Display name of the clean build step list. Used as part of the labels in the project window.
- bsl->setDefaultDisplayName(tr("Clean"));
- m_stepLists.append(bsl);
-
- updateCacheAndEmitEnvironmentChanged();
-
- connect(target, &Target::kitChanged,
- this, &BuildConfiguration::handleKitUpdate);
- connect(this, &BuildConfiguration::environmentChanged,
- this, &BuildConfiguration::emitBuildDirectoryChanged);
-
- ctor();
-}
-
-BuildConfiguration::BuildConfiguration(Target *target, BuildConfiguration *source) :
- ProjectConfiguration(target),
- m_clearSystemEnvironment(source->m_clearSystemEnvironment),
- m_userEnvironmentChanges(source->m_userEnvironmentChanges),
- m_buildDirectory(source->m_buildDirectory)
-{
- copyFrom(source);
- Q_ASSERT(target);
- // Do not clone stepLists here, do that in the derived constructor instead
- // otherwise BuildStepFactories might reject to set up a BuildStep for us
- // since we are not yet the derived class!
-
- updateCacheAndEmitEnvironmentChanged();
-
- connect(target, &Target::kitChanged,
- this, &BuildConfiguration::handleKitUpdate);
-
- ctor();
-}
-
-void BuildConfiguration::ctor()
+BuildConfiguration::BuildConfiguration(Target *target, Core::Id id)
+ : ProjectConfiguration(target, id)
{
Utils::MacroExpander *expander = macroExpander();
expander->setDisplayName(tr("Build Settings"));
expander->setAccumulating(true);
- expander->registerSubProvider([this] { return target()->macroExpander(); });
+ expander->registerSubProvider([target] { return target->macroExpander(); });
expander->registerVariable("buildDir", tr("Build directory"),
[this] { return buildDirectory().toUserOutput(); });
@@ -115,6 +74,12 @@ void BuildConfiguration::ctor()
expander->registerPrefix(Constants::VAR_CURRENTBUILD_ENV,
tr("Variables in the current build environment"),
[this](const QString &var) { return environment().value(var); });
+
+ updateCacheAndEmitEnvironmentChanged();
+ connect(target, &Target::kitChanged,
+ this, &BuildConfiguration::handleKitUpdate);
+ connect(this, &BuildConfiguration::environmentChanged,
+ this, &BuildConfiguration::emitBuildDirectoryChanged);
}
Utils::FileName BuildConfiguration::buildDirectory() const
@@ -136,6 +101,16 @@ void BuildConfiguration::setBuildDirectory(const Utils::FileName &dir)
emitBuildDirectoryChanged();
}
+void BuildConfiguration::initialize(const BuildInfo *info)
+{
+ setDisplayName(info->displayName);
+ setDefaultDisplayName(info->displayName);
+ setBuildDirectory(info->buildDirectory);
+
+ m_stepLists.append(new BuildStepList(this, Constants::BUILDSTEPS_BUILD));
+ m_stepLists.append(new BuildStepList(this, Constants::BUILDSTEPS_CLEAN));
+}
+
QList<NamedWidget *> BuildConfiguration::createSubConfigWidgets()
{
return QList<NamedWidget *>() << new BuildEnvironmentWidget(this);
@@ -183,16 +158,12 @@ bool BuildConfiguration::fromMap(const QVariantMap &map)
qWarning() << "No data for build step list" << i << "found!";
continue;
}
- auto list = new BuildStepList(this, Core::Id());
+ auto list = new BuildStepList(this, idFromMap(data));
if (!list->fromMap(data)) {
qWarning() << "Failed to restore build step list" << i;
delete list;
return false;
}
- if (list->id() == Constants::BUILDSTEPS_BUILD)
- list->setDefaultDisplayName(tr("Build"));
- else if (list->id() == Constants::BUILDSTEPS_CLEAN)
- list->setDefaultDisplayName(tr("Clean"));
m_stepLists.append(list);
}
@@ -290,19 +261,6 @@ void BuildConfiguration::setUserEnvironmentChanges(const QList<Utils::Environmen
updateCacheAndEmitEnvironmentChanged();
}
-void BuildConfiguration::cloneSteps(BuildConfiguration *source)
-{
- if (source == this)
- return;
- qDeleteAll(m_stepLists);
- m_stepLists.clear();
- foreach (BuildStepList *bsl, source->m_stepLists) {
- auto newBsl = new BuildStepList(this, bsl);
- newBsl->cloneSteps(bsl);
- m_stepLists.append(newBsl);
- }
-}
-
bool BuildConfiguration::isEnabled() const
{
return true;
@@ -360,12 +318,18 @@ void BuildConfiguration::prependCompilerPathToEnvironment(Kit *k, Utils::Environ
// IBuildConfigurationFactory
///
-IBuildConfigurationFactory::IBuildConfigurationFactory(QObject *parent) :
- QObject(parent)
-{ }
+int IBuildConfigurationFactory::priority(const Target *parent) const
+{
+ return canHandle(parent) ? 0 : -1;
+}
-IBuildConfigurationFactory::~IBuildConfigurationFactory()
-{ }
+int IBuildConfigurationFactory::priority(const Kit *k, const QString &projectPath) const
+{
+ QTC_ASSERT(!m_supportedProjectMimeTypeName.isEmpty(), return -1);
+ if (k && Utils::mimeTypeForFile(projectPath).matchesName(m_supportedProjectMimeTypeName))
+ return 0;
+ return -1;
+}
// restore
IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, const QVariantMap &map)
@@ -442,4 +406,89 @@ IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, Bui
}
return factory;
}
+
+void IBuildConfigurationFactory::setSupportedProjectType(Core::Id id)
+{
+ m_supportedProjectType = id;
+}
+
+void IBuildConfigurationFactory::setSupportedProjectMimeTypeName(const QString &mimeTypeName)
+{
+ m_supportedProjectMimeTypeName = mimeTypeName;
+}
+
+void IBuildConfigurationFactory::setSupportedTargetDeviceTypes(const QList<Core::Id> &ids)
+{
+ m_supportedTargetDeviceTypes = ids;
+}
+
+bool IBuildConfigurationFactory::canHandle(const Target *target) const
+{
+ if (m_supportedProjectType.isValid() && m_supportedProjectType != target->project()->id())
+ return false;
+
+ if (!target->project()->supportsKit(target->kit()))
+ return false;
+
+ if (!m_supportedTargetDeviceTypes.isEmpty())
+ if (!m_supportedTargetDeviceTypes.contains(
+ DeviceTypeKitInformation::deviceTypeId(target->kit())))
+ return false;
+
+ return true;
+}
+
+BuildConfiguration *IBuildConfigurationFactory::create(Target *parent, const BuildInfo *info) const
+{
+ if (!canHandle(parent))
+ return nullptr;
+ QTC_ASSERT(m_creator, return nullptr);
+ BuildConfiguration *bc = m_creator(parent);
+ if (!bc)
+ return nullptr;
+ bc->initialize(info);
+ return bc;
+}
+
+bool IBuildConfigurationFactory::canClone(const Target *parent, BuildConfiguration *product) const
+{
+ if (!canHandle(parent))
+ return false;
+ const Core::Id id = product->id();
+ return id == m_buildConfigId;
+}
+
+BuildConfiguration *IBuildConfigurationFactory::restore(Target *parent, const QVariantMap &map)
+{
+ if (!canRestore(parent, map))
+ return nullptr;
+ QTC_ASSERT(m_creator, return nullptr);
+ BuildConfiguration *bc = m_creator(parent);
+ QTC_ASSERT(bc, return nullptr);
+ if (!bc->fromMap(map)) {
+ delete bc;
+ bc = nullptr;
+ }
+ return bc;
+}
+
+bool IBuildConfigurationFactory::canRestore(const Target *parent, const QVariantMap &map) const
+{
+ if (!canHandle(parent))
+ return false;
+ const Core::Id id = idFromMap(map);
+ return id.name().startsWith(m_buildConfigId.name());
+}
+
+BuildConfiguration *IBuildConfigurationFactory::clone(Target *parent, BuildConfiguration *product)
+{
+ QTC_ASSERT(m_creator, return nullptr);
+ if (!canClone(parent, product))
+ return nullptr;
+ BuildConfiguration *bc = m_creator(parent);
+ QVariantMap data = product->toMap();
+ bc->fromMap(data);
+ return bc;
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h
index 08307eae58..3bc718fd51 100644
--- a/src/plugins/projectexplorer/buildconfiguration.h
+++ b/src/plugins/projectexplorer/buildconfiguration.h
@@ -33,7 +33,6 @@
namespace ProjectExplorer {
-class BuildConfiguration;
class BuildInfo;
class NamedWidget;
class BuildStepList;
@@ -45,9 +44,11 @@ class PROJECTEXPLORER_EXPORT BuildConfiguration : public ProjectConfiguration
{
Q_OBJECT
-public:
- // ctors are protected
+protected:
+ friend class IBuildConfigurationFactory;
+ explicit BuildConfiguration(Target *target, Core::Id id);
+public:
Utils::FileName buildDirectory() const;
Utils::FileName rawBuildDirectory() const;
void setBuildDirectory(const Utils::FileName &dir);
@@ -100,19 +101,14 @@ signals:
void buildTypeChanged();
protected:
- BuildConfiguration(Target *target, Core::Id id);
- BuildConfiguration(Target *target, BuildConfiguration *source);
-
- void cloneSteps(BuildConfiguration *source);
+ virtual void initialize(const BuildInfo *info);
void updateCacheAndEmitEnvironmentChanged();
private:
void handleKitUpdate();
void emitBuildDirectoryChanged();
- void ctor();
-
- bool m_clearSystemEnvironment;
+ bool m_clearSystemEnvironment = false;
QList<Utils::EnvironmentItem> m_userEnvironmentChanges;
QList<BuildStepList *> m_stepLists;
Utils::FileName m_buildDirectory;
@@ -124,37 +120,62 @@ class PROJECTEXPLORER_EXPORT IBuildConfigurationFactory : public QObject
{
Q_OBJECT
-public:
- explicit IBuildConfigurationFactory(QObject *parent = nullptr);
- ~IBuildConfigurationFactory() override;
+protected:
+ IBuildConfigurationFactory() = default;
+public:
// The priority is negative if this factory can not create anything for the target.
// It is 0 for the "default" factory that wants to handle the target.
// Add 100 for each specialization.
- virtual int priority(const Target *parent) const = 0;
+ virtual int priority(const Target *parent) const;
// List of build information that can be used to create a new build configuration via
// "Add Build Configuration" button.
virtual QList<BuildInfo *> availableBuilds(const Target *parent) const = 0;
- virtual int priority(const Kit *k, const QString &projectPath) const = 0;
+ virtual int priority(const Kit *k, const QString &projectPath) const;
// List of build information that can be used to initially set up a new build configuration.
virtual QList<BuildInfo *> availableSetups(const Kit *k, const QString &projectPath) const = 0;
- virtual BuildConfiguration *create(Target *parent, const BuildInfo *info) const = 0;
+ BuildConfiguration *create(Target *parent, const BuildInfo *info) const;
// used to recreate the runConfigurations when restoring settings
- virtual bool canRestore(const Target *parent, const QVariantMap &map) const = 0;
- virtual BuildConfiguration *restore(Target *parent, const QVariantMap &map) = 0;
- virtual bool canClone(const Target *parent, BuildConfiguration *product) const = 0;
- virtual BuildConfiguration *clone(Target *parent, BuildConfiguration *product) = 0;
+ bool canRestore(const Target *parent, const QVariantMap &map) const;
+ BuildConfiguration *restore(Target *parent, const QVariantMap &map);
+ bool canClone(const Target *parent, BuildConfiguration *product) const;
+ BuildConfiguration *clone(Target *parent, BuildConfiguration *product);
static IBuildConfigurationFactory *find(Target *parent, const QVariantMap &map);
static IBuildConfigurationFactory *find(const Kit *k, const QString &projectPath);
static IBuildConfigurationFactory *find(Target *parent);
static IBuildConfigurationFactory *find(Target *parent, BuildConfiguration *bc);
+ virtual bool canHandle(const ProjectExplorer::Target *t) const;
+
+protected:
+ void setSupportedProjectType(Core::Id id);
+ void setSupportedProjectMimeTypeName(const QString &mimeTypeName);
+ void setSupportedTargetDeviceTypes(const QList<Core::Id> &ids);
+ void setDefaultDisplayName(const QString &defaultDisplayName);
+
+ using BuildConfigurationCreator = std::function<BuildConfiguration *(Target *)>;
+
+ template <class BuildConfig>
+ void registerBuildConfiguration(Core::Id buildConfigId)
+ {
+ setObjectName(buildConfigId.toString() + "BuildConfigurationFactory");
+ m_creator = [](Target *t) { return new BuildConfig(t); };
+ m_buildConfigId = buildConfigId;
+ }
+
signals:
void availableCreationIdsChanged();
+
+private:
+ BuildConfigurationCreator m_creator;
+ Core::Id m_buildConfigId;
+ Core::Id m_supportedProjectType;
+ QList<Core::Id> m_supportedTargetDeviceTypes;
+ QString m_supportedProjectMimeTypeName;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildstep.cpp b/src/plugins/projectexplorer/buildstep.cpp
index 40c31f0c9f..ff2bf2bf3f 100644
--- a/src/plugins/projectexplorer/buildstep.cpp
+++ b/src/plugins/projectexplorer/buildstep.cpp
@@ -28,9 +28,12 @@
#include "buildconfiguration.h"
#include "buildsteplist.h"
#include "deployconfiguration.h"
+#include "kitinformation.h"
+#include "project.h"
#include "target.h"
#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
/*!
\class ProjectExplorer::BuildStep
@@ -109,26 +112,10 @@
static const char buildStepEnabledKey[] = "ProjectExplorer.BuildStep.Enabled";
-using namespace ProjectExplorer;
+namespace ProjectExplorer {
BuildStep::BuildStep(BuildStepList *bsl, Core::Id id) :
- ProjectConfiguration(bsl), m_enabled(true)
-{
- initialize(id);
- Q_ASSERT(bsl);
- ctor();
-}
-
-BuildStep::BuildStep(BuildStepList *bsl, BuildStep *bs) :
- ProjectConfiguration(bsl), m_enabled(bs->m_enabled)
-{
- copyFrom(bs);
- Q_ASSERT(bsl);
- setDisplayName(bs->displayName());
- ctor();
-}
-
-void BuildStep::ctor()
+ ProjectConfiguration(bsl, id)
{
Utils::MacroExpander *expander = macroExpander();
expander->setDisplayName(tr("Build Step"));
@@ -225,17 +212,133 @@ bool BuildStep::enabled() const
return m_enabled;
}
-IBuildStepFactory::IBuildStepFactory(QObject *parent) :
- QObject(parent)
+BuildStepFactory::BuildStepFactory()
{ }
-BuildStep *IBuildStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
+bool BuildStepFactory::canHandle(BuildStepList *bsl) const
+{
+ if (!m_supportedStepLists.isEmpty() && !m_supportedStepLists.contains(bsl->id()))
+ return false;
+
+ auto config = qobject_cast<ProjectConfiguration *>(bsl->parent());
+
+ if (!m_supportedDeviceTypes.isEmpty()) {
+ Target *target = bsl->target();
+ QTC_ASSERT(target, return false);
+ Core::Id deviceType = DeviceTypeKitInformation::deviceTypeId(target->kit());
+ if (!m_supportedDeviceTypes.contains(deviceType))
+ return false;
+ }
+
+ if (m_supportedProjectType.isValid()) {
+ if (!config)
+ return false;
+ Core::Id projectId = config->project()->id();
+ if (projectId != m_supportedProjectType)
+ return false;
+ }
+
+ if (!m_isRepeatable && bsl->contains(m_info.id))
+ return false;
+
+ if (m_supportedConfiguration.isValid()) {
+ if (!config)
+ return false;
+ Core::Id configId = config->id();
+ if (configId != m_supportedConfiguration)
+ return false;
+ }
+
+ return true;
+}
+
+void BuildStepFactory::setDisplayName(const QString &displayName)
+{
+ m_info.displayName = displayName;
+}
+
+void BuildStepFactory::setFlags(BuildStepInfo::Flags flags)
+{
+ m_info.flags = flags;
+}
+
+void BuildStepFactory::setSupportedStepList(Core::Id id)
+{
+ m_supportedStepLists = {id};
+}
+
+void BuildStepFactory::setSupportedStepLists(const QList<Core::Id> &ids)
+{
+ m_supportedStepLists = ids;
+}
+
+void BuildStepFactory::setSupportedConfiguration(Core::Id id)
+{
+ m_supportedConfiguration = id;
+}
+
+void BuildStepFactory::setSupportedProjectType(Core::Id id)
+{
+ m_supportedProjectType = id;
+}
+
+void BuildStepFactory::setSupportedDeviceType(Core::Id id)
+{
+ m_supportedDeviceTypes = {id};
+}
+
+void BuildStepFactory::setSupportedDeviceTypes(const QList<Core::Id> &ids)
+{
+ m_supportedDeviceTypes = ids;
+}
+
+BuildStepInfo BuildStepFactory::stepInfo() const
+{
+ return m_info;
+}
+
+Core::Id BuildStepFactory::stepId() const
+{
+ return m_info.id;
+}
+
+BuildStep *BuildStepFactory::create(BuildStepList *parent, Core::Id id)
+{
+ BuildStep *bs = nullptr;
+ if (id == m_info.id)
+ bs = m_info.creator(parent);
+ return bs;
+}
+
+BuildStep *BuildStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
+{
+ BuildStep *bs = m_info.creator(parent);
+ if (!bs)
+ return nullptr;
+ if (!bs->fromMap(map)) {
+ QTC_CHECK(false);
+ delete bs;
+ return nullptr;
+ }
+ return bs;
+}
+
+BuildStep *BuildStepFactory::clone(BuildStepList *parent, BuildStep *product)
{
- const Core::Id id = idFromMap(map);
- BuildStep *bs = create(parent, id);
- if (bs->fromMap(map))
- return bs;
- delete bs;
- return nullptr;
+ if ((m_info.flags & BuildStepInfo::Unclonable) != 0)
+ return nullptr;
+ if (m_info.id != product->id())
+ return nullptr;
+ BuildStep *bs = m_info.creator(parent);
+ if (!bs)
+ return nullptr;
+ const QVariantMap map = product->toMap();
+ if (!bs->fromMap(map)) {
+ QTC_CHECK(false);
+ delete bs;
+ return nullptr;
+ }
+ return bs;
}
+} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h
index 2fe6ee1960..adc9192060 100644
--- a/src/plugins/projectexplorer/buildstep.h
+++ b/src/plugins/projectexplorer/buildstep.h
@@ -28,17 +28,20 @@
#include "projectconfiguration.h"
#include "projectexplorer_export.h"
+#include <utils/qtcassert.h>
+
#include <QFutureInterface>
#include <QWidget>
namespace ProjectExplorer {
-class Task;
+
class BuildConfiguration;
+class BuildStepConfigWidget;
+class BuildStepFactory;
class BuildStepList;
class DeployConfiguration;
class Target;
-
-class BuildStepConfigWidget;
+class Task;
// Documentation inside.
class PROJECTEXPLORER_EXPORT BuildStep : public ProjectConfiguration
@@ -46,14 +49,12 @@ class PROJECTEXPLORER_EXPORT BuildStep : public ProjectConfiguration
Q_OBJECT
protected:
- BuildStep(BuildStepList *bsl, Core::Id id);
- BuildStep(BuildStepList *bsl, BuildStep *bs);
+ friend class BuildStepFactory;
+ explicit BuildStep(BuildStepList *bsl, Core::Id id);
public:
virtual bool init(QList<const BuildStep *> &earlierSteps) = 0;
-
virtual void run(QFutureInterface<bool> &fi) = 0;
-
virtual BuildStepConfigWidget *createConfigWidget() = 0;
virtual bool immutable() const;
@@ -97,8 +98,6 @@ signals:
void enabledChanged();
private:
- void ctor();
-
bool m_enabled = true;
};
@@ -111,27 +110,58 @@ public:
UniqueStep = 1 << 8 // Can't be used twice in a BuildStepList
};
- BuildStepInfo() {}
- BuildStepInfo(Core::Id id, const QString &displayName, Flags flags = Flags())
- : id(id), displayName(displayName), flags(flags)
- {}
+ using BuildStepCreator = std::function<BuildStep *(BuildStepList *)>;
Core::Id id;
QString displayName;
Flags flags = Flags();
+ BuildStepCreator creator;
};
-class PROJECTEXPLORER_EXPORT IBuildStepFactory : public QObject
+class PROJECTEXPLORER_EXPORT BuildStepFactory : public QObject
{
Q_OBJECT
public:
- explicit IBuildStepFactory(QObject *parent = nullptr);
+ BuildStepFactory();
+
+ BuildStepInfo stepInfo() const;
+ Core::Id stepId() const;
+ BuildStep *create(BuildStepList *parent, Core::Id id);
+ BuildStep *restore(BuildStepList *parent, const QVariantMap &map);
+ BuildStep *clone(BuildStepList *parent, BuildStep *product);
+
+ virtual bool canHandle(BuildStepList *bsl) const;
+
+protected:
+ using BuildStepCreator = std::function<BuildStep *(BuildStepList *)>;
+
+ template <class BuildStepType>
+ void registerStep(Core::Id id)
+ {
+ QTC_CHECK(!m_info.creator);
+ m_info.id = id;
+ m_info.creator = [](BuildStepList *bsl) { return new BuildStepType(bsl); };
+ }
+
+ void setSupportedStepList(Core::Id id);
+ void setSupportedStepLists(const QList<Core::Id> &ids);
+ void setSupportedConfiguration(Core::Id id);
+ void setSupportedProjectType(Core::Id id);
+ void setSupportedDeviceType(Core::Id id);
+ void setSupportedDeviceTypes(const QList<Core::Id> &ids);
+ void setRepeatable(bool on) { m_isRepeatable = on; }
+ void setDisplayName(const QString &displayName);
+ void setFlags(BuildStepInfo::Flags flags);
+
+private:
+ BuildStepInfo m_info;
- virtual QList<BuildStepInfo> availableSteps(BuildStepList *parent) const = 0;
- virtual BuildStep *create(BuildStepList *parent, Core::Id id) = 0;
- virtual BuildStep *restore(BuildStepList *parent, const QVariantMap &map);
- virtual BuildStep *clone(BuildStepList *parent, BuildStep *product) = 0;
+ Core::Id m_supportedProjectType;
+ QList<Core::Id> m_supportedDeviceTypes;
+ QList<Core::Id> m_supportedStepLists;
+ Core::Id m_supportedConfiguration;
+ bool m_isRepeatable = true;
};
class PROJECTEXPLORER_EXPORT BuildStepConfigWidget : public QWidget
diff --git a/src/plugins/projectexplorer/buildsteplist.cpp b/src/plugins/projectexplorer/buildsteplist.cpp
index 0cb7e618a5..1d1ffab0d6 100644
--- a/src/plugins/projectexplorer/buildsteplist.cpp
+++ b/src/plugins/projectexplorer/buildsteplist.cpp
@@ -44,27 +44,27 @@ const char STEPS_PREFIX[] = "ProjectExplorer.BuildStepList.Step.";
} // namespace
-BuildStepList::BuildStepList(QObject *parent, Core::Id id) :
- ProjectConfiguration(parent)
-{
- Q_ASSERT(parent);
- initialize(id);
+BuildStepList::BuildStepList(QObject *parent, Core::Id id)
+ : ProjectConfiguration(parent, id)
+{
+ if (id == Constants::BUILDSTEPS_BUILD) {
+ //: Display name of the clean build step list. Used as part of the labels in the project window.
+ setDefaultDisplayName(tr("Build"));
+ } else if (id == Constants::BUILDSTEPS_CLEAN) {
+ //: Display name of the build build step list. Used as part of the labels in the project window.
+ setDefaultDisplayName(tr("Clean"));
+ }
}
-BuildStepList::BuildStepList(QObject *parent, BuildStepList *source) :
- ProjectConfiguration(parent)
+BuildStepList::~BuildStepList()
{
- copyFrom(source);
- setDisplayName(source->displayName());
- Q_ASSERT(parent);
- // do not clone the steps here:
- // The BC is not fully set up yet and thus some of the buildstepfactories
- // will fail to clone the buildsteps!
+ clear();
}
-BuildStepList::~BuildStepList()
+void BuildStepList::clear()
{
qDeleteAll(m_steps);
+ m_steps.clear();
}
QVariantMap BuildStepList::toMap() const
@@ -95,29 +95,6 @@ bool BuildStepList::contains(Core::Id id) const
});
}
-void BuildStepList::cloneSteps(BuildStepList *source)
-{
- Q_ASSERT(source);
- const QList<IBuildStepFactory *> factories
- = ExtensionSystem::PluginManager::getObjects<IBuildStepFactory>();
- foreach (BuildStep *originalbs, source->steps()) {
- foreach (IBuildStepFactory *factory, factories) {
- const QList<BuildStepInfo> steps = factory->availableSteps(source);
- const Core::Id sourceId = originalbs->id();
- const auto canClone = [sourceId](const BuildStepInfo &info) {
- return (info.flags & BuildStepInfo::Unclonable) == 0 && info.id == sourceId;
- };
- if (Utils::contains(steps, canClone)) {
- if (BuildStep *clonebs = factory->clone(this, originalbs)) {
- m_steps.append(clonebs);
- break;
- }
- qWarning() << "Cloning of step " << originalbs->displayName() << " failed (continuing).";
- }
- }
- }
-}
-
bool BuildStepList::isActive() const
{
return qobject_cast<ProjectConfiguration *>(parent())->isActive();
@@ -125,12 +102,14 @@ bool BuildStepList::isActive() const
bool BuildStepList::fromMap(const QVariantMap &map)
{
+ clear();
+
// We need the ID set before trying to restore the steps!
if (!ProjectConfiguration::fromMap(map))
return false;
- const QList<IBuildStepFactory *> factories
- = ExtensionSystem::PluginManager::getObjects<IBuildStepFactory>();
+ const QList<BuildStepFactory *> factories
+ = ExtensionSystem::PluginManager::getObjects<BuildStepFactory>();
int maxSteps = map.value(QString::fromLatin1(STEPS_COUNT_KEY), 0).toInt();
for (int i = 0; i < maxSteps; ++i) {
@@ -139,17 +118,21 @@ bool BuildStepList::fromMap(const QVariantMap &map)
qWarning() << "No step data found for" << i << "(continuing).";
continue;
}
- foreach (IBuildStepFactory *factory, factories) {
- const QList<BuildStepInfo> steps = factory->availableSteps(this);
- const Core::Id id = ProjectExplorer::idFromMap(bsData);
- if (Utils::contains(steps, Utils::equal(&BuildStepInfo::id, id))) {
- if (BuildStep *bs = factory->restore(this, bsData)) {
- appendStep(bs);
- break;
+ bool handled = false;
+ Core::Id stepId = idFromMap(bsData);
+ for (BuildStepFactory *factory : factories) {
+ if (factory->stepId() == stepId) {
+ if (factory->canHandle(this)) {
+ if (BuildStep *bs = factory->restore(this, bsData)) {
+ appendStep(bs);
+ handled = true;
+ } else {
+ qWarning() << "Restoration of step" << i << "failed (continuing).";
+ }
}
- qWarning() << "Restoration of step" << i << "failed (continuing).";
}
}
+ QTC_CHECK(handled);
}
return true;
}
diff --git a/src/plugins/projectexplorer/buildsteplist.h b/src/plugins/projectexplorer/buildsteplist.h
index 8a1c6659bc..80ef5e5310 100644
--- a/src/plugins/projectexplorer/buildsteplist.h
+++ b/src/plugins/projectexplorer/buildsteplist.h
@@ -41,10 +41,11 @@ class PROJECTEXPLORER_EXPORT BuildStepList : public ProjectConfiguration
Q_OBJECT
public:
- BuildStepList(QObject *parent, Core::Id id);
- BuildStepList(QObject *parent, BuildStepList *source);
+ explicit BuildStepList(QObject *parent, Core::Id id);
~BuildStepList() override;
+ void clear();
+
QList<BuildStep *> steps() const;
QList<BuildStep *> steps(const std::function<bool(const BuildStep *)> &filter) const;
template <class BS> BS *firstOfType() {
@@ -82,7 +83,6 @@ public:
virtual QVariantMap toMap() const override;
virtual bool fromMap(const QVariantMap &map) override;
- void cloneSteps(BuildStepList *source);
bool isActive() const override;
diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp
index 64610a7b3e..d835b3f609 100644
--- a/src/plugins/projectexplorer/buildstepspage.cpp
+++ b/src/plugins/projectexplorer/buildstepspage.cpp
@@ -286,12 +286,12 @@ void BuildStepListWidget::init(BuildStepList *bsl)
void BuildStepListWidget::updateAddBuildStepMenu()
{
- QMap<QString, QPair<Core::Id, IBuildStepFactory *> > map;
+ QMap<QString, QPair<Core::Id, BuildStepFactory *> > map;
//Build up a list of possible steps and save map the display names to the (internal) name and factories.
- QList<IBuildStepFactory *> factories = ExtensionSystem::PluginManager::getObjects<IBuildStepFactory>();
- foreach (IBuildStepFactory *factory, factories) {
- const QList<BuildStepInfo> infos = factory->availableSteps(m_buildStepList);
- for (const BuildStepInfo &info : infos) {
+ QList<BuildStepFactory *> factories = ExtensionSystem::PluginManager::getObjects<BuildStepFactory>();
+ foreach (BuildStepFactory *factory, factories) {
+ if (factory->canHandle(m_buildStepList)) {
+ const BuildStepInfo &info = factory->stepInfo();
if (info.flags & BuildStepInfo::Uncreatable)
continue;
if ((info.flags & BuildStepInfo::UniqueStep) && m_buildStepList->contains(info.id))
@@ -304,11 +304,11 @@ void BuildStepListWidget::updateAddBuildStepMenu()
QMenu *menu = m_addButton->menu();
menu->clear();
if (!map.isEmpty()) {
- QMap<QString, QPair<Core::Id, IBuildStepFactory *> >::const_iterator it, end;
+ QMap<QString, QPair<Core::Id, BuildStepFactory *> >::const_iterator it, end;
end = map.constEnd();
for (it = map.constBegin(); it != end; ++it) {
QAction *action = menu->addAction(it.key());
- IBuildStepFactory *factory = it.value().second;
+ BuildStepFactory *factory = it.value().second;
Core::Id id = it.value().first;
connect(action, &QAction::triggered, [id, factory, this]() {
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
index 7f357fc774..3e732af2e4 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
@@ -83,24 +83,13 @@ private:
};
CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target)
- : RunConfiguration(target)
+ : RunConfiguration(target, CUSTOM_EXECUTABLE_ID)
{
addExtraAspect(new LocalEnvironmentAspect(this, LocalEnvironmentAspect::BaseEnvironmentModifier()));
addExtraAspect(new ArgumentsAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.Arguments"));
addExtraAspect(new TerminalAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal"));
}
-void CustomExecutableRunConfiguration::initialize(Core::Id)
-{
- RunConfiguration::initialize(CUSTOM_EXECUTABLE_ID);
- if (target()->activeBuildConfiguration())
- m_workingDirectory = Constants::DEFAULT_WORKING_DIR;
- else
- m_workingDirectory = Constants::DEFAULT_WORKING_DIR_ALTERNATE;
-
- setDefaultDisplayName(defaultDisplayName());
-}
-
// Note: Qt4Project deletes all empty customexecrunconfigs for which isConfigured() == false.
CustomExecutableRunConfiguration::~CustomExecutableRunConfiguration()
{
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.h b/src/plugins/projectexplorer/customexecutablerunconfiguration.h
index 483954e7af..925af00358 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.h
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.h
@@ -65,14 +65,10 @@ public:
signals:
void changed();
-protected:
- void initialize(Core::Id) override;
+private:
bool fromMap(const QVariantMap &map) override;
QString defaultDisplayName() const;
-private:
- void ctor();
-
void configurationDialogFinished();
void setExecutable(const QString &executable);
QString rawExecutable() const;
diff --git a/src/plugins/projectexplorer/deployconfiguration.cpp b/src/plugins/projectexplorer/deployconfiguration.cpp
index 6f44d135b1..1c3967442d 100644
--- a/src/plugins/projectexplorer/deployconfiguration.cpp
+++ b/src/plugins/projectexplorer/deployconfiguration.cpp
@@ -34,62 +34,51 @@
#include <extensionsystem/pluginmanager.h>
+#include <utils/algorithm.h>
+
namespace ProjectExplorer {
const char BUILD_STEP_LIST_COUNT[] = "ProjectExplorer.BuildConfiguration.BuildStepListCount";
const char BUILD_STEP_LIST_PREFIX[] = "ProjectExplorer.BuildConfiguration.BuildStepList.";
const char DEFAULT_DEPLOYCONFIGURATION_ID[] = "ProjectExplorer.DefaultDeployConfiguration";
-DeployConfiguration::DeployConfiguration(Target *target, Core::Id id) :
- ProjectConfiguration(target)
+DeployConfiguration::DeployConfiguration(Target *target, Core::Id id)
+ : ProjectConfiguration(target, id),
+ m_stepList(this, Constants::BUILDSTEPS_DEPLOY)
{
- ProjectConfiguration::initialize(id);
- Q_ASSERT(target);
- m_stepList = new BuildStepList(this, Core::Id(Constants::BUILDSTEPS_DEPLOY));
+ Utils::MacroExpander *expander = macroExpander();
+ expander->setDisplayName(tr("Deploy Settings"));
+ expander->setAccumulating(true);
+ expander->registerSubProvider([target] {
+ BuildConfiguration *bc = target->activeBuildConfiguration();
+ return bc ? bc->macroExpander() : target->macroExpander();
+ });
+
//: Display name of the deploy build step list. Used as part of the labels in the project window.
- m_stepList->setDefaultDisplayName(tr("Deploy"));
+ m_stepList.setDefaultDisplayName(tr("Deploy"));
//: Default DeployConfiguration display name
setDefaultDisplayName(tr("Deploy locally"));
- ctor();
}
-DeployConfiguration::DeployConfiguration(Target *target, DeployConfiguration *source) :
- ProjectConfiguration(target)
+void DeployConfiguration::initialize()
{
- ProjectConfiguration::copyFrom(source);
- Q_ASSERT(target);
- // Do not clone stepLists here, do that in the derived constructor instead
- // otherwise BuildStepFactories might reject to set up a BuildStep for us
- // since we are not yet the derived class!
- ctor();
}
-void DeployConfiguration::ctor()
+BuildStepList *DeployConfiguration::stepList()
{
- Utils::MacroExpander *expander = macroExpander();
- expander->setDisplayName(tr("Deploy Settings"));
- expander->setAccumulating(true);
- expander->registerSubProvider([this]() -> Utils::MacroExpander * {
- BuildConfiguration *bc = target()->activeBuildConfiguration();
- return bc ? bc->macroExpander() : target()->macroExpander();
- });
+ return &m_stepList;
}
-DeployConfiguration::~DeployConfiguration()
+const BuildStepList *DeployConfiguration::stepList() const
{
- delete m_stepList;
-}
-
-BuildStepList *DeployConfiguration::stepList() const
-{
- return m_stepList;
+ return &m_stepList;
}
QVariantMap DeployConfiguration::toMap() const
{
QVariantMap map(ProjectConfiguration::toMap());
map.insert(QLatin1String(BUILD_STEP_LIST_COUNT), 1);
- map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QLatin1Char('0'), m_stepList->toMap());
+ map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QLatin1Char('0'), m_stepList.toMap());
return map;
}
@@ -118,23 +107,18 @@ bool DeployConfiguration::fromMap(const QVariantMap &map)
return false;
QVariantMap data = map.value(QLatin1String(BUILD_STEP_LIST_PREFIX) + QLatin1Char('0')).toMap();
if (!data.isEmpty()) {
- delete m_stepList;
- m_stepList = new BuildStepList(this, Core::Id());
- if (!m_stepList->fromMap(data)) {
+ m_stepList.clear();
+ if (!m_stepList.fromMap(data)) {
qWarning() << "Failed to restore deploy step list";
- delete m_stepList;
- m_stepList = 0;
+ m_stepList.clear();
return false;
}
- m_stepList->setDefaultDisplayName(tr("Deploy"));
+ m_stepList.setDefaultDisplayName(tr("Deploy"));
} else {
qWarning() << "No data for deploy step list found!";
return false;
}
- // We assume that we hold the deploy list
- Q_ASSERT(m_stepList && m_stepList->id() == Constants::BUILDSTEPS_DEPLOY);
-
return true;
}
@@ -153,129 +137,185 @@ bool DeployConfiguration::isActive() const
return target()->isActive() && target()->activeDeployConfiguration() == this;
}
-void DeployConfiguration::cloneSteps(DeployConfiguration *source)
-{
- if (source == this)
- return;
- delete m_stepList;
- m_stepList = new BuildStepList(this, source->stepList());
- m_stepList->cloneSteps(source->stepList());
-}
///
-// DefaultDeployConfiguration
+// DeployConfigurationFactory
///
-DefaultDeployConfiguration::DefaultDeployConfiguration(Target *target, Core::Id id)
- : DeployConfiguration(target, id)
-{
-}
-
-DefaultDeployConfiguration::DefaultDeployConfiguration(Target *target, DeployConfiguration *source)
- : DeployConfiguration(target, source)
+DeployConfigurationFactory::DeployConfigurationFactory()
{
- cloneSteps(source);
+ setObjectName("DeployConfigurationFactory");
}
-///
-// DeployConfigurationFactory
-///
-
-DeployConfigurationFactory::DeployConfigurationFactory(QObject *parent) :
- QObject(parent)
-{ setObjectName(QLatin1String("DeployConfigurationFactory")); }
-
-DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, const QVariantMap &map)
+QList<Core::Id> DeployConfigurationFactory::availableCreationIds(Target *parent) const
{
- return ExtensionSystem::PluginManager::getObject<DeployConfigurationFactory>(
- [&parent, &map](DeployConfigurationFactory *factory) {
- return factory->canRestore(parent, map);
- });
+ if (!canHandle(parent))
+ return {};
+ return Utils::transform(availableBuildTargets(parent), [this](const QString &suffix) {
+ return m_deployConfigBaseId.withSuffix(suffix);
+ });
}
-QList<DeployConfigurationFactory *> DeployConfigurationFactory::find(Target *parent)
+QList<QString> DeployConfigurationFactory::availableBuildTargets(Target *) const
{
- return ExtensionSystem::PluginManager::getObjects<DeployConfigurationFactory>(
- [&parent](DeployConfigurationFactory *factory) {
- return !factory->availableCreationIds(parent).isEmpty();
- });
+ return {QString()};
}
-DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, DeployConfiguration *dc)
+QString DeployConfigurationFactory::displayNameForBuildTarget(const QString &) const
{
- return ExtensionSystem::PluginManager::getObject<DeployConfigurationFactory>(
- [&parent, &dc](DeployConfigurationFactory *factory) {
- return factory->canClone(parent, dc);
- });
+ return m_defaultDisplayName;
}
-///
-// DefaultDeployConfigurationFactory
-///
-
-QList<Core::Id> DefaultDeployConfigurationFactory::availableCreationIds(Target *parent) const
+QString DeployConfigurationFactory::displayNameForId(Core::Id id) const
{
- if (!canHandle(parent))
- return QList<Core::Id>();
- return QList<Core::Id>() << Core::Id(DEFAULT_DEPLOYCONFIGURATION_ID);
+ return displayNameForBuildTarget(id.suffixAfter(m_deployConfigBaseId));
}
-QString DefaultDeployConfigurationFactory::displayNameForId(Core::Id id) const
+bool DeployConfigurationFactory::canHandle(Target *target) const
{
- if (id == DEFAULT_DEPLOYCONFIGURATION_ID)
- //: Display name of the default deploy configuration
- return DeployConfigurationFactory::tr("Deploy Configuration");
- return QString();
+ if (m_supportedProjectType.isValid()) {
+ if (target->project()->id() != m_supportedProjectType)
+ return false;
+ }
+
+ if (!target->project()->supportsKit(target->kit()))
+ return false;
+
+ if (!m_supportedTargetDeviceTypes.isEmpty()) {
+ if (!m_supportedTargetDeviceTypes.contains(
+ DeviceTypeKitInformation::deviceTypeId(target->kit())))
+ return false;
+ }
+
+ return true;
}
-bool DefaultDeployConfigurationFactory::canCreate(Target *parent, Core::Id id) const
+bool DeployConfigurationFactory::canCreate(Target *parent, Core::Id id) const
{
if (!canHandle(parent))
return false;
- return id == DEFAULT_DEPLOYCONFIGURATION_ID;
+ if (!id.name().startsWith(m_deployConfigBaseId.name()))
+ return false;
+ return true;
}
-DeployConfiguration *DefaultDeployConfigurationFactory::create(Target *parent, Core::Id id)
+DeployConfiguration *DeployConfigurationFactory::create(Target *parent, Core::Id id)
{
if (!canCreate(parent, id))
return nullptr;
- return new DefaultDeployConfiguration(parent, id);
+ QTC_ASSERT(m_creator, return nullptr);
+ DeployConfiguration *dc = m_creator(parent);
+ if (!dc)
+ return nullptr;
+ dc->initialize();
+ return dc;
}
-bool DefaultDeployConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
+bool DeployConfigurationFactory::canClone(Target *parent, DeployConfiguration *product) const
{
- return canCreate(parent, idFromMap(map));
+ if (!canHandle(parent))
+ return false;
+ const Core::Id id = product->id();
+ if (!id.name().startsWith(m_deployConfigBaseId.name()))
+ return false;
+ return true;
}
-DeployConfiguration *DefaultDeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
+DeployConfiguration *DeployConfigurationFactory::clone(Target *parent, DeployConfiguration *product)
+{
+ QTC_ASSERT(m_creator, return nullptr);
+ if (!canClone(parent, product))
+ return nullptr;
+ DeployConfiguration *dc = m_creator(parent);
+ QVariantMap data = product->toMap();
+ dc->fromMap(data);
+ return dc;
+}
+
+DeployConfiguration *DeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
{
if (!canRestore(parent, map))
return nullptr;
- auto dc = new DefaultDeployConfiguration(parent, idFromMap(map));
+ QTC_ASSERT(m_creator, return nullptr);
+ DeployConfiguration *dc = m_creator(parent);
+ QTC_ASSERT(dc, return nullptr);
if (!dc->fromMap(map)) {
delete dc;
- return nullptr;
+ dc = nullptr;
}
return dc;
}
-bool DefaultDeployConfigurationFactory::canClone(Target *parent, DeployConfiguration *product) const
+bool DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
{
- return canCreate(parent, product->id());
+ if (!canHandle(parent))
+ return false;
+ const Core::Id id = idFromMap(map);
+ return id.name().startsWith(m_deployConfigBaseId.name());
}
-DeployConfiguration *DefaultDeployConfigurationFactory::clone(Target *parent, DeployConfiguration *product)
+DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, const QVariantMap &map)
{
- if (!canClone(parent, product))
- return nullptr;
- return new DefaultDeployConfiguration(parent, product);
+ return ExtensionSystem::PluginManager::getObject<DeployConfigurationFactory>(
+ [&parent, &map](DeployConfigurationFactory *factory) {
+ return factory->canRestore(parent, map);
+ });
+}
+
+QList<DeployConfigurationFactory *> DeployConfigurationFactory::find(Target *parent)
+{
+ return ExtensionSystem::PluginManager::getObjects<DeployConfigurationFactory>(
+ [&parent](DeployConfigurationFactory *factory) {
+ return !factory->availableCreationIds(parent).isEmpty();
+ });
+}
+
+DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, DeployConfiguration *dc)
+{
+ return ExtensionSystem::PluginManager::getObject<DeployConfigurationFactory>(
+ [&parent, &dc](DeployConfigurationFactory *factory) {
+ return factory->canClone(parent, dc);
+ });
+}
+
+void DeployConfigurationFactory::setSupportedTargetDeviceTypes(const QList<Core::Id> &ids)
+{
+ m_supportedTargetDeviceTypes = ids;
+}
+
+void DeployConfigurationFactory::setDefaultDisplayName(const QString &defaultDisplayName)
+{
+ m_defaultDisplayName = defaultDisplayName;
+}
+
+void DeployConfigurationFactory::setSupportedProjectType(Core::Id id)
+{
+ m_supportedProjectType = id;
+}
+
+///
+// DefaultDeployConfigurationFactory
+///
+
+DefaultDeployConfigurationFactory::DefaultDeployConfigurationFactory()
+{
+ struct DefaultDeployConfiguration : DeployConfiguration
+ {
+ DefaultDeployConfiguration(Target *t)
+ : DeployConfiguration(t, DEFAULT_DEPLOYCONFIGURATION_ID)
+ {}
+ };
+
+ registerDeployConfiguration<DefaultDeployConfiguration>(DEFAULT_DEPLOYCONFIGURATION_ID);
+ setSupportedTargetDeviceTypes({Constants::DESKTOP_DEVICE_TYPE});
+ //: Display name of the default deploy configuration
+ setDefaultDisplayName(DeployConfigurationFactory::tr("Deploy Configuration"));
}
bool DefaultDeployConfigurationFactory::canHandle(Target *parent) const
{
- if (!parent->project()->supportsKit(parent->kit()) || parent->project()->needsSpecialDeployment())
- return false;
- return DeviceTypeKitInformation::deviceTypeId(parent->kit()) == Constants::DESKTOP_DEVICE_TYPE;
+ return DeployConfigurationFactory::canHandle(parent)
+ && !parent->project()->needsSpecialDeployment();
}
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/deployconfiguration.h b/src/plugins/projectexplorer/deployconfiguration.h
index db3b37c5c3..4e42e5e00f 100644
--- a/src/plugins/projectexplorer/deployconfiguration.h
+++ b/src/plugins/projectexplorer/deployconfiguration.h
@@ -27,12 +27,9 @@
#include "projectexplorer_export.h"
+#include "buildsteplist.h"
#include "projectconfiguration.h"
-#include <QString>
-
-QT_FORWARD_DECLARE_CLASS(QStringList)
-
namespace ProjectExplorer {
class BuildStepList;
@@ -44,11 +41,16 @@ class PROJECTEXPLORER_EXPORT DeployConfiguration : public ProjectConfiguration
{
Q_OBJECT
+protected:
+ friend class DeployConfigurationFactory;
+ explicit DeployConfiguration(Target *target, Core::Id id);
+
public:
- // ctors are protected
- ~DeployConfiguration() override;
+ ~DeployConfiguration() override = default;
+ virtual void initialize();
- BuildStepList *stepList() const;
+ BuildStepList *stepList();
+ const BuildStepList *stepList() const;
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
@@ -66,26 +68,8 @@ public:
signals:
void enabledChanged();
-protected:
- DeployConfiguration(Target *target, Core::Id id);
- DeployConfiguration(Target *target, DeployConfiguration *source);
-
- void cloneSteps(DeployConfiguration *source);
-
private:
- void ctor();
-
- BuildStepList *m_stepList = nullptr;
-};
-
-class PROJECTEXPLORER_EXPORT DefaultDeployConfiguration : public DeployConfiguration
-{
- Q_OBJECT
- friend class DefaultDeployConfigurationFactory; // for the ctors
-
-protected:
- DefaultDeployConfiguration(Target *target, Core::Id id);
- DefaultDeployConfiguration(Target *target, DeployConfiguration *source);
+ BuildStepList m_stepList;
};
class PROJECTEXPLORER_EXPORT DeployConfigurationFactory : public QObject
@@ -93,43 +77,66 @@ class PROJECTEXPLORER_EXPORT DeployConfigurationFactory : public QObject
Q_OBJECT
public:
- explicit DeployConfigurationFactory(QObject *parent = nullptr);
+ DeployConfigurationFactory();
// used to show the list of possible additons to a target, returns a list of types
- virtual QList<Core::Id> availableCreationIds(Target *parent) const = 0;
+ QList<Core::Id> availableCreationIds(Target *parent) const;
// used to translate the types to names to display to the user
- virtual QString displayNameForId(Core::Id id) const = 0;
+ QString displayNameForId(Core::Id id) const;
- virtual bool canCreate(Target *parent, Core::Id id) const = 0;
- virtual DeployConfiguration *create(Target *parent, Core::Id id) = 0;
+ virtual bool canHandle(ProjectExplorer::Target *target) const;
+
+ bool canCreate(Target *parent, Core::Id id) const;
+ virtual DeployConfiguration *create(Target *parent, Core::Id id);
// used to recreate the runConfigurations when restoring settings
- virtual bool canRestore(Target *parent, const QVariantMap &map) const = 0;
- virtual DeployConfiguration *restore(Target *parent, const QVariantMap &map) = 0;
- virtual bool canClone(Target *parent, DeployConfiguration *product) const = 0;
- virtual DeployConfiguration *clone(Target *parent, DeployConfiguration *product) = 0;
+ bool canRestore(Target *parent, const QVariantMap &map) const;
+ DeployConfiguration *restore(Target *parent, const QVariantMap &map);
+ bool canClone(Target *parent, DeployConfiguration *product) const;
+ DeployConfiguration *clone(Target *parent, DeployConfiguration *product);
static DeployConfigurationFactory *find(Target *parent, const QVariantMap &map);
static QList<DeployConfigurationFactory *> find(Target *parent);
static DeployConfigurationFactory *find(Target *parent, DeployConfiguration *dc);
+ void setSupportedTargetDeviceTypes(const QList<Core::Id> &ids);
+ void setDefaultDisplayName(const QString &defaultDisplayName);
+ void setSupportedProjectType(Core::Id id);
+
+protected:
+ virtual QList<QString> availableBuildTargets(Target *parent) const;
+ virtual QString displayNameForBuildTarget(const QString &buildTarget) const;
+
+ using DeployConfigurationCreator = std::function<DeployConfiguration *(Target *)>;
+
+ template <class DeployConfig>
+ void registerDeployConfiguration(Core::Id deployConfigBaseId)
+ {
+ m_creator = [this](Target *t) {
+ auto dc = new DeployConfig(t);
+ dc->setDefaultDisplayName(m_defaultDisplayName);
+ return dc;
+ };
+ m_deployConfigBaseId = deployConfigBaseId;
+ }
+
signals:
void availableCreationIdsChanged();
+
+private:
+ DeployConfigurationCreator m_creator;
+ Core::Id m_deployConfigBaseId;
+ Core::Id m_supportedProjectType;
+ QList<Core::Id> m_supportedTargetDeviceTypes;
+ QString m_defaultDisplayName;
};
class DefaultDeployConfigurationFactory : public DeployConfigurationFactory
{
public:
- QList<Core::Id> availableCreationIds(Target *parent) const override;
- // used to translate the types to names to display to the user
- QString displayNameForId(Core::Id id) const override;
- bool canCreate(Target *parent, Core::Id id) const override;
- DeployConfiguration *create(Target *parent, Core::Id id) override;
- bool canRestore(Target *parent, const QVariantMap &map) const override;
- DeployConfiguration *restore(Target *parent, const QVariantMap &map) override;
- bool canClone(Target *parent, DeployConfiguration *product) const override;
- DeployConfiguration *clone(Target *parent, DeployConfiguration *product) override;
+ DefaultDeployConfigurationFactory();
+
private:
- bool canHandle(Target *parent) const;
+ bool canHandle(Target *parent) const override;
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp b/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp
index a978543354..2d6164c9ae 100644
--- a/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.cpp
@@ -35,14 +35,8 @@
using namespace ProjectExplorer;
-DeviceCheckBuildStep::DeviceCheckBuildStep(BuildStepList *bsl, Core::Id id)
- : BuildStep(bsl, id)
-{
- setDefaultDisplayName(stepDisplayName());
-}
-
-DeviceCheckBuildStep::DeviceCheckBuildStep(BuildStepList *bsl, DeviceCheckBuildStep *bs)
- : BuildStep(bsl, bs)
+DeviceCheckBuildStep::DeviceCheckBuildStep(BuildStepList *bsl)
+ : BuildStep(bsl, stepId())
{
setDefaultDisplayName(stepDisplayName());
}
diff --git a/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h b/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h
index b56f12f078..7886a9e8ab 100644
--- a/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h
+++ b/src/plugins/projectexplorer/devicesupport/devicecheckbuildstep.h
@@ -36,8 +36,7 @@ class PROJECTEXPLORER_EXPORT DeviceCheckBuildStep : public BuildStep
{
Q_OBJECT
public:
- DeviceCheckBuildStep(BuildStepList *bsl, Core::Id id);
- DeviceCheckBuildStep(BuildStepList *bsl, DeviceCheckBuildStep *bs);
+ explicit DeviceCheckBuildStep(BuildStepList *bsl);
bool init(QList<const BuildStep *> &earlierSteps) override;
diff --git a/src/plugins/projectexplorer/processstep.cpp b/src/plugins/projectexplorer/processstep.cpp
index ae7b2a31a0..afe2f9ada4 100644
--- a/src/plugins/projectexplorer/processstep.cpp
+++ b/src/plugins/projectexplorer/processstep.cpp
@@ -46,20 +46,8 @@ const char PROCESS_WORKINGDIRECTORY_KEY[] = "ProjectExplorer.ProcessStep.Working
const char PROCESS_ARGUMENTS_KEY[] = "ProjectExplorer.ProcessStep.Arguments";
}
-ProcessStep::ProcessStep(BuildStepList *bsl) : AbstractProcessStep(bsl, Core::Id(PROCESS_STEP_ID))
-{
- ctor();
-}
-
-ProcessStep::ProcessStep(BuildStepList *bsl, ProcessStep *bs) : AbstractProcessStep(bsl, bs),
- m_command(bs->m_command),
- m_arguments(bs->m_arguments),
- m_workingDirectory(bs->m_workingDirectory)
-{
- ctor();
-}
-
-void ProcessStep::ctor()
+ProcessStep::ProcessStep(BuildStepList *bsl)
+ : AbstractProcessStep(bsl, PROCESS_STEP_ID)
{
//: Default ProcessStep display name
setDefaultDisplayName(tr("Custom Process Step"));
@@ -156,21 +144,13 @@ bool ProcessStep::fromMap(const QVariantMap &map)
// ProcessStepFactory
//*******
-QList<BuildStepInfo> ProcessStepFactory::availableSteps(BuildStepList *parent) const
-{
- Q_UNUSED(parent);
- return {{PROCESS_STEP_ID, ProcessStep::tr("Custom Process Step", "item in combobox")}};
-}
-
-BuildStep *ProcessStepFactory::create(BuildStepList *parent, Core::Id id)
-{
- Q_UNUSED(id);
- return new ProcessStep(parent);
-}
-
-BuildStep *ProcessStepFactory::clone(BuildStepList *parent, BuildStep *bs)
+ProcessStepFactory::ProcessStepFactory()
{
- return new ProcessStep(parent, static_cast<ProcessStep *>(bs));
+ registerStep<ProcessStep>(PROCESS_STEP_ID);
+ setDisplayName(ProcessStep::tr("Custom Process Step", "item in combobox"));
+ setSupportedStepLists({ProjectExplorer::Constants::BUILDSTEPS_BUILD,
+ ProjectExplorer::Constants::BUILDSTEPS_CLEAN,
+ ProjectExplorer::Constants::BUILDSTEPS_DEPLOY});
}
//*******
diff --git a/src/plugins/projectexplorer/processstep.h b/src/plugins/projectexplorer/processstep.h
index 8d92fca092..7da9f4ec09 100644
--- a/src/plugins/projectexplorer/processstep.h
+++ b/src/plugins/projectexplorer/processstep.h
@@ -29,19 +29,14 @@
#include "abstractprocessstep.h"
namespace ProjectExplorer {
-
namespace Internal {
-class ProcessStepFactory : public IBuildStepFactory
+class ProcessStepFactory : public BuildStepFactory
{
Q_OBJECT
public:
- QList<ProjectExplorer::BuildStepInfo>
- availableSteps(ProjectExplorer::BuildStepList *parent) const override;
-
- BuildStep *create(BuildStepList *parent, Core::Id id) override;
- BuildStep *clone(BuildStepList *parent, BuildStep *product) override;
+ ProcessStepFactory();
};
class ProcessStep : public AbstractProcessStep
@@ -68,13 +63,8 @@ public:
QVariantMap toMap() const override;
-protected:
- ProcessStep(BuildStepList *bsl, ProcessStep *bs);
-
- bool fromMap(const QVariantMap &map) override;
-
private:
- void ctor();
+ bool fromMap(const QVariantMap &map) override;
QString m_command;
QString m_arguments;
diff --git a/src/plugins/projectexplorer/projectconfiguration.cpp b/src/plugins/projectexplorer/projectconfiguration.cpp
index 0362c747c9..3ab01fba2f 100644
--- a/src/plugins/projectexplorer/projectconfiguration.cpp
+++ b/src/plugins/projectexplorer/projectconfiguration.cpp
@@ -25,33 +25,34 @@
#include "projectconfiguration.h"
+#include <utils/qtcassert.h>
+
using namespace ProjectExplorer;
const char CONFIGURATION_ID_KEY[] = "ProjectExplorer.ProjectConfiguration.Id";
const char DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DisplayName";
const char DEFAULT_DISPLAY_NAME_KEY[] = "ProjectExplorer.ProjectConfiguration.DefaultDisplayName";
-ProjectConfiguration::ProjectConfiguration(QObject *parent)
- : QObject(parent)
-{}
-
-void ProjectConfiguration::initialize(Core::Id id)
+ProjectConfiguration::ProjectConfiguration(QObject *parent, Core::Id id)
+ : QObject(parent), m_id(id)
{
- m_id = id;
+ QTC_CHECK(id.isValid());
setObjectName(id.toString());
}
-void ProjectConfiguration::copyFrom(const ProjectConfiguration *source)
+Core::Id ProjectConfiguration::id() const
{
- Q_ASSERT(source);
- m_id = source->m_id;
- m_defaultDisplayName = source->m_defaultDisplayName;
- m_displayName = tr("Clone of %1").arg(source->displayName());
+ return m_id;
}
-Core::Id ProjectConfiguration::id() const
+QString ProjectConfiguration::extraId() const
{
- return m_id;
+ return QString();
+}
+
+QString ProjectConfiguration::settingsIdKey()
+{
+ return QString(CONFIGURATION_ID_KEY);
}
QString ProjectConfiguration::displayName() const
@@ -102,8 +103,9 @@ bool ProjectConfiguration::usesDefaultDisplayName() const
QVariantMap ProjectConfiguration::toMap() const
{
+ QTC_CHECK(m_id.isValid());
QVariantMap map;
- map.insert(QLatin1String(CONFIGURATION_ID_KEY), m_id.toSetting());
+ map.insert(QLatin1String(CONFIGURATION_ID_KEY), m_id.withSuffix(extraId()).toSetting());
map.insert(QLatin1String(DISPLAY_NAME_KEY), m_displayName);
map.insert(QLatin1String(DEFAULT_DISPLAY_NAME_KEY), m_defaultDisplayName);
return map;
@@ -111,12 +113,14 @@ QVariantMap ProjectConfiguration::toMap() const
bool ProjectConfiguration::fromMap(const QVariantMap &map)
{
- m_id = Core::Id::fromSetting(map.value(QLatin1String(CONFIGURATION_ID_KEY)));
+ Core::Id id = Core::Id::fromSetting(map.value(QLatin1String(CONFIGURATION_ID_KEY)));
+ QTC_ASSERT(id.toString().startsWith(m_id.toString()), return false);
+
m_displayName = map.value(QLatin1String(DISPLAY_NAME_KEY), QString()).toString();
m_defaultDisplayName = map.value(QLatin1String(DEFAULT_DISPLAY_NAME_KEY),
m_defaultDisplayName.isEmpty() ?
m_displayName : m_defaultDisplayName).toString();
- return m_id.isValid();
+ return true;
}
Core::Id ProjectExplorer::idFromMap(const QVariantMap &map)
@@ -134,16 +138,10 @@ bool StatefulProjectConfiguration::isEnabled() const
return m_isEnabled;
}
-StatefulProjectConfiguration::StatefulProjectConfiguration(QObject *parent) :
- ProjectConfiguration(parent)
+StatefulProjectConfiguration::StatefulProjectConfiguration(QObject *parent, Core::Id id) :
+ ProjectConfiguration(parent, id)
{ }
-void StatefulProjectConfiguration::copyFrom(const StatefulProjectConfiguration *source)
-{
- ProjectConfiguration::copyFrom(source);
- m_isEnabled = source->m_isEnabled;
-}
-
void StatefulProjectConfiguration::setEnabled(bool enabled)
{
if (enabled == m_isEnabled)
diff --git a/src/plugins/projectexplorer/projectconfiguration.h b/src/plugins/projectexplorer/projectconfiguration.h
index 38fe375e02..ec23948571 100644
--- a/src/plugins/projectexplorer/projectconfiguration.h
+++ b/src/plugins/projectexplorer/projectconfiguration.h
@@ -42,11 +42,14 @@ class PROJECTEXPLORER_EXPORT ProjectConfiguration : public QObject
{
Q_OBJECT
+protected:
+ explicit ProjectConfiguration(QObject *parent, Core::Id id);
+
public:
- // ctors are protected
~ProjectConfiguration() = default;
Core::Id id() const;
+
QString displayName() const;
bool usesDefaultDisplayName() const;
@@ -69,17 +72,17 @@ public:
virtual bool isActive() const = 0;
+ // Used in settings to mangle in build targets in RunConfigurations.
+ virtual QString extraId() const;
+
+ static QString settingsIdKey();
+
signals:
void displayNameChanged();
void toolTipChanged();
-protected:
- ProjectConfiguration(QObject *parent);
- void initialize(Core::Id id);
- void copyFrom(const ProjectConfiguration *source);
-
private:
- Core::Id m_id;
+ const Core::Id m_id;
QString m_displayName;
QString m_defaultDisplayName;
QString m_toolTip;
@@ -101,8 +104,7 @@ signals:
void enabledChanged();
protected:
- StatefulProjectConfiguration(QObject *parent);
- void copyFrom(const StatefulProjectConfiguration *source);
+ StatefulProjectConfiguration(QObject *parent, Core::Id id);
void setEnabled(bool enabled);
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index 512ae87491..83cbdd0249 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -191,11 +191,9 @@ void IRunConfigurationAspect::resetProjectToGlobalSettings()
static std::vector<RunConfiguration::AspectFactory> theAspectFactories;
-RunConfiguration::RunConfiguration(Target *target)
- : StatefulProjectConfiguration(target)
+RunConfiguration::RunConfiguration(Target *target, Core::Id id)
+ : StatefulProjectConfiguration(target, id)
{
- Q_ASSERT(target);
-
connect(target->project(), &Project::parsingStarted,
this, [this]() { updateEnabledState(); });
connect(target->project(), &Project::parsingFinished,
@@ -235,17 +233,6 @@ RunConfiguration::~RunConfiguration()
qDeleteAll(m_aspects);
}
-void RunConfiguration::initialize(Core::Id id)
-{
- StatefulProjectConfiguration::initialize(id);
-}
-
-void RunConfiguration::copyFrom(const RunConfiguration *source)
-{
- QVariantMap data = source->toMap();
- fromMap(data);
-}
-
bool RunConfiguration::isActive() const
{
return target()->isActive() && target()->activeRunConfiguration() == this;
@@ -450,20 +437,17 @@ IRunConfigurationFactory::IRunConfigurationFactory(QObject *parent) :
{
}
-QList<Core::Id> IRunConfigurationFactory::availableCreationIds(Target *parent, CreationMode mode) const
+QList<RunConfigurationCreationInfo>
+ IRunConfigurationFactory::availableCreators(Target *parent, CreationMode mode) const
{
if (!canHandle(parent))
return {};
return Utils::transform(availableBuildTargets(parent, mode), [this](const QString &suffix) {
- return m_runConfigBaseId.withSuffix(suffix);
+ return RunConfigurationCreationInfo{this, m_runConfigBaseId, suffix,
+ this->displayNameForBuildTarget(suffix)};
});
}
-QString IRunConfigurationFactory::displayNameForId(Core::Id id) const
-{
- return displayNameForBuildTarget(id.suffixAfter(m_runConfigBaseId));
-}
-
QString IRunConfigurationFactory::displayNameForBuildTarget(const QString &buildTarget) const
{
return buildTarget;
@@ -501,30 +485,30 @@ bool IRunConfigurationFactory::canCreateHelper(Target *, const QString &) const
return true;
}
-bool IRunConfigurationFactory::canCreate(Target *parent, Core::Id id) const
+RunConfiguration *IRunConfigurationFactory::create(Target *parent, Core::Id id, const QString &extra) const
{
if (!canHandle(parent))
- return false;
- if (!id.name().startsWith(m_runConfigBaseId.name()))
- return false;
- return canCreateHelper(parent, id.suffixAfter(m_runConfigBaseId));
-}
-
-RunConfiguration *IRunConfigurationFactory::create(Target *parent, Core::Id id)
-{
- if (!canCreate(parent, id))
return nullptr;
+ if (id != m_runConfigBaseId)
+ return nullptr;
+ if (!canCreateHelper(parent, extra))
+ return nullptr;
+
QTC_ASSERT(m_creator, return nullptr);
RunConfiguration *rc = m_creator(parent);
if (!rc)
return nullptr;
- rc->initialize(id);
- return rc;
-}
-bool IRunConfigurationFactory::canCloneHelper(Target *, RunConfiguration *) const
-{
- return true;
+ // "FIX" ids by mangling in the extra data (build system target etc)
+ // for compatibility for the current format used in settings.
+ if (!extra.isEmpty()) {
+ QVariantMap data = rc->toMap();
+ data[ProjectConfiguration::settingsIdKey()] = id.withSuffix(extra).toString();
+ rc->fromMap(data);
+ QVariantMap data2 = rc->toMap();
+ }
+
+ return rc;
}
bool IRunConfigurationFactory::canClone(Target *parent, RunConfiguration *product) const
@@ -532,19 +516,16 @@ bool IRunConfigurationFactory::canClone(Target *parent, RunConfiguration *produc
if (!canHandle(parent))
return false;
const Core::Id id = product->id();
- if (!id.name().startsWith(m_runConfigBaseId.name()))
- return false;
- return canCloneHelper(parent, product);
+ return id.name().startsWith(m_runConfigBaseId.name());
}
-RunConfiguration *IRunConfigurationFactory::restore(Target *parent, const QVariantMap &map)
+RunConfiguration *IRunConfigurationFactory::restore(Target *parent, const QVariantMap &map) const
{
if (!canRestore(parent, map))
return nullptr;
QTC_ASSERT(m_creator, return nullptr);
RunConfiguration *rc = m_creator(parent);
QTC_ASSERT(rc, return nullptr);
- rc->initialize(idFromMap(map));
if (!rc->fromMap(map)) {
delete rc;
rc = nullptr;
@@ -560,13 +541,16 @@ bool IRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map
return id.name().startsWith(m_runConfigBaseId.name());
}
-RunConfiguration *IRunConfigurationFactory::clone(Target *parent, RunConfiguration *product)
+RunConfiguration *IRunConfigurationFactory::clone(Target *parent, RunConfiguration *product) const
{
QTC_ASSERT(m_creator, return nullptr);
if (!canClone(parent, product))
return nullptr;
RunConfiguration *runConfig = m_creator(parent);
- runConfig->copyFrom(product);
+
+ QVariantMap data = product->toMap();
+ runConfig->fromMap(data);
+
return runConfig;
}
@@ -590,7 +574,7 @@ QList<IRunConfigurationFactory *> IRunConfigurationFactory::find(Target *parent)
{
return ExtensionSystem::PluginManager::getObjects<IRunConfigurationFactory>(
[&parent](IRunConfigurationFactory *factory) {
- return !factory->availableCreationIds(parent).isEmpty();
+ return !factory->availableCreators(parent).isEmpty();
});
}
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index f9166d8312..740e400a40 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -47,6 +47,7 @@ namespace ProjectExplorer {
class Abi;
class BuildConfiguration;
class IRunConfigurationAspect;
+class IRunConfigurationFactory;
class RunConfiguration;
class RunConfigWidget;
class RunControl;
@@ -262,9 +263,7 @@ signals:
protected:
friend class IRunConfigurationFactory;
- RunConfiguration(Target *target);
- virtual void initialize(Core::Id id);
- void copyFrom(const RunConfiguration *source);
+ RunConfiguration(Target *target, Core::Id id);
/// convenience function to get current build configuration.
BuildConfiguration *activeBuildConfiguration() const;
@@ -274,9 +273,24 @@ protected:
private:
static void addAspectFactory(const AspectFactory &aspectFactory);
+ friend class IRunConfigurationFactory;
+
QList<IRunConfigurationAspect *> m_aspects;
};
+class RunConfigurationCreationInfo
+{
+public:
+ RunConfigurationCreationInfo(const IRunConfigurationFactory *factory, Core::Id id,
+ QString extra, QString displayName)
+ : factory(factory) , id(id) , extra(extra) , displayName(displayName) {}
+
+ const IRunConfigurationFactory *factory = nullptr;
+ Core::Id id;
+ QString extra;
+ QString displayName;
+};
+
class PROJECTEXPLORER_EXPORT IRunConfigurationFactory : public QObject
{
Q_OBJECT
@@ -285,17 +299,17 @@ public:
explicit IRunConfigurationFactory(QObject *parent = nullptr);
enum CreationMode {UserCreate, AutoCreate};
- QList<Core::Id> availableCreationIds(Target *parent, CreationMode mode = UserCreate) const;
- QString displayNameForId(Core::Id id) const;
+
+ QList<RunConfigurationCreationInfo> availableCreators(Target *parent,
+ CreationMode mode = UserCreate) const;
virtual bool canHandle(Target *target) const;
- bool canCreate(Target *parent, Core::Id id) const;
- RunConfiguration *create(Target *parent, Core::Id id);
+ RunConfiguration *create(Target *parent, Core::Id id, const QString &extra) const;
bool canRestore(Target *parent, const QVariantMap &map) const;
- RunConfiguration *restore(Target *parent, const QVariantMap &map);
+ RunConfiguration *restore(Target *parent, const QVariantMap &map) const;
bool canClone(Target *parent, RunConfiguration *product) const;
- RunConfiguration *clone(Target *parent, RunConfiguration *product);
+ RunConfiguration *clone(Target *parent, RunConfiguration *product) const;
static IRunConfigurationFactory *find(Target *parent, const QVariantMap &map);
static IRunConfigurationFactory *find(Target *parent, RunConfiguration *rc);
@@ -309,7 +323,6 @@ protected:
virtual QString displayNameForBuildTarget(const QString &buildTarget) const;
virtual bool canCreateHelper(Target *parent, const QString &buildTarget) const;
- virtual bool canCloneHelper(Target *parent, RunConfiguration *product) const;
using RunConfigurationCreator = std::function<RunConfiguration *(Target *)>;
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
index 7930a78336..5687534756 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
@@ -237,19 +237,19 @@ void RunSettingsWidget::aboutToShowAddMenu()
connect(cloneAction, &QAction::triggered,
this, &RunSettingsWidget::cloneRunConfiguration);
}
- QList<IRunConfigurationFactory *> factories =
+ const QList<IRunConfigurationFactory *> factories =
ExtensionSystem::PluginManager::getObjects<IRunConfigurationFactory>();
QList<QAction *> menuActions;
- foreach (IRunConfigurationFactory *factory, factories) {
- QList<Core::Id> ids = factory->availableCreationIds(m_target);
- foreach (Core::Id id, ids) {
- auto action = new QAction(factory->displayNameForId(id), m_addRunMenu);
- connect(action, &QAction::triggered, [factory, id, this]() {
- RunConfiguration *newRC = factory->create(m_target, id);
+ for (IRunConfigurationFactory *factory : factories) {
+ const QList<RunConfigurationCreationInfo> items = factory->availableCreators(m_target);
+ for (const RunConfigurationCreationInfo &item : items) {
+ auto action = new QAction(item.displayName, m_addRunMenu);
+ connect(action, &QAction::triggered, [item, this] {
+ RunConfiguration *newRC = item.factory->create(m_target, item.id, item.extra);
if (!newRC)
return;
- QTC_CHECK(newRC->id() == id);
+ QTC_CHECK(newRC->id() == item.id);
m_target->addRunConfiguration(newRC);
m_target->setActiveRunConfiguration(newRC);
m_removeRunToolButton->setEnabled(m_target->runConfigurations().size() > 1);
diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp
index 221a8d55a2..33bd4d83f0 100644
--- a/src/plugins/projectexplorer/target.cpp
+++ b/src/plugins/projectexplorer/target.cpp
@@ -115,10 +115,9 @@ QList<DeployConfigurationFactory *> TargetPrivate::deployFactories() const
}
Target::Target(Project *project, Kit *k) :
- ProjectConfiguration(project),
+ ProjectConfiguration(project, k->id()),
d(new TargetPrivate(k))
{
- initialize(k->id());
QTC_CHECK(d->m_kit);
connect(DeviceManager::instance(), &DeviceManager::updated, this, &Target::updateDeviceState);
@@ -547,7 +546,7 @@ void Target::updateDefaultDeployConfigurations()
void Target::updateDefaultRunConfigurations()
{
- QList<IRunConfigurationFactory *> rcFactories = IRunConfigurationFactory::find(this);
+ const QList<IRunConfigurationFactory *> rcFactories = IRunConfigurationFactory::find(this);
if (rcFactories.isEmpty()) {
qWarning("No run configuration factory found for target id '%s'.", qPrintable(id().toString()));
return;
@@ -565,42 +564,46 @@ void Target::updateDefaultRunConfigurations()
int configuredCount = existingConfigured.count();
// find all RC ids that can get created:
- QList<Core::Id> availableFactoryIds;
- foreach (IRunConfigurationFactory *rcFactory, rcFactories)
- availableFactoryIds.append(rcFactory->availableCreationIds(this));
+ QList<RunConfigurationCreationInfo> availableFactories;
+ for (IRunConfigurationFactory *rcFactory : rcFactories)
+ availableFactories.append(rcFactory->availableCreators(this));
- QList<Core::Id> autoCreateFactoryIds;
- foreach (IRunConfigurationFactory *rcFactory, rcFactories)
- autoCreateFactoryIds.append(rcFactory->availableCreationIds(this,
- IRunConfigurationFactory::AutoCreate));
+ QList<RunConfigurationCreationInfo> autoCreateFactories;
+ for (IRunConfigurationFactory *rcFactory : rcFactories)
+ autoCreateFactories.append(rcFactory->availableCreators(this,
+ IRunConfigurationFactory::AutoCreate));
// Put outdated RCs into toRemove, do not bother with factories
// that produce already existing RCs
QList<RunConfiguration *> toRemove;
- QList<Core::Id> toIgnore;
+ QList<RunConfigurationCreationInfo> existing;
foreach (RunConfiguration *rc, existingConfigured) {
- if (availableFactoryIds.contains(rc->id()))
- toIgnore.append(rc->id()); // Already there
- else if (project()->knowsAllBuildExecutables())
- toRemove << rc;
+ bool present = false;
+ for (const RunConfigurationCreationInfo &item : availableFactories) {
+ if (item.id == rc->id() && item.extra == rc->extraId()) {
+ existing.append(item);
+ present = true;
+ }
+ }
+ if (!present && project()->knowsAllBuildExecutables())
+ toRemove.append(rc);
}
- foreach (Core::Id i, toIgnore)
- autoCreateFactoryIds.removeAll(i);
configuredCount -= toRemove.count();
// Create new RCs and put them into newConfigured/newUnconfigured
- foreach (Core::Id id, autoCreateFactoryIds) {
- IRunConfigurationFactory *factory = Utils::findOrDefault(rcFactories,
- [this, id] (IRunConfigurationFactory *i) {
- return i->canCreate(this, id);
- });
- if (!factory)
+ foreach (const RunConfigurationCreationInfo &item, autoCreateFactories) {
+ bool exists = false;
+ for (const RunConfigurationCreationInfo &ex : existing) {
+ if (ex.id == item.id && ex.extra == item.extra)
+ exists = true;
+ }
+ if (exists)
continue;
- RunConfiguration *rc = factory->create(this, id);
+ RunConfiguration *rc = item.factory->create(this, item.id, item.extra);
if (!rc)
continue;
- QTC_CHECK(rc->id() == id);
+ QTC_CHECK(rc->id() == item.id);
if (!rc->isConfigured())
newUnconfigured << rc;
else
@@ -643,7 +646,7 @@ void Target::updateDefaultRunConfigurations()
// Make sure a configured RC will be active after we delete the RCs:
RunConfiguration *active = activeRunConfiguration();
- if (removalList.contains(active) || !active->isEnabled()) {
+ if (active && (removalList.contains(active) || !active->isEnabled())) {
RunConfiguration *newConfiguredDefault = newConfigured.isEmpty() ? nullptr : newConfigured.at(0);
RunConfiguration *rc
@@ -796,7 +799,7 @@ bool Target::fromMap(const QVariantMap &map)
qWarning("Factory '%s' failed to restore deployment configuration!", qPrintable(factory->objectName()));
continue;
}
- QTC_CHECK(dc->id() == ProjectExplorer::idFromMap(valueMap));
+ QTC_CHECK(dc->id().withSuffix(dc->extraId()) == ProjectExplorer::idFromMap(valueMap));
addDeployConfiguration(dc);
if (i == activeConfiguration)
setActiveDeployConfiguration(dc);
@@ -824,7 +827,7 @@ bool Target::fromMap(const QVariantMap &map)
RunConfiguration *rc = factory->restore(this, valueMap);
if (!rc)
continue;
- QTC_CHECK(rc->id() == ProjectExplorer::idFromMap(valueMap));
+ QTC_CHECK(rc->id().withSuffix(rc->extraId()) == ProjectExplorer::idFromMap(valueMap));
addRunConfiguration(rc);
if (i == activeConfiguration)
setActiveRunConfiguration(rc);