diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2023-06-27 16:26:56 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2023-06-30 10:59:01 +0000 |
commit | b1876052bd401bccc816b54f12072548670d5df8 (patch) | |
tree | 8af9ce454ffcdba839688dbaec5c7cb5778d32d4 /src/plugins | |
parent | 1cbd41790691c880794a07ec7b0a192d6cb0e7d8 (diff) |
ProjectExplorer: Do not auto-remove customized run configurations
Until now, it could easily happen that a user's carefully fine-tuned run
configurations disappeared just because of e.g. a temporarily broken
build system file or simply a switch to a different build configuration.
As this is clearly not acceptable, we now make sure customized run
configurations are not thrown away even when there is currently no
matching factory for them.
Fixes: QTCREATORBUG-23163
Fixes: QTCREATORBUG-28273
Change-Id: Ic011a650d15a2897108df986c7e9fe410852e926
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/projectexplorer/projectconfiguration.h | 1 | ||||
-rw-r--r-- | src/plugins/projectexplorer/projectconfigurationmodel.cpp | 20 | ||||
-rw-r--r-- | src/plugins/projectexplorer/runconfiguration.cpp | 41 | ||||
-rw-r--r-- | src/plugins/projectexplorer/runconfiguration.h | 6 | ||||
-rw-r--r-- | src/plugins/projectexplorer/target.cpp | 4 | ||||
-rw-r--r-- | src/plugins/projectexplorer/target.h | 1 |
6 files changed, 65 insertions, 8 deletions
diff --git a/src/plugins/projectexplorer/projectconfiguration.h b/src/plugins/projectexplorer/projectconfiguration.h index 790d9ebf6b..713c187c83 100644 --- a/src/plugins/projectexplorer/projectconfiguration.h +++ b/src/plugins/projectexplorer/projectconfiguration.h @@ -38,6 +38,7 @@ public: bool usesDefaultDisplayName() const { return m_displayName.usesDefaultValue(); } void setDisplayName(const QString &name); void setDefaultDisplayName(const QString &name); + void forceDisplayNameSerialization() { m_displayName.forceSerialization(); } void setToolTip(const QString &text); QString toolTip() const; diff --git a/src/plugins/projectexplorer/projectconfigurationmodel.cpp b/src/plugins/projectexplorer/projectconfigurationmodel.cpp index 61e608dc4b..23b790a494 100644 --- a/src/plugins/projectexplorer/projectconfigurationmodel.cpp +++ b/src/plugins/projectexplorer/projectconfigurationmodel.cpp @@ -5,9 +5,10 @@ #include "buildconfiguration.h" #include "deployconfiguration.h" +#include "projectconfiguration.h" +#include "projectexplorertr.h" #include "runconfiguration.h" #include "target.h" -#include "projectconfiguration.h" #include <utils/algorithm.h> #include <utils/stringutils.h> @@ -30,6 +31,9 @@ static bool isOrderedBefore(const ProjectConfiguration *a, const ProjectConfigur ProjectConfigurationModel::ProjectConfigurationModel(Target *target) : m_target(target) { + connect(target, &Target::runConfigurationsUpdated, this, [this] { + emit dataChanged(index(0, 0), index(rowCount(), 0)); + }); } int ProjectConfigurationModel::rowCount(const QModelIndex &parent) const @@ -87,13 +91,17 @@ void ProjectConfigurationModel::displayNameChanged(ProjectConfiguration *pc) QVariant ProjectConfigurationModel::data(const QModelIndex &index, int role) const { + if (index.row() >= m_projectConfigurations.size()) + return {}; + ProjectConfiguration * const config = m_projectConfigurations.at(index.row()); + if (role == Qt::DisplayRole) { - const int row = index.row(); - if (row < m_projectConfigurations.size()) - return m_projectConfigurations.at(row)->expandedDisplayName(); + QString displayName = config->expandedDisplayName(); + if (const auto rc = qobject_cast<RunConfiguration *>(config); rc && !rc->hasCreator()) + displayName += QString(" [%1]").arg(Tr::tr("unavailable")); + return displayName; } - - return QVariant(); + return {}; } ProjectConfiguration *ProjectConfigurationModel::projectConfigurationAt(int i) const diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 452d07c359..ab6e4fc32f 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -45,6 +45,7 @@ using namespace ProjectExplorer::Internal; namespace ProjectExplorer { const char BUILD_KEY[] = "ProjectExplorer.RunConfiguration.BuildKey"; +const char CUSTOMIZED_KEY[] = "ProjectExplorer.RunConfiguration.Customized"; /////////////////////////////////////////////////////////////////////// // @@ -162,6 +163,7 @@ RunConfiguration::RunConfiguration(Target *target, Utils::Id id) : ProjectConfiguration(target, id) { QTC_CHECK(target && target == this->target()); + forceDisplayNameSerialization(); connect(target, &Target::parsingFinished, this, &RunConfiguration::update); m_expander.setDisplayName(Tr::tr("Run Settings")); @@ -239,6 +241,34 @@ bool RunConfiguration::isConfigured() const return !Utils::anyOf(checkForIssues(), [](const Task &t) { return t.type == Task::Error; }); } +bool RunConfiguration::isCustomized() const +{ + if (m_customized) + return true; + QVariantMap state = toMapSimple(); + + // TODO: Why do we save this at all? It's a computed value. + state.remove("RunConfiguration.WorkingDirectory.default"); + + return state != m_pristineState; +} + +bool RunConfiguration::hasCreator() const +{ + return Utils::contains(RunConfigurationFactory::creatorsForTarget(target()), + [this](const RunConfigurationCreationInfo &info) { + return info.factory->runConfigurationId() == id() && info.buildKey == buildKey(); + }); +} + +void RunConfiguration::setPristineState() +{ + if (!m_customized) { + m_pristineState = toMapSimple(); + m_pristineState.remove("RunConfiguration.WorkingDirectory.default"); + } +} + void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory) { theAspectFactories.push_back(aspectFactory); @@ -277,8 +307,14 @@ Task RunConfiguration::createConfigurationIssue(const QString &description) cons QVariantMap RunConfiguration::toMap() const { - QVariantMap map = ProjectConfiguration::toMap(); + QVariantMap map = toMapSimple(); + map.insert(CUSTOMIZED_KEY, isCustomized()); + return map; +} +QVariantMap RunConfiguration::toMapSimple() const +{ + QVariantMap map = ProjectConfiguration::toMap(); map.insert(BUILD_KEY, m_buildKey); // FIXME: Remove this id mangling, e.g. by using a separate entry for the build key. @@ -344,6 +380,7 @@ bool RunConfiguration::fromMap(const QVariantMap &map) if (!ProjectConfiguration::fromMap(map)) return false; + m_customized = m_customized || map.value(CUSTOMIZED_KEY, false).toBool(); m_buildKey = map.value(BUILD_KEY).toString(); if (m_buildKey.isEmpty()) { @@ -584,6 +621,7 @@ RunConfiguration *RunConfigurationCreationInfo::create(Target *target) const rc->m_buildKey = buildKey; rc->update(); rc->setDisplayName(displayName); + rc->setPristineState(); return rc; } @@ -597,6 +635,7 @@ RunConfiguration *RunConfigurationFactory::restore(Target *parent, const QVarian RunConfiguration *rc = factory->create(parent); if (rc->fromMap(map)) { rc->update(); + rc->setPristineState(); return rc; } delete rc; diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 5970414156..9d9a55120b 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -111,7 +111,10 @@ public: QWidget *createConfigurationWidget(); bool isConfigured() const; + bool isCustomized() const; + bool hasCreator() const; virtual Tasks checkForIssues() const { return {}; } + void setPristineState(); using CommandLineGetter = std::function<Utils::CommandLine()>; void setCommandLineGetter(const CommandLineGetter &cmdGetter); @@ -170,6 +173,7 @@ private: // Any additional data should be handled by aspects. bool fromMap(const QVariantMap &map) final; QVariantMap toMap() const final; + QVariantMap toMapSimple() const; static void addAspectFactory(const AspectFactory &aspectFactory); @@ -182,6 +186,8 @@ private: RunnableModifier m_runnableModifier; Updater m_updater; Utils::MacroExpander m_expander; + QVariantMap m_pristineState; + bool m_customized = false; }; class RunConfigurationCreationInfo diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp index 82d85f84e5..d2f6b3535e 100644 --- a/src/plugins/projectexplorer/target.cpp +++ b/src/plugins/projectexplorer/target.cpp @@ -706,7 +706,7 @@ void Target::updateDefaultRunConfigurations() present = true; } } - if (!present) + if (!present && !rc->isCustomized()) toRemove.append(rc); } configuredCount -= toRemove.count(); @@ -797,6 +797,8 @@ void Target::updateDefaultRunConfigurations() // Remove the RCs that are no longer needed: for (RunConfiguration *rc : std::as_const(removalList)) removeRunConfiguration(rc); + + emit runConfigurationsUpdated(); } QVariant Target::namedSettings(const QString &name) const diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h index 5cfb69eeca..6e4f06abd0 100644 --- a/src/plugins/projectexplorer/target.h +++ b/src/plugins/projectexplorer/target.h @@ -131,6 +131,7 @@ signals: void removedRunConfiguration(ProjectExplorer::RunConfiguration *rc); void addedRunConfiguration(ProjectExplorer::RunConfiguration *rc); void activeRunConfigurationChanged(ProjectExplorer::RunConfiguration *rc); + void runConfigurationsUpdated(); void removedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc); void addedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc); |