ProjectExplorer: Try harder not to lose custom project settings

... when a kit disappears.
This can easily happen, for instance due to a Qt version update via the
installer, and until now resulted in the disappearance of all user
customizations of build and run configurations.
We now store some additional data when serializing a target, and use it
to recreate a kit of the same type upon restoring. While the resulting
configurations are not guaranteed to be functional, they should contain
all the customizations, which the user can then copy over to a proper
kit.

Fixes: QTCREATORBUG-23023
Change-Id: I659d52808b2f8a308e6aa094e8ef2ee60d586952
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-03-10 15:52:15 +01:00
parent 3b5fc296f2
commit 4657563e4a
3 changed files with 34 additions and 4 deletions

View File

@@ -31,6 +31,7 @@
#include "deployconfiguration.h"
#include "editorconfiguration.h"
#include "kit.h"
#include "kitinformation.h"
#include "makestep.h"
#include "projectexplorer.h"
#include "projectmacroexpander.h"
@@ -39,6 +40,7 @@
#include "runcontrol.h"
#include "session.h"
#include "target.h"
#include "taskhub.h"
#include "userfileaccessor.h"
#include <coreplugin/idocument.h>
@@ -57,6 +59,7 @@
#include <utils/macroexpander.h>
#include <utils/pointeralgorithm.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
#include <QFileDialog>
@@ -757,8 +760,22 @@ void Project::createTargetFromMap(const QVariantMap &map, int index)
Kit *k = KitManager::kit(id);
if (!k) {
qWarning("Warning: No kit '%s' found. Continuing.", qPrintable(id.toString()));
return;
Core::Id deviceTypeId = Core::Id::fromSetting(targetMap.value(Target::deviceTypeKey()));
if (!deviceTypeId.isValid())
deviceTypeId = Constants::DESKTOP_DEVICE_TYPE;
const QString formerKitName = targetMap.value(Target::displayNameKey()).toString();
k = KitManager::registerKit([deviceTypeId, &formerKitName](Kit *kit) {
const QString tempKitName = Utils::makeUniquelyNumbered(
tr("Replacement for \"%1\"").arg(formerKitName),
Utils::transform(KitManager::kits(), &Kit::unexpandedDisplayName));
kit->setUnexpandedDisplayName(tempKitName);
DeviceTypeKitAspect::setDeviceTypeId(kit, deviceTypeId);
kit->setup();
}, id);
TaskHub::addTask(BuildSystemTask(Task::Warning, tr("Project \"%1\" was configured for "
"kit \"%2\" with id %3, which does not exist anymore. The new kit \"%4\" was "
"created in its place, in an attempt not to lose custom project settings.")
.arg(displayName(), formerKitName, id.toString(), k->displayName())));
}
auto t = std::make_unique<Target>(this, k, Target::_constructor_tag{});

View File

@@ -259,6 +259,16 @@ QString Target::toolTip() const
return d->m_kit->toHtml();
}
QString Target::displayNameKey()
{
return QString("ProjectExplorer.ProjectConfiguration.DisplayName");
}
QString Target::deviceTypeKey()
{
return QString("DeviceType");
}
void Target::addBuildConfiguration(BuildConfiguration *bc)
{
QTC_ASSERT(bc && !d->m_buildConfigurations.contains(bc), return);
@@ -499,15 +509,15 @@ QVariantMap Target::toMap() const
return QVariantMap();
QVariantMap map;
map.insert(displayNameKey(), displayName());
map.insert(deviceTypeKey(), DeviceTypeKitAspect::deviceTypeId(kit()).toSetting());
{
// FIXME: For compatibility within the 4.11 cycle, remove this block later.
// This is only read by older versions of Creator, but even there not actively used.
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";
map.insert(QLatin1String(CONFIGURATION_ID_KEY), id().toSetting());
map.insert(QLatin1String(DISPLAY_NAME_KEY), displayName());
map.insert(QLatin1String(DEFAULT_DISPLAY_NAME_KEY), displayName());
}

View File

@@ -69,6 +69,9 @@ public:
QString displayName() const;
QString toolTip() const;
static QString displayNameKey();
static QString deviceTypeKey();
// Build configuration
void addBuildConfiguration(BuildConfiguration *bc);
bool removeBuildConfiguration(BuildConfiguration *bc);