Commit c3906f53 authored by Tobias Hunger's avatar Tobias Hunger
Browse files

SettingsAccessor: Factor out issue reporting

Change-Id: I4855fc2c4b3303d6d44d025589117e08bb577aef
Reviewed-by: default avatarDaniel Teske <>
parent de353520
......@@ -46,7 +46,6 @@
#include <utils/qtcprocess.h>
#include <QApplication>
#include <QMessageBox>
using namespace Utils;
......@@ -655,6 +654,106 @@ QVariantMap SettingsAccessor::upgradeSettings(const QVariantMap &data, int toVer
return result;
* Find issues with the settings file and warn the user about them.
* \a data is the data from the settings file.
* \a path is the full path to the settings used.
* \a parent is the widget to be set as parent of any dialogs that are opened.
* Returns \c true if the settings are not usable anymore and \c false otherwise.
SettingsAccessor::ProceedInfo SettingsAccessor::reportIssues(const QVariantMap &data,
const Utils::FileName &path,
QWidget *parent) const
IssueInfo issue = findIssues(data, path);
QMessageBox::Icon icon = QMessageBox::Information;
if (issue.buttons.count() > 1)
icon = QMessageBox::Question;
QMessageBox::StandardButtons buttons = QMessageBox::NoButton;
foreach (QMessageBox::StandardButton b, issue.buttons.keys())
buttons |= b;
if (buttons == QMessageBox::NoButton)
return Continue;
QMessageBox msgBox(icon, issue.title, issue.message, buttons, parent);
if (issue.defaultButton != QMessageBox::NoButton)
if (issue.escapeButton != QMessageBox::NoButton)
int boxAction = msgBox.exec();
return issue.buttons.value(static_cast<QMessageBox::StandardButton>(boxAction));
* Checks \a data located at \a path for issues to be displayed with reportIssues.
* Returns a IssueInfo object which is then used by reportIssues.
SettingsAccessor::IssueInfo SettingsAccessor::findIssues(const QVariantMap &data, const Utils::FileName &path) const
SettingsAccessor::IssueInfo result;
Utils::FileName defaultSettingsPath = project()->projectFilePath();
int version = versionFromMap(data);
if (!path.toFileInfo().exists()) {
return result;
} else if (data.isEmpty() || version < firstSupportedVersion() || version > currentVersion()) {
result.title = QApplication::translate("Utils::SettingsAccessor", "No Valid Settings Found");
result.message = QApplication::translate("Utils::SettingsAccessor",
"<p>No valid settings file could be found.</p>"
"<p>All settings files found in directory \"%1\" "
"were either too new or too old to be read.</p>")
result.buttons.insert(QMessageBox::Ok, DiscardAndContinue);
} else if ((path != defaultSettingsPath) && (version < currentVersion())) {
result.title = QApplication::translate("Utils::SettingsAccessor", "Using Old Settings");
result.message = QApplication::translate("Utils::SettingsAccessor",
"<p>The versioned backup \"%1\" of the settings "
"file is used, because the non-versioned file was "
"created by an incompatible version of Qt Creator.</p>"
"<p>Settings changes made since the last time this "
"version of Qt Creator was used are ignored, and "
"changes made now will <b>not</b> be propagated to "
"the newer version.</p>").arg(path.toUserOutput());
result.buttons.insert(QMessageBox::Ok, Continue);
if (!result.buttons.isEmpty())
return result;
QByteArray readId = environmentIdFromMap(data);
if (!readId.isEmpty() && readId != creatorId()) {
result.title = differentEnvironmentMsg(project()->displayName());
result.message = QApplication::translate("ProjectExplorer::EnvironmentIdAccessor",
"<p>No .user settings file created by this instance "
"of Qt Creator was found.</p>"
"<p>Did you work with this project on another machine or "
"using a different settings path before?</p>"
"<p>Do you still want to load the settings file \"%1\"?</p>")
result.defaultButton = QMessageBox::No;
result.escapeButton = QMessageBox::No;
result.buttons.insert(QMessageBox::Yes, SettingsAccessor::Continue);
result.buttons.insert(QMessageBox::No, SettingsAccessor::DiscardAndContinue);
return result;
QString SettingsAccessor::differentEnvironmentMsg(const QString &projectName)
return QApplication::translate("ProjectExplorer::EnvironmentIdAccessor",
"Settings File for \"%1\" from a different Environment?")
namespace {
// When restoring settings...
......@@ -855,59 +954,13 @@ QVariantMap SettingsAccessor::readUserSettings(QWidget *parent) const
result = d->bestSettings(this, fileList);
if (result.path.isEmpty())
result.path = project()->projectDirectory();
ProceedInfo proceed = reportIssues(, result.path, parent);
if (proceed == DiscardAndContinue)
return QVariantMap();
const QByteArray resultEnvironmentId = environmentIdFromMap(;
// Error handling:
if (!result.isValid()) {
"No valid Settings found"),
"<p>No valid settings file could be found "
"for this installation of Qt Creator.</p>"
"<p>All settings files were either too new or too "
"old to be read.</p>"),
} else if (!resultEnvironmentId.isEmpty() && resultEnvironmentId != creatorId()) {
// Wrong environment!
QMessageBox msgBox(
"Settings File for \"%1\" from a different Environment?")
"<p>No .user settings file created by this instance "
"of Qt Creator was found.</p>"
"<p>Did you work with this project on another machine or "
"using a different settings path before?</p>"
"<p>Do you still want to load the settings file \"%1\"?</p>")
QMessageBox::Yes | QMessageBox::No,
if (msgBox.exec() == QMessageBox::No);
} else if ((result.path.toString() != defaultFileName(m_userSuffix))
&& (versionFromMap( < currentVersion())) {
"Using Old Settings"),
"<p>The versioned backup \"%1\" of the .user settings "
"file is used, because the non-versioned file was "
"created by an incompatible version of Qt Creator.</p>"
"<p>Project settings changes made since "
"the last time this version of Qt Creator was used "
"with this project are ignored, and changes made now "
"will <b>not</b> be propagated to the newer version."
......@@ -33,6 +33,7 @@
#include <utils/fileutils.h>
#include <QVariantMap>
#include <QMessageBox>
namespace Utils { class PersistentSettingsWriter; }
......@@ -65,13 +66,54 @@ public:
bool addVersionUpgrader(Internal::VersionUpgrader *upgrader); // takes ownership of upgrader
enum ProceedInfo { Continue, DiscardAndContinue };
class IssueInfo {
IssueInfo() : defaultButton(QMessageBox::NoButton), escapeButton(QMessageBox::NoButton) { }
IssueInfo(const QString &t, const QString &m,
QMessageBox::StandardButton d = QMessageBox::NoButton,
QMessageBox::StandardButton e = QMessageBox::NoButton,
const QHash<QMessageBox::StandardButton, ProceedInfo> &b
= QHash<QMessageBox::StandardButton, ProceedInfo>()) :
title(t), message(m), defaultButton(d), escapeButton(e), buttons(b)
{ }
IssueInfo(const IssueInfo &other) :
{ }
IssueInfo &operator = (const IssueInfo &other)
title = other.title;
message = other.message;
defaultButton = other.defaultButton;
escapeButton = other.escapeButton;
buttons = other.buttons;
return *this;
QString title;
QString message;
QMessageBox::StandardButton defaultButton;
QMessageBox::StandardButton escapeButton;
QHash<QMessageBox::StandardButton, ProceedInfo> buttons;
QVariantMap readFile(const Utils::FileName &path) const;
QVariantMap upgradeSettings(const QVariantMap &data, int toVersion) const;
ProceedInfo reportIssues(const QVariantMap &data, const Utils::FileName &path, QWidget *parent) const;
virtual QVariantMap prepareSettings(const QVariantMap &data) const;
virtual bool isBetterMatch(const QVariantMap &origData, const QVariantMap &newData) const;
virtual IssueInfo findIssues(const QVariantMap &data, const Utils::FileName &path) const;
QList<Utils::FileName> settingsFiles(const QString &suffix) const;
static QByteArray creatorId();
......@@ -83,6 +125,7 @@ private:
QVariantMap mergeSettings(const QVariantMap &userMap, const QVariantMap &sharedMap) const;
static QByteArray environmentIdFromMap(const QVariantMap &data);
static QString differentEnvironmentMsg(const QString &projectName);
QString m_userSuffix;
QString m_sharedSuffix;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment