ProjectExplorer: Copy more RunConfiguration data to RunControl

The aspects are now responsible for defining what data needs
to be copied and also to provide a suitable interface (kind
of source-compatible to direct use) for access.

The important change here is that RunControl::aspect(...) doesn't
need to access RunControl::runConfiguration() in fully aspectified
RunConfigurations anymore. In not-fully aspectified the runConfig
access is moved to the user code to make the problem visible there.
Long term, aspectification should be finished.

As an additional benefit, the resolving of macros etc can
now be done at the correct time.

Change-Id: I690d9f8f696ce9b4efd42082ba3f81b514efcb77
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2022-04-08 11:35:54 +02:00
parent 24b4a7be74
commit 530b9ae85a
33 changed files with 282 additions and 54 deletions

View File

@@ -82,6 +82,9 @@ public:
int m_spanY = 1; int m_spanY = 1;
BaseAspect::ConfigWidgetCreator m_configWidgetCreator; BaseAspect::ConfigWidgetCreator m_configWidgetCreator;
QList<QPointer<QWidget>> m_subWidgets; QList<QPointer<QWidget>> m_subWidgets;
BaseAspect::DataCreator m_dataCreator;
QList<BaseAspect::DataExtractor> m_dataExtractors;
}; };
} // Internal } // Internal
@@ -110,7 +113,9 @@ public:
*/ */
BaseAspect::BaseAspect() BaseAspect::BaseAspect()
: d(new Internal::BaseAspectPrivate) : d(new Internal::BaseAspectPrivate)
{} {
addDataExtractor(this, &BaseAspect::value, &Data::value);
}
/*! /*!
Destructs a BaseAspect. Destructs a BaseAspect.
@@ -772,6 +777,9 @@ StringAspect::StringAspect()
{ {
setDefaultValue(QString()); setDefaultValue(QString());
setSpan(2, 1); // Default: Label + something setSpan(2, 1); // Default: Label + something
addDataExtractor(this, &StringAspect::value, &Data::value);
addDataExtractor(this, &StringAspect::filePath, &Data::filePath);
} }
/*! /*!
@@ -1293,6 +1301,8 @@ BoolAspect::BoolAspect(const QString &settingsKey)
setDefaultValue(false); setDefaultValue(false);
setSettingsKey(settingsKey); setSettingsKey(settingsKey);
setSpan(2, 1); setSpan(2, 1);
addDataExtractor(this, &BoolAspect::value, &Data::value);
} }
/*! /*!
@@ -1747,6 +1757,8 @@ IntegerAspect::IntegerAspect()
{ {
setDefaultValue(qint64(0)); setDefaultValue(qint64(0));
setSpan(2, 1); setSpan(2, 1);
addDataExtractor(this, &IntegerAspect::value, &Data::value);
} }
/*! /*!
@@ -2378,4 +2390,43 @@ void AspectContainer::forEachAspect(const std::function<void(BaseAspect *)> &run
} }
} }
BaseAspect::Data *BaseAspect::extractData(const MacroExpander *expander) const
{
QTC_ASSERT(d->m_dataCreator, return nullptr);
Data *data = d->m_dataCreator();
data->m_classId = metaObject();
data->m_id = id();
for (const DataExtractor &extractor : d->m_dataExtractors)
extractor(data, expander);
return data;
}
void BaseAspect::addDataExtractorHelper(const DataExtractor &extractor) const
{
d->m_dataExtractors.append(extractor);
}
void BaseAspect::setDataCreatorHelper(const DataCreator &creator) const
{
d->m_dataCreator = creator;
}
const BaseAspect::Data *AspectContainerData::aspect(Id instanceId) const
{
for (const BaseAspect::Data *data : m_data) {
if (data->id() == instanceId)
return data;
}
return nullptr;
}
const BaseAspect::Data *AspectContainerData::aspect(BaseAspect::Data::ClassId classId) const
{
for (const BaseAspect::Data *data : m_data) {
if (data->classId() == classId)
return data;
}
return nullptr;
}
} // namespace Utils } // namespace Utils

View File

@@ -140,6 +140,30 @@ public:
bool isDirty() const; bool isDirty() const;
bool hasAction() const; bool hasAction() const;
class QTCREATOR_UTILS_EXPORT Data
{
public:
// The (unique) address of the "owning" aspect's meta object is used as identifier.
using ClassId = const void *;
virtual ~Data() = default;
Utils::Id id() const { return m_id; }
ClassId classId() const { return m_classId; }
QVariant value;
protected:
friend class BaseAspect;
Utils::Id m_id;
ClassId m_classId = 0;
};
using DataCreator = std::function<Data *()>;
using DataExtractor = std::function<void(Data *data, const MacroExpander *expander)>;
Data *extractData(const MacroExpander *expander) const;
signals: signals:
void changed(); void changed();
void labelLinkActivated(const QString &link); void labelLinkActivated(const QString &link);
@@ -149,6 +173,29 @@ protected:
void setupLabel(); void setupLabel();
void addLabeledItem(LayoutBuilder &builder, QWidget *widget); void addLabeledItem(LayoutBuilder &builder, QWidget *widget);
void setDataCreatorHelper(const DataCreator &creator) const;
void addDataExtractorHelper(const DataExtractor &extractor) const;
template <typename AspectClass, typename DataClass, typename Type>
void addDataExtractor(AspectClass *aspect,
Type(AspectClass::*p)() const,
Type DataClass::*q) {
setDataCreatorHelper([] { return new DataClass; });
addDataExtractorHelper([aspect, p, q](Data *data, const MacroExpander *) {
static_cast<DataClass *>(data)->*q = (aspect->*p)();
});
}
template <typename AspectClass, typename DataClass, typename Type>
void addDataExtractor(AspectClass *aspect,
Type(AspectClass::*p)(const MacroExpander *) const,
Type DataClass::*q) {
setDataCreatorHelper([] { return new DataClass; });
addDataExtractorHelper([aspect, p, q](Data *data, const MacroExpander *expander) {
static_cast<DataClass *>(data)->*q = (aspect->*p)(expander);
});
}
template <class Widget, typename ...Args> template <class Widget, typename ...Args>
Widget *createSubWidget(Args && ...args) { Widget *createSubWidget(Args && ...args) {
auto w = new Widget(args...); auto w = new Widget(args...);
@@ -172,6 +219,11 @@ public:
explicit BoolAspect(const QString &settingsKey = QString()); explicit BoolAspect(const QString &settingsKey = QString());
~BoolAspect() override; ~BoolAspect() override;
struct Data : BaseAspect::Data
{
bool value;
};
void addToLayout(LayoutBuilder &builder) override; void addToLayout(LayoutBuilder &builder) override;
QAction *action() override; QAction *action() override;
@@ -280,6 +332,12 @@ public:
StringAspect(); StringAspect();
~StringAspect() override; ~StringAspect() override;
struct Data : BaseAspect::Data
{
QString value;
Utils::FilePath filePath;
};
void addToLayout(LayoutBuilder &builder) override; void addToLayout(LayoutBuilder &builder) override;
QVariant volatileValue() const override; QVariant volatileValue() const override;
@@ -373,6 +431,8 @@ public:
void setSpecialValueText(const QString &specialText); void setSpecialValueText(const QString &specialText);
void setSingleStep(qint64 step); void setSingleStep(qint64 step);
struct Data : BaseAspect::Data { qint64 value = 0; };
private: private:
std::unique_ptr<Internal::IntegerAspectPrivate> d; std::unique_ptr<Internal::IntegerAspectPrivate> d;
}; };
@@ -499,6 +559,29 @@ private:
std::unique_ptr<Internal::TextDisplayPrivate> d; std::unique_ptr<Internal::TextDisplayPrivate> d;
}; };
class QTCREATOR_UTILS_EXPORT AspectContainerData
{
public:
AspectContainerData() = default;
~AspectContainerData() { qDeleteAll(m_data); }
const BaseAspect::Data *aspect(Utils::Id instanceId) const;
const BaseAspect::Data *aspect(Utils::BaseAspect::Data::ClassId classId) const;
template <typename T> const typename T::Data *aspect() const
{
return static_cast<const typename T::Data *>(aspect(&T::staticMetaObject));
}
void append(BaseAspect::Data *data) { m_data.append(data); }
private:
AspectContainerData(const AspectContainerData &) = delete;
void operator=(const AspectContainerData &) = delete;
QList<BaseAspect::Data *> m_data;
};
class QTCREATOR_UTILS_EXPORT AspectContainer : public QObject class QTCREATOR_UTILS_EXPORT AspectContainer : public QObject
{ {
Q_OBJECT Q_OBJECT

View File

@@ -119,3 +119,5 @@ public:
}; };
} // namespace Utils } // namespace Utils
Q_DECLARE_METATYPE(Utils::Environment)

View File

@@ -425,7 +425,7 @@ bool AndroidQmlPreviewWorker::startPreviewApp()
const QDir destDir(apkInfo()->uploadDir); const QDir destDir(apkInfo()->uploadDir);
const QString qmlrcPath = destDir.filePath(m_uploadInfo.uploadPackage.baseName() const QString qmlrcPath = destDir.filePath(m_uploadInfo.uploadPackage.baseName()
+ packageSuffix); + packageSuffix);
const QStringList envVars = m_rc->aspect<EnvironmentAspect>()->environment().toStringList(); const QStringList envVars = m_rc->aspect<EnvironmentAspect>()->environment.toStringList();
const QStringList command { const QStringList command {
"am", "start", "am", "start",

View File

@@ -242,8 +242,8 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
auto aspect = runControl->aspect<Debugger::DebuggerRunConfigurationAspect>(); auto aspect = runControl->aspect<Debugger::DebuggerRunConfigurationAspect>();
Utils::Id runMode = runControl->runMode(); Utils::Id runMode = runControl->runMode();
const bool debuggingMode = runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE; const bool debuggingMode = runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE;
m_useCppDebugger = debuggingMode && aspect->useCppDebugger(); m_useCppDebugger = debuggingMode && aspect->useCppDebugger;
if (debuggingMode && aspect->useQmlDebugger()) if (debuggingMode && aspect->useQmlDebugger)
m_qmlDebugServices = QmlDebug::QmlDebuggerServices; m_qmlDebugServices = QmlDebug::QmlDebuggerServices;
else if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) else if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE)
m_qmlDebugServices = QmlDebug::QmlProfilerServices; m_qmlDebugServices = QmlDebug::QmlProfilerServices;
@@ -270,7 +270,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
m_deviceSerialNumber = AndroidManager::deviceSerialNumber(target); m_deviceSerialNumber = AndroidManager::deviceSerialNumber(target);
m_apiLevel = AndroidManager::deviceApiLevel(target); m_apiLevel = AndroidManager::deviceApiLevel(target);
m_extraEnvVars = runControl->aspect<EnvironmentAspect>()->environment(); m_extraEnvVars = runControl->aspect<EnvironmentAspect>()->environment;
qCDebug(androidRunWorkerLog) << "Environment variables for the app" qCDebug(androidRunWorkerLog) << "Environment variables for the app"
<< m_extraEnvVars.toStringList(); << m_extraEnvVars.toStringList();
@@ -279,14 +279,14 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
} }
if (auto aspect = runControl->aspect(Constants::ANDROID_AM_START_ARGS)) { if (auto aspect = runControl->aspect(Constants::ANDROID_AM_START_ARGS)) {
QTC_CHECK(aspect->value().type() == QVariant::String); QTC_CHECK(aspect->value.type() == QVariant::String);
const QString startArgs = aspect->value().toString(); const QString startArgs = aspect->value.toString();
m_amStartExtraArgs = ProcessArgs::splitArgs(startArgs, OsTypeOtherUnix); m_amStartExtraArgs = ProcessArgs::splitArgs(startArgs, OsTypeOtherUnix);
} }
if (auto aspect = runControl->aspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) { if (auto aspect = runControl->aspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) {
QTC_CHECK(aspect->value().type() == QVariant::String); QTC_CHECK(aspect->value.type() == QVariant::String);
const QStringList commands = aspect->value().toString().split('\n', Qt::SkipEmptyParts); const QStringList commands = aspect->value.toString().split('\n', Qt::SkipEmptyParts);
for (const QString &shellCmd : commands) for (const QString &shellCmd : commands)
m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd)); m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
} }
@@ -295,8 +295,8 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd)); m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
if (auto aspect = runControl->aspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) { if (auto aspect = runControl->aspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) {
QTC_CHECK(aspect->value().type() == QVariant::String); QTC_CHECK(aspect->value.type() == QVariant::String);
const QStringList commands = aspect->value().toString().split('\n', Qt::SkipEmptyParts); const QStringList commands = aspect->value.toString().split('\n', Qt::SkipEmptyParts);
for (const QString &shellCmd : commands) for (const QString &shellCmd : commands)
m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd)); m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd));
} }

View File

@@ -166,7 +166,7 @@ bool GdbServerProvider::aboutToRun(DebuggerRunTool *runTool,
const auto exeAspect = runControl->aspect<ExecutableAspect>(); const auto exeAspect = runControl->aspect<ExecutableAspect>();
QTC_ASSERT(exeAspect, return false); QTC_ASSERT(exeAspect, return false);
const FilePath bin = exeAspect->executable(); const FilePath bin = exeAspect->executable;
if (bin.isEmpty()) { if (bin.isEmpty()) {
errorMessage = BareMetalDebugSupport::tr( errorMessage = BareMetalDebugSupport::tr(
"Cannot debug: Local executable is not set."); "Cannot debug: Local executable is not set.");
@@ -184,7 +184,7 @@ bool GdbServerProvider::aboutToRun(DebuggerRunTool *runTool,
inferior.extraData.insert(Debugger::Constants::kPeripheralDescriptionFile, inferior.extraData.insert(Debugger::Constants::kPeripheralDescriptionFile,
m_peripheralDescriptionFile.toVariant()); m_peripheralDescriptionFile.toVariant());
if (const auto argAspect = runControl->aspect<ArgumentsAspect>()) if (const auto argAspect = runControl->aspect<ArgumentsAspect>())
inferior.command.setArguments(argAspect->arguments(runControl->macroExpander())); inferior.command.setArguments(argAspect->arguments);
runTool->setInferior(inferior); runTool->setInferior(inferior);
runTool->setSymbolFile(bin); runTool->setSymbolFile(bin);
runTool->setStartMode(AttachToRemoteServer); runTool->setStartMode(AttachToRemoteServer);

View File

@@ -194,7 +194,7 @@ bool UvscServerProvider::aboutToRun(DebuggerRunTool *runTool, QString &errorMess
const auto exeAspect = runControl->aspect<ExecutableAspect>(); const auto exeAspect = runControl->aspect<ExecutableAspect>();
QTC_ASSERT(exeAspect, return false); QTC_ASSERT(exeAspect, return false);
const FilePath bin = exeAspect->executable(); const FilePath bin = exeAspect->executable;
if (bin.isEmpty()) { if (bin.isEmpty()) {
errorMessage = BareMetalDebugSupport::tr("Cannot debug: Local executable is not set."); errorMessage = BareMetalDebugSupport::tr("Cannot debug: Local executable is not set.");
return false; return false;

View File

@@ -95,6 +95,7 @@ CorePlugin::CorePlugin()
qRegisterMetaType<Core::Search::TextPosition>(); qRegisterMetaType<Core::Search::TextPosition>();
qRegisterMetaType<Utils::CommandLine>(); qRegisterMetaType<Utils::CommandLine>();
qRegisterMetaType<Utils::FilePath>(); qRegisterMetaType<Utils::FilePath>();
qRegisterMetaType<Utils::Environment>();
m_instance = this; m_instance = this;
setupSystemEnvironment(); setupSystemEnvironment();
} }

View File

@@ -182,6 +182,11 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
return builder.emerge(false); return builder.emerge(false);
}); });
addDataExtractor(this, &DebuggerRunConfigurationAspect::useCppDebugger, &Data::useCppDebugger);
addDataExtractor(this, &DebuggerRunConfigurationAspect::useQmlDebugger, &Data::useQmlDebugger);
addDataExtractor(this, &DebuggerRunConfigurationAspect::useMultiProcess, &Data::useMultiProcess);
addDataExtractor(this, &DebuggerRunConfigurationAspect::overrideStartup, &Data::overrideStartup);
m_cppAspect = new DebuggerLanguageAspect; m_cppAspect = new DebuggerLanguageAspect;
m_cppAspect->setLabel(tr("Enable C++")); m_cppAspect->setLabel(tr("Enable C++"));
m_cppAspect->setSettingsKey("RunConfiguration.UseCppDebugger"); m_cppAspect->setSettingsKey("RunConfiguration.UseCppDebugger");

View File

@@ -56,6 +56,14 @@ public:
int portsUsedByDebugger() const; int portsUsedByDebugger() const;
struct Data : BaseAspect::Data
{
bool useCppDebugger;
bool useQmlDebugger;
bool useMultiProcess;
QString overrideStartup;
};
private: private:
Internal::DebuggerLanguageAspect *m_cppAspect; Internal::DebuggerLanguageAspect *m_cppAspect;
Internal::DebuggerLanguageAspect *m_qmlAspect; Internal::DebuggerLanguageAspect *m_qmlAspect;

View File

@@ -868,11 +868,11 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
m_runParameters.displayName = runControl->displayName(); m_runParameters.displayName = runControl->displayName();
if (auto symbolsAspect = runControl->aspect<SymbolFileAspect>()) if (auto symbolsAspect = runControl->aspect<SymbolFileAspect>())
m_runParameters.symbolFile = symbolsAspect->filePath(); m_runParameters.symbolFile = symbolsAspect->filePath;
if (auto terminalAspect = runControl->aspect<TerminalAspect>()) if (auto terminalAspect = runControl->aspect<TerminalAspect>())
m_runParameters.useTerminal = terminalAspect->useTerminal(); m_runParameters.useTerminal = terminalAspect->useTerminal;
if (auto runAsRootAspect = runControl->aspect<RunAsRootAspect>()) if (auto runAsRootAspect = runControl->aspect<RunAsRootAspect>())
m_runParameters.runAsRoot = runAsRootAspect->value(); m_runParameters.runAsRoot = runAsRootAspect->value;
Kit *kit = runControl->kit(); Kit *kit = runControl->kit();
QTC_ASSERT(kit, return); QTC_ASSERT(kit, return);
@@ -886,13 +886,13 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
m_runParameters.qtPackageSourceLocation = qtVersion->qtPackageSourcePath().toString(); m_runParameters.qtPackageSourceLocation = qtVersion->qtPackageSourcePath().toString();
if (auto aspect = runControl->aspect<DebuggerRunConfigurationAspect>()) { if (auto aspect = runControl->aspect<DebuggerRunConfigurationAspect>()) {
if (!aspect->useCppDebugger()) if (!aspect->useCppDebugger)
m_runParameters.cppEngineType = NoEngineType; m_runParameters.cppEngineType = NoEngineType;
m_runParameters.isQmlDebugging = aspect->useQmlDebugger(); m_runParameters.isQmlDebugging = aspect->useQmlDebugger;
m_runParameters.multiProcess = aspect->useMultiProcess(); m_runParameters.multiProcess = aspect->useMultiProcess;
m_runParameters.additionalStartupCommands = aspect->overrideStartup(); m_runParameters.additionalStartupCommands = aspect->overrideStartup;
if (aspect->useCppDebugger()) { if (aspect->useCppDebugger) {
if (DebuggerKitAspect::debugger(kit)) { if (DebuggerKitAspect::debugger(kit)) {
const Tasks tasks = DebuggerKitAspect::validateDebugger(kit); const Tasks tasks = DebuggerKitAspect::validateDebugger(kit);
for (const Task &t : tasks) { for (const Task &t : tasks) {

View File

@@ -92,7 +92,7 @@ public:
const Target *target = runControl->target(); const Target *target = runControl->target();
Runnable r; Runnable r;
r.command = {cmakeFilePath(target), r.command = {cmakeFilePath(target),
runControl->runConfiguration()->aspect<StringAspect>()->value(), runControl->aspect<StringAspect>()->value,
CommandLine::Raw}; CommandLine::Raw};
r.workingDirectory = target->activeBuildConfiguration()->buildDirectory(); r.workingDirectory = target->activeBuildConfiguration()->buildDirectory();
r.environment = target->activeBuildConfiguration()->environment(); r.environment = target->activeBuildConfiguration()->environment();

View File

@@ -115,9 +115,9 @@ public:
{ {
setId("LocalPerfRecordWorker"); setId("LocalPerfRecordWorker");
auto perfAspect = static_cast<PerfRunConfigurationAspect *>(runControl->aspect(Constants::PerfSettingsId)); auto perfAspect = runControl->aspect<PerfRunConfigurationAspect>();
QTC_ASSERT(perfAspect, return); QTC_ASSERT(perfAspect, return);
PerfSettings *settings = static_cast<PerfSettings *>(perfAspect->currentSettings()); PerfSettings *settings = static_cast<PerfSettings *>(perfAspect->currentSettings);
QTC_ASSERT(settings, return); QTC_ASSERT(settings, return);
m_perfRecordArguments = settings->perfRecordArguments(); m_perfRecordArguments = settings->perfRecordArguments();
} }

View File

@@ -182,6 +182,7 @@ CustomParsersAspect::CustomParsersAspect(Target *target)
setId("CustomOutputParsers"); setId("CustomOutputParsers");
setSettingsKey("CustomOutputParsers"); setSettingsKey("CustomOutputParsers");
setDisplayName(tr("Custom Output Parsers")); setDisplayName(tr("Custom Output Parsers"));
addDataExtractor(this, &CustomParsersAspect::parsers, &Data::parsers);
setConfigWidgetCreator([this] { setConfigWidgetCreator([this] {
const auto widget = new Internal::CustomParsersSelectionWidget; const auto widget = new Internal::CustomParsersSelectionWidget;
widget->setSelectedParsers(m_parsers); widget->setSelectedParsers(m_parsers);

View File

@@ -100,7 +100,12 @@ public:
CustomParsersAspect(Target *target); CustomParsersAspect(Target *target);
void setParsers(const QList<Utils::Id> &parsers) { m_parsers = parsers; } void setParsers(const QList<Utils::Id> &parsers) { m_parsers = parsers; }
const QList<Utils::Id> parsers() const { return m_parsers; } QList<Utils::Id> parsers() const { return m_parsers; }
struct Data : BaseAspect::Data
{
QList<Utils::Id> parsers;
};
private: private:
void fromMap(const QVariantMap &map) override; void fromMap(const QVariantMap &map) override;

View File

@@ -46,6 +46,7 @@ EnvironmentAspect::EnvironmentAspect()
setDisplayName(tr("Environment")); setDisplayName(tr("Environment"));
setId("EnvironmentAspect"); setId("EnvironmentAspect");
setConfigWidgetCreator([this] { return new EnvironmentAspectWidget(this); }); setConfigWidgetCreator([this] { return new EnvironmentAspectWidget(this); });
addDataExtractor(this, &EnvironmentAspect::environment, &Data::environment);
} }
int EnvironmentAspect::baseEnvironmentBase() const int EnvironmentAspect::baseEnvironmentBase() const

View File

@@ -70,6 +70,11 @@ public:
bool isLocal() const { return m_isLocal; } bool isLocal() const { return m_isLocal; }
struct Data : BaseAspect::Data
{
Utils::Environment environment;
};
signals: signals:
void baseEnvironmentChanged(); void baseEnvironmentChanged();
void userEnvironmentChangesChanged(const Utils::EnvironmentItems &diff); void userEnvironmentChangesChanged(const Utils::EnvironmentItems &diff);

View File

@@ -93,7 +93,10 @@ void ISettingsAspect::setConfigWidgetCreator(const ConfigWidgetCreator &configWi
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
GlobalOrProjectAspect::GlobalOrProjectAspect() = default; GlobalOrProjectAspect::GlobalOrProjectAspect()
{
addDataExtractor(this, &GlobalOrProjectAspect::currentSettings, &Data::currentSettings);
}
GlobalOrProjectAspect::~GlobalOrProjectAspect() GlobalOrProjectAspect::~GlobalOrProjectAspect()
{ {
@@ -264,14 +267,20 @@ void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
theAspectFactories.push_back(aspectFactory); theAspectFactories.push_back(aspectFactory);
} }
QMap<Utils::Id, QVariantMap> RunConfiguration::aspectData() const QMap<Utils::Id, QVariantMap> RunConfiguration::settingsData() const
{ {
QMap<Utils::Id, QVariantMap> data; QMap<Utils::Id, QVariantMap> data;
for (BaseAspect *aspect : qAsConst(m_aspects)) for (BaseAspect *aspect : m_aspects)
aspect->toActiveMap(data[aspect->id()]); aspect->toActiveMap(data[aspect->id()]);
return data; return data;
} }
void RunConfiguration::storeAspectData(AspectContainerData *storage) const
{
for (BaseAspect *aspect : m_aspects)
storage->append(aspect->extractData(&m_expander));
}
BuildSystem *RunConfiguration::activeBuildSystem() const BuildSystem *RunConfiguration::activeBuildSystem() const
{ {
return target()->buildSystem(); return target()->buildSystem();

View File

@@ -105,6 +105,11 @@ public:
ISettingsAspect *globalSettings() const { return m_globalSettings; } ISettingsAspect *globalSettings() const { return m_globalSettings; }
ISettingsAspect *currentSettings() const; ISettingsAspect *currentSettings() const;
struct Data : Utils::BaseAspect::Data
{
ISettingsAspect *currentSettings = nullptr;
};
protected: protected:
friend class RunConfiguration; friend class RunConfiguration;
void fromMap(const QVariantMap &map) override; void fromMap(const QVariantMap &map) override;
@@ -163,7 +168,8 @@ public:
addAspectFactory([](Target *target) { return new T(target); }); addAspectFactory([](Target *target) { return new T(target); });
} }
QMap<Utils::Id, QVariantMap> aspectData() const; QMap<Utils::Id, QVariantMap> settingsData() const; // FIXME: Merge into aspectData?
void storeAspectData(Utils::AspectContainerData *storage) const;
void update(); void update();
@@ -276,3 +282,5 @@ private:
}; };
} // namespace ProjectExplorer } // namespace ProjectExplorer
Q_DECLARE_METATYPE(ProjectExplorer::ISettingsAspect *);

View File

@@ -65,6 +65,8 @@ TerminalAspect::TerminalAspect()
setDisplayName(tr("Terminal")); setDisplayName(tr("Terminal"));
setId("TerminalAspect"); setId("TerminalAspect");
setSettingsKey("RunConfiguration.UseTerminal"); setSettingsKey("RunConfiguration.UseTerminal");
addDataExtractor(this, &TerminalAspect::useTerminal, &Data::useTerminal);
addDataExtractor(this, &TerminalAspect::isUserSet, &Data::isUserSet);
calculateUseTerminal(); calculateUseTerminal();
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged, connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
this, &TerminalAspect::calculateUseTerminal); this, &TerminalAspect::calculateUseTerminal);
@@ -320,6 +322,9 @@ ArgumentsAspect::ArgumentsAspect()
setDisplayName(tr("Arguments")); setDisplayName(tr("Arguments"));
setId("ArgumentsAspect"); setId("ArgumentsAspect");
setSettingsKey("RunConfiguration.Arguments"); setSettingsKey("RunConfiguration.Arguments");
addDataExtractor(this, &ArgumentsAspect::arguments, &Data::arguments);
m_labelText = tr("Command line arguments:"); m_labelText = tr("Command line arguments:");
} }
@@ -514,6 +519,9 @@ ExecutableAspect::ExecutableAspect()
setDisplayName(tr("Executable")); setDisplayName(tr("Executable"));
setId("ExecutableAspect"); setId("ExecutableAspect");
setExecutablePathStyle(HostOsInfo::hostOs()); setExecutablePathStyle(HostOsInfo::hostOs());
addDataExtractor(this, &ExecutableAspect::executable, &Data::executable);
m_executable.setPlaceHolderText(tr("<unknown>")); m_executable.setPlaceHolderText(tr("<unknown>"));
m_executable.setLabelText(tr("Executable:")); m_executable.setLabelText(tr("Executable:"));
m_executable.setDisplayStyle(StringAspect::LabelDisplay); m_executable.setDisplayStyle(StringAspect::LabelDisplay);

View File

@@ -55,6 +55,12 @@ public:
bool isUserSet() const; bool isUserSet() const;
struct Data : BaseAspect::Data
{
bool useTerminal;
bool isUserSet;
};
private: private:
void fromMap(const QVariantMap &map) override; void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override; void toMap(QVariantMap &map) const override;
@@ -115,6 +121,11 @@ public:
void setResetter(const std::function<QString()> &resetter); void setResetter(const std::function<QString()> &resetter);
void resetArguments(); void resetArguments();
struct Data : BaseAspect::Data
{
QString arguments;
};
private: private:
void fromMap(const QVariantMap &map) override; void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override; void toMap(QVariantMap &map) const override;
@@ -178,6 +189,11 @@ public:
void setEnvironmentChange(const Utils::EnvironmentChange &change); void setEnvironmentChange(const Utils::EnvironmentChange &change);
void setDisplayStyle(Utils::StringAspect::DisplayStyle style); void setDisplayStyle(Utils::StringAspect::DisplayStyle style);
struct Data : BaseAspect::Data
{
Utils::FilePath executable;
};
protected: protected:
void fromMap(const QVariantMap &map) override; void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override; void toMap(QVariantMap &map) const override;

View File

@@ -351,6 +351,7 @@ public:
Utils::Icon icon; Utils::Icon icon;
const MacroExpander *macroExpander = nullptr; const MacroExpander *macroExpander = nullptr;
QPointer<RunConfiguration> runConfiguration; // Not owned. Avoid use. QPointer<RunConfiguration> runConfiguration; // Not owned. Avoid use.
AspectContainerData aspectData;
QString buildKey; QString buildKey;
QMap<Utils::Id, QVariantMap> settingsData; QMap<Utils::Id, QVariantMap> settingsData;
Utils::Id runConfigId; Utils::Id runConfigId;
@@ -390,7 +391,9 @@ void RunControl::setRunConfiguration(RunConfiguration *runConfig)
d->runnable = runConfig->runnable(); d->runnable = runConfig->runnable();
d->displayName = runConfig->expandedDisplayName(); d->displayName = runConfig->expandedDisplayName();
d->buildKey = runConfig->buildKey(); d->buildKey = runConfig->buildKey();
d->settingsData = runConfig->aspectData(); d->settingsData = runConfig->settingsData();
runConfig->storeAspectData(&d->aspectData);
setTarget(runConfig->target()); setTarget(runConfig->target());
@@ -857,9 +860,8 @@ void RunControlPrivate::showError(const QString &msg)
void RunControl::setupFormatter(OutputFormatter *formatter) const void RunControl::setupFormatter(OutputFormatter *formatter) const
{ {
QList<Utils::OutputLineParser *> parsers = OutputFormatterFactory::createFormatters(target()); QList<Utils::OutputLineParser *> parsers = OutputFormatterFactory::createFormatters(target());
if (const auto customParsersAspect if (const auto customParsersAspect = aspect<CustomParsersAspect>()) {
= (runConfiguration() ? runConfiguration()->aspect<CustomParsersAspect>() : nullptr)) { for (const Id id : qAsConst(customParsersAspect->parsers)) {
for (const Utils::Id id : customParsersAspect->parsers()) {
if (CustomParser * const parser = CustomParser::createFromId(id)) if (CustomParser * const parser = CustomParser::createFromId(id))
parsers << parser; parsers << parser;
} }
@@ -938,12 +940,17 @@ const MacroExpander *RunControl::macroExpander() const
return d->macroExpander; return d->macroExpander;
} }
BaseAspect *RunControl::aspect(Utils::Id id) const const BaseAspect::Data *RunControl::aspect(Id instanceId) const
{ {
return d->runConfiguration ? d->runConfiguration->aspect(id) : nullptr; return d->aspectData.aspect(instanceId);
} }
QVariantMap RunControl::settingsData(Utils::Id id) const const BaseAspect::Data *RunControl::aspect(BaseAspect::Data::ClassId classId) const
{
return d->aspectData.aspect(classId);
}
QVariantMap RunControl::settingsData(Id id) const
{ {
return d->settingsData.value(id); return d->settingsData.value(id);
} }
@@ -1181,9 +1188,9 @@ SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl)
{ {
setId("SimpleTargetRunner"); setId("SimpleTargetRunner");
if (auto terminalAspect = runControl->aspect<TerminalAspect>()) if (auto terminalAspect = runControl->aspect<TerminalAspect>())
m_useTerminal = terminalAspect->useTerminal(); m_useTerminal = terminalAspect->useTerminal;
if (auto runAsRootAspect = runControl->aspect<RunAsRootAspect>()) if (auto runAsRootAspect = runControl->aspect<RunAsRootAspect>())
m_runAsRoot = runAsRootAspect->value(); m_runAsRoot = runAsRootAspect->value;
} }
void SimpleTargetRunner::start() void SimpleTargetRunner::start()

View File

@@ -229,9 +229,11 @@ public:
Project *project() const; Project *project() const;
Kit *kit() const; Kit *kit() const;
const Utils::MacroExpander *macroExpander() const; const Utils::MacroExpander *macroExpander() const;
Utils::BaseAspect *aspect(Utils::Id id) const;
template <typename T> T *aspect() const { const Utils::BaseAspect::Data *aspect(Utils::Id instanceId) const;
return runConfiguration() ? runConfiguration()->aspect<T>() : nullptr; const Utils::BaseAspect::Data *aspect(Utils::BaseAspect::Data::ClassId classId) const;
template <typename T> const typename T::Data *aspect() const {
return dynamic_cast<const typename T::Data *>(aspect(&T::staticMetaObject));
} }
QString buildKey() const; QString buildKey() const;

View File

@@ -449,7 +449,8 @@ void QmlPreviewPluginPrivate::setDirty()
void QmlPreviewPluginPrivate::addPreview(ProjectExplorer::RunControl *preview) void QmlPreviewPluginPrivate::addPreview(ProjectExplorer::RunControl *preview)
{ {
m_runningPreviews.append(preview); m_runningPreviews.append(preview);
if (auto multiLanguageAspect = preview->aspect<QmlProjectManager::QmlMultiLanguageAspect>()) { if (auto multiLanguageAspect =
preview->runConfiguration()->aspect<QmlProjectManager::QmlMultiLanguageAspect>()) {
connect(multiLanguageAspect, &QmlProjectManager::QmlMultiLanguageAspect::changed, connect(multiLanguageAspect, &QmlProjectManager::QmlMultiLanguageAspect::changed,
preview, &ProjectExplorer::RunControl::initiateStop); preview, &ProjectExplorer::RunControl::initiateStop);
} }

View File

@@ -134,8 +134,8 @@ LocalQmlPreviewSupport::LocalQmlPreviewSupport(ProjectExplorer::RunControl *runC
const auto *qmlBuildSystem = qobject_cast<QmlProjectManager::QmlBuildSystem *>(currentTarget->buildSystem()); const auto *qmlBuildSystem = qobject_cast<QmlProjectManager::QmlBuildSystem *>(currentTarget->buildSystem());
if (const auto aspect = runControl->aspect<QmlProjectManager::QmlMainFileAspect>()) { if (const auto aspect = runControl->aspect<QmlProjectManager::QmlMainFileAspect>()) {
const QString mainScript = aspect->mainScript(); const QString mainScript = aspect->mainScript;
const QString currentFile = aspect->currentFile(); const QString currentFile = aspect->currentFile;
const QString mainScriptFromProject = qmlBuildSystem->targetFile( const QString mainScriptFromProject = qmlBuildSystem->targetFile(
Utils::FilePath::fromString(mainScript)).toString(); Utils::FilePath::fromString(mainScript)).toString();

View File

@@ -311,9 +311,8 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
{ {
d->m_toolBusy = true; d->m_toolBusy = true;
auto runControl = runWorker->runControl(); auto runControl = runWorker->runControl();
if (auto aspect = static_cast<QmlProfilerRunConfigurationAspect *>( if (auto aspect = runControl->aspect<QmlProfilerRunConfigurationAspect>()) {
runControl->aspect(Constants::SETTINGS))) { if (auto settings = static_cast<const QmlProfilerSettings *>(aspect->currentSettings)) {
if (auto settings = static_cast<const QmlProfilerSettings *>(aspect->currentSettings())) {
d->m_profilerConnections->setFlushInterval(settings->flushEnabled.value() ? d->m_profilerConnections->setFlushInterval(settings->flushEnabled.value() ?
settings->flushInterval.value() : 0); settings->flushInterval.value() : 0);
d->m_profilerModelManager->setAggregateTraces(settings->aggregateTraces.value()); d->m_profilerModelManager->setAggregateTraces(settings->aggregateTraces.value());

View File

@@ -37,14 +37,14 @@
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <utils/layoutbuilder.h>
#include <utils/mimeutils.h> #include <utils/mimeutils.h>
#include <QComboBox> #include <QComboBox>
#include <utils/layoutbuilder.h>
using namespace Core; using namespace Core;
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils;
namespace QmlProjectManager { namespace QmlProjectManager {
@@ -60,6 +60,9 @@ QmlMainFileAspect::QmlMainFileAspect(Target *target)
: m_target(target) : m_target(target)
, m_scriptFile(M_CURRENT_FILE) , m_scriptFile(M_CURRENT_FILE)
{ {
addDataExtractor(this, &QmlMainFileAspect::mainScript, &Data::mainScript);
addDataExtractor(this, &QmlMainFileAspect::currentFile, &Data::currentFile);
connect(EditorManager::instance(), &EditorManager::currentEditorChanged, connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
this, &QmlMainFileAspect::changeCurrentFile); this, &QmlMainFileAspect::changeCurrentFile);
connect(EditorManager::instance(), &EditorManager::currentDocumentStateChanged, connect(EditorManager::instance(), &EditorManager::currentDocumentStateChanged,

View File

@@ -47,6 +47,7 @@ class QmlBuildSystem;
class QMLPROJECTMANAGER_EXPORT QmlMainFileAspect : public Utils::BaseAspect class QMLPROJECTMANAGER_EXPORT QmlMainFileAspect : public Utils::BaseAspect
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QmlMainFileAspect(ProjectExplorer::Target *target); explicit QmlMainFileAspect(ProjectExplorer::Target *target);
~QmlMainFileAspect() override; ~QmlMainFileAspect() override;
@@ -57,6 +58,12 @@ public:
FileInSettings FileInSettings
}; };
struct Data : BaseAspect::Data
{
QString mainScript;
QString currentFile;
};
void addToLayout(Utils::LayoutBuilder &builder) final; void addToLayout(Utils::LayoutBuilder &builder) final;
void toMap(QVariantMap &map) const final; void toMap(QVariantMap &map) const final;
void fromMap(const QVariantMap &map) final; void fromMap(const QVariantMap &map) final;
@@ -74,7 +81,6 @@ public:
QmlBuildSystem *qmlBuildSystem() const; QmlBuildSystem *qmlBuildSystem() const;
public: public:
ProjectExplorer::Target *m_target = nullptr; ProjectExplorer::Target *m_target = nullptr;
QPointer<QComboBox> m_fileListCombo; QPointer<QComboBox> m_fileListCombo;
QStandardItemModel m_fileListModel; QStandardItemModel m_fileListModel;

View File

@@ -45,7 +45,7 @@ Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl)
: RunWorker(runControl) : RunWorker(runControl)
{ {
setId("Slog2InfoRunner"); setId("Slog2InfoRunner");
m_applicationId = runControl->aspect<ExecutableAspect>()->executable().fileName(); m_applicationId = runControl->aspect<ExecutableAspect>()->executable.fileName();
// See QTCREATORBUG-10712 for details. // See QTCREATORBUG-10712 for details.
// We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info. // We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info.

View File

@@ -87,7 +87,7 @@ void ValgrindToolRunner::start()
m_runner.setDebuggee(runnable()); m_runner.setDebuggee(runnable());
if (auto aspect = runControl()->aspect<TerminalAspect>()) if (auto aspect = runControl()->aspect<TerminalAspect>())
m_runner.setUseTerminal(aspect->useTerminal()); m_runner.setUseTerminal(aspect->useTerminal);
connect(&m_runner, &ValgrindRunner::processOutputReceived, connect(&m_runner, &ValgrindRunner::processOutputReceived,
this, &ValgrindToolRunner::receiveProcessOutput); this, &ValgrindToolRunner::receiveProcessOutput);

View File

@@ -120,7 +120,7 @@ public:
setStarter([this, runControl, portsGatherer] { setStarter([this, runControl, portsGatherer] {
Runnable r; Runnable r;
const QString browserId = const QString browserId =
runControl->aspect<WebBrowserSelectionAspect>()->currentBrowser(); runControl->aspect<WebBrowserSelectionAspect>()->currentBrowser;
r.command = emrunCommand(runControl->runConfiguration(), r.command = emrunCommand(runControl->runConfiguration(),
browserId, browserId,
QString::number(portsGatherer->findEndPoint().port())); QString::number(portsGatherer->findEndPoint().port()));

View File

@@ -89,6 +89,8 @@ WebBrowserSelectionAspect::WebBrowserSelectionAspect(ProjectExplorer::Target *ta
setDisplayName(tr("Web Browser")); setDisplayName(tr("Web Browser"));
setId("WebBrowserAspect"); setId("WebBrowserAspect");
setSettingsKey("RunConfiguration.WebBrowser"); setSettingsKey("RunConfiguration.WebBrowser");
addDataExtractor(this, &WebBrowserSelectionAspect::currentBrowser, &Data::currentBrowser);
} }
void WebBrowserSelectionAspect::addToLayout(LayoutBuilder &builder) void WebBrowserSelectionAspect::addToLayout(LayoutBuilder &builder)

View File

@@ -49,6 +49,11 @@ public:
QString currentBrowser() const; QString currentBrowser() const;
struct Data : BaseAspect::Data
{
QString currentBrowser;
};
private: private:
QComboBox *m_webBrowserComboBox = nullptr; QComboBox *m_webBrowserComboBox = nullptr;
QString m_currentBrowser; QString m_currentBrowser;