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;
BaseAspect::ConfigWidgetCreator m_configWidgetCreator;
QList<QPointer<QWidget>> m_subWidgets;
BaseAspect::DataCreator m_dataCreator;
QList<BaseAspect::DataExtractor> m_dataExtractors;
};
} // Internal
@@ -110,7 +113,9 @@ public:
*/
BaseAspect::BaseAspect()
: d(new Internal::BaseAspectPrivate)
{}
{
addDataExtractor(this, &BaseAspect::value, &Data::value);
}
/*!
Destructs a BaseAspect.
@@ -772,6 +777,9 @@ StringAspect::StringAspect()
{
setDefaultValue(QString());
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);
setSettingsKey(settingsKey);
setSpan(2, 1);
addDataExtractor(this, &BoolAspect::value, &Data::value);
}
/*!
@@ -1747,6 +1757,8 @@ IntegerAspect::IntegerAspect()
{
setDefaultValue(qint64(0));
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

View File

@@ -140,6 +140,30 @@ public:
bool isDirty() 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:
void changed();
void labelLinkActivated(const QString &link);
@@ -149,6 +173,29 @@ protected:
void setupLabel();
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>
Widget *createSubWidget(Args && ...args) {
auto w = new Widget(args...);
@@ -172,6 +219,11 @@ public:
explicit BoolAspect(const QString &settingsKey = QString());
~BoolAspect() override;
struct Data : BaseAspect::Data
{
bool value;
};
void addToLayout(LayoutBuilder &builder) override;
QAction *action() override;
@@ -280,6 +332,12 @@ public:
StringAspect();
~StringAspect() override;
struct Data : BaseAspect::Data
{
QString value;
Utils::FilePath filePath;
};
void addToLayout(LayoutBuilder &builder) override;
QVariant volatileValue() const override;
@@ -373,6 +431,8 @@ public:
void setSpecialValueText(const QString &specialText);
void setSingleStep(qint64 step);
struct Data : BaseAspect::Data { qint64 value = 0; };
private:
std::unique_ptr<Internal::IntegerAspectPrivate> d;
};
@@ -499,6 +559,29 @@ private:
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
{
Q_OBJECT

View File

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

View File

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

View File

@@ -242,8 +242,8 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
auto aspect = runControl->aspect<Debugger::DebuggerRunConfigurationAspect>();
Utils::Id runMode = runControl->runMode();
const bool debuggingMode = runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE;
m_useCppDebugger = debuggingMode && aspect->useCppDebugger();
if (debuggingMode && aspect->useQmlDebugger())
m_useCppDebugger = debuggingMode && aspect->useCppDebugger;
if (debuggingMode && aspect->useQmlDebugger)
m_qmlDebugServices = QmlDebug::QmlDebuggerServices;
else if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE)
m_qmlDebugServices = QmlDebug::QmlProfilerServices;
@@ -270,7 +270,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
m_deviceSerialNumber = AndroidManager::deviceSerialNumber(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"
<< m_extraEnvVars.toStringList();
@@ -279,14 +279,14 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
}
if (auto aspect = runControl->aspect(Constants::ANDROID_AM_START_ARGS)) {
QTC_CHECK(aspect->value().type() == QVariant::String);
const QString startArgs = aspect->value().toString();
QTC_CHECK(aspect->value.type() == QVariant::String);
const QString startArgs = aspect->value.toString();
m_amStartExtraArgs = ProcessArgs::splitArgs(startArgs, OsTypeOtherUnix);
}
if (auto aspect = runControl->aspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) {
QTC_CHECK(aspect->value().type() == QVariant::String);
const QStringList commands = aspect->value().toString().split('\n', Qt::SkipEmptyParts);
QTC_CHECK(aspect->value.type() == QVariant::String);
const QStringList commands = aspect->value.toString().split('\n', Qt::SkipEmptyParts);
for (const QString &shellCmd : commands)
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));
if (auto aspect = runControl->aspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) {
QTC_CHECK(aspect->value().type() == QVariant::String);
const QStringList commands = aspect->value().toString().split('\n', Qt::SkipEmptyParts);
QTC_CHECK(aspect->value.type() == QVariant::String);
const QStringList commands = aspect->value.toString().split('\n', Qt::SkipEmptyParts);
for (const QString &shellCmd : commands)
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>();
QTC_ASSERT(exeAspect, return false);
const FilePath bin = exeAspect->executable();
const FilePath bin = exeAspect->executable;
if (bin.isEmpty()) {
errorMessage = BareMetalDebugSupport::tr(
"Cannot debug: Local executable is not set.");
@@ -184,7 +184,7 @@ bool GdbServerProvider::aboutToRun(DebuggerRunTool *runTool,
inferior.extraData.insert(Debugger::Constants::kPeripheralDescriptionFile,
m_peripheralDescriptionFile.toVariant());
if (const auto argAspect = runControl->aspect<ArgumentsAspect>())
inferior.command.setArguments(argAspect->arguments(runControl->macroExpander()));
inferior.command.setArguments(argAspect->arguments);
runTool->setInferior(inferior);
runTool->setSymbolFile(bin);
runTool->setStartMode(AttachToRemoteServer);

View File

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

View File

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

View File

@@ -182,6 +182,11 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target)
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->setLabel(tr("Enable C++"));
m_cppAspect->setSettingsKey("RunConfiguration.UseCppDebugger");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -100,7 +100,12 @@ public:
CustomParsersAspect(Target *target);
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:
void fromMap(const QVariantMap &map) override;

View File

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

View File

@@ -70,6 +70,11 @@ public:
bool isLocal() const { return m_isLocal; }
struct Data : BaseAspect::Data
{
Utils::Environment environment;
};
signals:
void baseEnvironmentChanged();
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()
{
@@ -264,14 +267,20 @@ void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
theAspectFactories.push_back(aspectFactory);
}
QMap<Utils::Id, QVariantMap> RunConfiguration::aspectData() const
QMap<Utils::Id, QVariantMap> RunConfiguration::settingsData() const
{
QMap<Utils::Id, QVariantMap> data;
for (BaseAspect *aspect : qAsConst(m_aspects))
for (BaseAspect *aspect : m_aspects)
aspect->toActiveMap(data[aspect->id()]);
return data;
}
void RunConfiguration::storeAspectData(AspectContainerData *storage) const
{
for (BaseAspect *aspect : m_aspects)
storage->append(aspect->extractData(&m_expander));
}
BuildSystem *RunConfiguration::activeBuildSystem() const
{
return target()->buildSystem();

View File

@@ -105,6 +105,11 @@ public:
ISettingsAspect *globalSettings() const { return m_globalSettings; }
ISettingsAspect *currentSettings() const;
struct Data : Utils::BaseAspect::Data
{
ISettingsAspect *currentSettings = nullptr;
};
protected:
friend class RunConfiguration;
void fromMap(const QVariantMap &map) override;
@@ -163,7 +168,8 @@ public:
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();
@@ -276,3 +282,5 @@ private:
};
} // namespace ProjectExplorer
Q_DECLARE_METATYPE(ProjectExplorer::ISettingsAspect *);

View File

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

View File

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

View File

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

View File

@@ -229,9 +229,11 @@ public:
Project *project() const;
Kit *kit() const;
const Utils::MacroExpander *macroExpander() const;
Utils::BaseAspect *aspect(Utils::Id id) const;
template <typename T> T *aspect() const {
return runConfiguration() ? runConfiguration()->aspect<T>() : nullptr;
const Utils::BaseAspect::Data *aspect(Utils::Id instanceId) const;
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;

View File

@@ -449,7 +449,8 @@ void QmlPreviewPluginPrivate::setDirty()
void QmlPreviewPluginPrivate::addPreview(ProjectExplorer::RunControl *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,
preview, &ProjectExplorer::RunControl::initiateStop);
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -45,7 +45,7 @@ Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl)
: RunWorker(runControl)
{
setId("Slog2InfoRunner");
m_applicationId = runControl->aspect<ExecutableAspect>()->executable().fileName();
m_applicationId = runControl->aspect<ExecutableAspect>()->executable.fileName();
// See QTCREATORBUG-10712 for details.
// 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());
if (auto aspect = runControl()->aspect<TerminalAspect>())
m_runner.setUseTerminal(aspect->useTerminal());
m_runner.setUseTerminal(aspect->useTerminal);
connect(&m_runner, &ValgrindRunner::processOutputReceived,
this, &ValgrindToolRunner::receiveProcessOutput);

View File

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

View File

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

View File

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