Utils: Rework CheckableMessageBox

Remove function overloads, thes are hard to read, to use and to extend.
I'd even argue this should be a plain default ctor and a few setters +
exec(), pretty much like Process::start() nowadays.

Move "decider" magic into a structure that can be filled ad-hoc outside
checkablemessagebox.cpp paving the ground for:

...removing  aspect dependency from CheckableMessageBox, Instead, add a
convenience function to BoolAspect.  Arguably, the latter is not needed
and could be done on the user side.

Use pointers instead of mutable references for in-out parameter.
Makes the "specialness" visible on the user side.

Pass ICore::settings() centrally as done elsewhere to reduce line noise
on the user side.

Change-Id: Ibb366353d1ea35401723fd05ce05672617a0a8fd
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
hjk
2023-05-19 10:09:59 +02:00
parent c0ebf227a7
commit d740a355bb
29 changed files with 129 additions and 319 deletions

View File

@@ -4,6 +4,7 @@
#include "aspects.h" #include "aspects.h"
#include "algorithm.h" #include "algorithm.h"
#include "checkablemessagebox.h"
#include "environment.h" #include "environment.h"
#include "fancylineedit.h" #include "fancylineedit.h"
#include "layoutbuilder.h" #include "layoutbuilder.h"
@@ -1358,11 +1359,10 @@ FilePathAspect::FilePathAspect()
The color aspect is displayed using a QtColorButton. The color aspect is displayed using a QtColorButton.
*/ */
ColorAspect::ColorAspect(const QString &settingsKey) ColorAspect::ColorAspect()
: d(new Internal::ColorAspectPrivate) : d(new Internal::ColorAspectPrivate)
{ {
setDefaultValue(QColor::fromRgb(0, 0, 0)); setDefaultValue(QColor::fromRgb(0, 0, 0));
setSettingsKey(settingsKey);
setSpan(1, 1); setSpan(1, 1);
addDataExtractor(this, &ColorAspect::value, &Data::value); addDataExtractor(this, &ColorAspect::value, &Data::value);
@@ -1587,6 +1587,14 @@ void BoolAspect::setLabelPlacement(BoolAspect::LabelPlacement labelPlacement)
d->m_labelPlacement = labelPlacement; d->m_labelPlacement = labelPlacement;
} }
CheckableDecider BoolAspect::checkableDecider()
{
return CheckableDecider(
[this] { return !value(); },
[this] { setValue(true); }
);
}
/*! /*!
\class Utils::SelectionAspect \class Utils::SelectionAspect
\inmodule QtCreator \inmodule QtCreator

View File

@@ -24,6 +24,7 @@ namespace Utils {
class AspectContainer; class AspectContainer;
class BoolAspect; class BoolAspect;
class CheckableDecider;
namespace Internal { namespace Internal {
class AspectContainerPrivate; class AspectContainerPrivate;
@@ -222,6 +223,7 @@ public:
void addToLayout(Layouting::LayoutItem &parent) override; void addToLayout(Layouting::LayoutItem &parent) override;
std::function<void(QObject *)> groupChecker(); std::function<void(QObject *)> groupChecker();
Utils::CheckableDecider checkableDecider();
QAction *action() override; QAction *action() override;
@@ -255,7 +257,7 @@ class QTCREATOR_UTILS_EXPORT ColorAspect : public BaseAspect
Q_OBJECT Q_OBJECT
public: public:
explicit ColorAspect(const QString &settingsKey = QString()); ColorAspect();
~ColorAspect() override; ~ColorAspect() override;
struct Data : BaseAspect::Data struct Data : BaseAspect::Data

View File

@@ -31,16 +31,19 @@ static const char kDoNotAskAgainKey[] = "DoNotAskAgain";
namespace Utils { namespace Utils {
static QSettings *theSettings;
static QMessageBox::StandardButton exec( static QMessageBox::StandardButton exec(
QWidget *parent, QWidget *parent,
QMessageBox::Icon icon, QMessageBox::Icon icon,
const QString &title, const QString &title,
const QString &text, const QString &text,
std::optional<CheckableMessageBox::Decider> decider, const CheckableDecider &decider,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton, QMessageBox::StandardButton defaultButton,
QMessageBox::StandardButton acceptButton, QMessageBox::StandardButton acceptButton,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides) QMap<QMessageBox::StandardButton, QString> buttonTextOverrides,
const QString &msg)
{ {
QMessageBox msgBox(parent); QMessageBox msgBox(parent);
msgBox.setWindowTitle(title); msgBox.setWindowTitle(title);
@@ -59,18 +62,13 @@ static QMessageBox::StandardButton exec(
} }
} }
if (decider) { if (decider.shouldAskAgain) {
if (!CheckableMessageBox::shouldAskAgain(*decider)) if (!decider.shouldAskAgain())
return acceptButton; return acceptButton;
msgBox.setCheckBox(new QCheckBox); msgBox.setCheckBox(new QCheckBox);
msgBox.checkBox()->setChecked(false); msgBox.checkBox()->setChecked(false);
msgBox.checkBox()->setText(msg);
std::visit(
[&msgBox](auto &&decider) {
msgBox.checkBox()->setText(decider.text);
},
*decider);
} }
msgBox.setStandardButtons(buttons); msgBox.setStandardButtons(buttons);
@@ -81,21 +79,44 @@ static QMessageBox::StandardButton exec(
QMessageBox::StandardButton clickedBtn = msgBox.standardButton(msgBox.clickedButton()); QMessageBox::StandardButton clickedBtn = msgBox.standardButton(msgBox.clickedButton());
if (decider && msgBox.checkBox()->isChecked() if (decider.doNotAskAgain && msgBox.checkBox()->isChecked()
&& (acceptButton == QMessageBox::NoButton || clickedBtn == acceptButton)) && (acceptButton == QMessageBox::NoButton || clickedBtn == acceptButton))
CheckableMessageBox::doNotAskAgain(*decider); decider.doNotAskAgain();
return clickedBtn; return clickedBtn;
} }
CheckableDecider::CheckableDecider(const QString &settingsSubKey)
{
QTC_ASSERT(theSettings, return);
shouldAskAgain = [settingsSubKey] {
theSettings->beginGroup(QLatin1String(kDoNotAskAgainKey));
bool shouldNotAsk = theSettings->value(settingsSubKey, false).toBool();
theSettings->endGroup();
return !shouldNotAsk;
};
doNotAskAgain = [settingsSubKey] {
theSettings->beginGroup(QLatin1String(kDoNotAskAgainKey));
theSettings->setValue(settingsSubKey, true);
theSettings->endGroup();
};
}
CheckableDecider::CheckableDecider(bool *storage)
{
shouldAskAgain = [storage] { return !*storage; };
doNotAskAgain = [storage] { *storage = true; };
}
QMessageBox::StandardButton CheckableMessageBox::question( QMessageBox::StandardButton CheckableMessageBox::question(
QWidget *parent, QWidget *parent,
const QString &title, const QString &title,
const QString &question, const QString &question,
std::optional<Decider> decider, const CheckableDecider &decider,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton, QMessageBox::StandardButton defaultButton,
QMessageBox::StandardButton acceptButton, QMessageBox::StandardButton acceptButton,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides) QMap<QMessageBox::StandardButton, QString> buttonTextOverrides,
const QString &msg)
{ {
return exec(parent, return exec(parent,
QMessageBox::Question, QMessageBox::Question,
@@ -105,17 +126,19 @@ QMessageBox::StandardButton CheckableMessageBox::question(
buttons, buttons,
defaultButton, defaultButton,
acceptButton, acceptButton,
buttonTextOverrides); buttonTextOverrides,
msg.isEmpty() ? msgDoNotAskAgain() : msg);
} }
QMessageBox::StandardButton CheckableMessageBox::information( QMessageBox::StandardButton CheckableMessageBox::information(
QWidget *parent, QWidget *parent,
const QString &title, const QString &title,
const QString &text, const QString &text,
std::optional<Decider> decider, const CheckableDecider &decider,
QMessageBox::StandardButtons buttons, QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton, QMessageBox::StandardButton defaultButton,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides) QMap<QMessageBox::StandardButton, QString> buttonTextOverrides,
const QString &msg)
{ {
return exec(parent, return exec(parent,
QMessageBox::Information, QMessageBox::Information,
@@ -125,82 +148,33 @@ QMessageBox::StandardButton CheckableMessageBox::information(
buttons, buttons,
defaultButton, defaultButton,
QMessageBox::NoButton, QMessageBox::NoButton,
buttonTextOverrides); buttonTextOverrides,
} msg.isEmpty() ? msgDoNotShowAgain() : msg);
void CheckableMessageBox::doNotAskAgain(Decider &decider)
{
std::visit(
[](auto &&decider) {
using T = std::decay_t<decltype(decider)>;
if constexpr (std::is_same_v<T, BoolDecision>) {
decider.doNotAskAgain = true;
} else if constexpr (std::is_same_v<T, SettingsDecision>) {
decider.settings->beginGroup(QLatin1String(kDoNotAskAgainKey));
decider.settings->setValue(decider.settingsSubKey, true);
decider.settings->endGroup();
} else if constexpr (std::is_same_v<T, AspectDecision>) {
decider.aspect.setValue(true);
}
},
decider);
}
bool CheckableMessageBox::shouldAskAgain(const Decider &decider)
{
bool result = std::visit(
[](auto &&decider) {
using T = std::decay_t<decltype(decider)>;
if constexpr (std::is_same_v<T, BoolDecision>) {
return !decider.doNotAskAgain;
} else if constexpr (std::is_same_v<T, SettingsDecision>) {
decider.settings->beginGroup(QLatin1String(kDoNotAskAgainKey));
bool shouldNotAsk = decider.settings->value(decider.settingsSubKey, false).toBool();
decider.settings->endGroup();
return !shouldNotAsk;
} else if constexpr (std::is_same_v<T, AspectDecision>) {
return !decider.aspect.value();
}
},
decider);
return result;
}
bool CheckableMessageBox::shouldAskAgain(QSettings *settings, const QString &key)
{
return shouldAskAgain(make_decider(settings, key));
}
void CheckableMessageBox::doNotAskAgain(QSettings *settings, const QString &key)
{
Decider decider = make_decider(settings, key);
return doNotAskAgain(decider);
} }
/*! /*!
Resets all suppression settings for doNotAskAgainQuestion() found in \a settings, Resets all suppression settings for doNotAskAgainQuestion()
so all these message boxes are shown again. so all these message boxes are shown again.
*/ */
void CheckableMessageBox::resetAllDoNotAskAgainQuestions(QSettings *settings) void CheckableMessageBox::resetAllDoNotAskAgainQuestions()
{ {
QTC_ASSERT(settings, return); QTC_ASSERT(theSettings, return);
settings->beginGroup(QLatin1String(kDoNotAskAgainKey)); theSettings->beginGroup(QLatin1String(kDoNotAskAgainKey));
settings->remove(QString()); theSettings->remove(QString());
settings->endGroup(); theSettings->endGroup();
} }
/*! /*!
Returns whether any message boxes from doNotAskAgainQuestion() are suppressed Returns whether any message boxes from doNotAskAgainQuestion() are suppressed
in the \a settings. in the settings.
*/ */
bool CheckableMessageBox::hasSuppressedQuestions(QSettings *settings) bool CheckableMessageBox::hasSuppressedQuestions()
{ {
QTC_ASSERT(settings, return false); QTC_ASSERT(theSettings, return false);
settings->beginGroup(QLatin1String(kDoNotAskAgainKey)); theSettings->beginGroup(QLatin1String(kDoNotAskAgainKey));
const bool hasSuppressed = !settings->childKeys().isEmpty() const bool hasSuppressed = !theSettings->childKeys().isEmpty()
|| !settings->childGroups().isEmpty(); || !theSettings->childGroups().isEmpty();
settings->endGroup(); theSettings->endGroup();
return hasSuppressed; return hasSuppressed;
} }
@@ -222,4 +196,9 @@ QString CheckableMessageBox::msgDoNotShowAgain()
return Tr::tr("Do not &show again"); return Tr::tr("Do not &show again");
} }
void CheckableMessageBox::initialize(QSettings *settings)
{
theSettings = settings;
}
} // namespace Utils } // namespace Utils

View File

@@ -5,8 +5,6 @@
#include "utils_global.h" #include "utils_global.h"
#include "aspects.h"
#include <QMessageBox> #include <QMessageBox>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -15,208 +13,51 @@ QT_END_NAMESPACE
namespace Utils { namespace Utils {
class CheckableMessageBoxPrivate; class QTCREATOR_UTILS_EXPORT CheckableDecider
{
public:
CheckableDecider() = default;
CheckableDecider(const QString &settingsSubKey);
CheckableDecider(bool *doNotAskAgain);
CheckableDecider(const std::function<bool()> &should, const std::function<void()> &doNot)
: shouldAskAgain(should), doNotAskAgain(doNot)
{}
std::function<bool()> shouldAskAgain;
std::function<void()> doNotAskAgain;
};
class QTCREATOR_UTILS_EXPORT CheckableMessageBox class QTCREATOR_UTILS_EXPORT CheckableMessageBox
{ {
public: public:
struct BoolDecision
{
QString text;
bool &doNotAskAgain;
};
struct SettingsDecision
{
QString text;
QSettings *settings;
QString settingsSubKey;
};
struct AspectDecision
{
QString text;
BoolAspect &aspect;
};
using Decider = std::variant<BoolDecision, SettingsDecision, AspectDecision>;
static Decider make_decider(QSettings *settings,
const QString &settingsSubKey,
const QString &text = msgDoNotAskAgain())
{
return Decider{SettingsDecision{text, settings, settingsSubKey}};
}
static Decider make_decider(bool &doNotAskAgain, const QString &text = msgDoNotAskAgain())
{
return Decider{BoolDecision{text, doNotAskAgain}};
}
static Decider make_decider(BoolAspect &aspect, const QString &text = msgDoNotAskAgain())
{
return Decider{AspectDecision{text, aspect}};
}
static QMessageBox::StandardButton question( static QMessageBox::StandardButton question(
QWidget *parent, QWidget *parent,
const QString &title, const QString &title,
const QString &question, const QString &question,
std::optional<Decider> decider = std::nullopt, const CheckableDecider &decider,
QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No,
QMessageBox::StandardButton defaultButton = QMessageBox::No,
QMessageBox::StandardButton acceptButton = QMessageBox::Yes,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {});
static QMessageBox::StandardButton question(
QWidget *parent,
const QString &title,
const QString &question,
bool &value,
QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No, QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No,
QMessageBox::StandardButton defaultButton = QMessageBox::No, QMessageBox::StandardButton defaultButton = QMessageBox::No,
QMessageBox::StandardButton acceptButton = QMessageBox::Yes, QMessageBox::StandardButton acceptButton = QMessageBox::Yes,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {}, QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {},
const QString &text = msgDoNotAskAgain()) const QString &msg = {});
{
Decider decider = make_decider(value, text);
return CheckableMessageBox::question(parent,
title,
question,
decider,
buttons,
defaultButton,
acceptButton,
buttonTextOverrides);
}
static QMessageBox::StandardButton question(
QWidget *parent,
const QString &title,
const QString &question,
QSettings *settings,
const QString &settingsSubKey,
QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No,
QMessageBox::StandardButton defaultButton = QMessageBox::No,
QMessageBox::StandardButton acceptButton = QMessageBox::Yes,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {},
const QString &text = msgDoNotAskAgain())
{
Decider decider = make_decider(settings, settingsSubKey, text);
return CheckableMessageBox::question(parent,
title,
question,
decider,
buttons,
defaultButton,
acceptButton,
buttonTextOverrides);
}
static QMessageBox::StandardButton question(
QWidget *parent,
const QString &title,
const QString &question,
BoolAspect &aspect,
QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No,
QMessageBox::StandardButton defaultButton = QMessageBox::No,
QMessageBox::StandardButton acceptButton = QMessageBox::Yes,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {},
const QString &text = msgDoNotAskAgain())
{
Decider decider = make_decider(aspect, text);
return CheckableMessageBox::question(parent,
title,
question,
decider,
buttons,
defaultButton,
acceptButton,
buttonTextOverrides);
}
static QMessageBox::StandardButton information( static QMessageBox::StandardButton information(
QWidget *parent, QWidget *parent,
const QString &title, const QString &title,
const QString &text, const QString &text,
std::optional<Decider> decider = std::nullopt, const CheckableDecider &decider,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {});
static QMessageBox::StandardButton information(
QWidget *parent,
const QString &title,
const QString &information,
bool &value,
QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {}, QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {},
const QString &text = msgDoNotAskAgain()) const QString &msg = {});
{
Decider decider = make_decider(value, text);
return CheckableMessageBox::information(parent,
title,
information,
decider,
buttons,
defaultButton,
buttonTextOverrides);
}
static QMessageBox::StandardButton information(
QWidget *parent,
const QString &title,
const QString &information,
QSettings *settings,
const QString &settingsSubKey,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {},
const QString &text = msgDoNotAskAgain())
{
Decider decider = make_decider(settings, settingsSubKey, text);
return CheckableMessageBox::information(parent,
title,
information,
decider,
buttons,
defaultButton,
buttonTextOverrides);
}
static QMessageBox::StandardButton information(
QWidget *parent,
const QString &title,
const QString &information,
BoolAspect &aspect,
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton,
QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {},
const QString &text = msgDoNotAskAgain())
{
Decider decider = make_decider(aspect, text);
return CheckableMessageBox::information(parent,
title,
information,
decider,
buttons,
defaultButton,
buttonTextOverrides);
}
// check and set "ask again" status
static bool shouldAskAgain(const Decider &decider);
static void doNotAskAgain(Decider &decider);
static bool shouldAskAgain(QSettings *settings, const QString &key);
static void doNotAskAgain(QSettings *settings, const QString &key);
// Conversion convenience // Conversion convenience
static void resetAllDoNotAskAgainQuestions(QSettings *settings); static void resetAllDoNotAskAgainQuestions();
static bool hasSuppressedQuestions(QSettings *settings); static bool hasSuppressedQuestions();
static QString msgDoNotAskAgain(); static QString msgDoNotAskAgain();
static QString msgDoNotShowAgain(); static QString msgDoNotShowAgain();
static void initialize(QSettings *settings);
}; };
} // namespace Utils } // namespace Utils

View File

@@ -261,8 +261,7 @@ void BookmarkView::removeAll()
Tr::tr("Remove All Bookmarks"), Tr::tr("Remove All Bookmarks"),
Tr::tr("Are you sure you want to remove all bookmarks from " Tr::tr("Are you sure you want to remove all bookmarks from "
"all files in the current session?"), "all files in the current session?"),
ICore::settings(), QString("RemoveAllBookmarks"))
QLatin1String("RemoveAllBookmarks"))
!= QMessageBox::Yes) != QMessageBox::Yes)
return; return;

View File

@@ -602,8 +602,7 @@ static bool continueDespiteReleaseBuild(const QString &toolName)
return CheckableMessageBox::question(ICore::dialogParent(), return CheckableMessageBox::question(ICore::dialogParent(),
title, title,
message, message,
ICore::settings(), QString("ClangToolsCorrectModeWarning"))
"ClangToolsCorrectModeWarning")
== QMessageBox::Yes; == QMessageBox::Yes;
} }

View File

@@ -141,8 +141,7 @@ void showHintAboutBuildBeforeAnalysis()
Utils::CheckableMessageBox::information(Core::ICore::dialogParent(), Utils::CheckableMessageBox::information(Core::ICore::dialogParent(),
Tr::tr("Info About Build the Project Before Analysis"), Tr::tr("Info About Build the Project Before Analysis"),
hintAboutBuildBeforeAnalysis(), hintAboutBuildBeforeAnalysis(),
Core::ICore::settings(), QString("ClangToolsDisablingBuildBeforeAnalysisHint"));
"ClangToolsDisablingBuildBeforeAnalysisHint");
} }
FilePath fullPath(const FilePath &executable) FilePath fullPath(const FilePath &executable)

View File

@@ -594,7 +594,7 @@ void CMakeBuildSettingsWidget::reconfigureWithInitialParameters()
Core::ICore::dialogParent(), Core::ICore::dialogParent(),
Tr::tr("Re-configure with Initial Parameters"), Tr::tr("Re-configure with Initial Parameters"),
Tr::tr("Clear CMake configuration and configure with initial parameters?"), Tr::tr("Clear CMake configuration and configure with initial parameters?"),
settings->askBeforeReConfigureInitialParams, settings->askBeforeReConfigureInitialParams.checkableDecider(),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes); QMessageBox::Yes);

View File

@@ -238,7 +238,7 @@ void CMakeManager::reloadCMakePresets()
Tr::tr("Reload CMake Presets"), Tr::tr("Reload CMake Presets"),
Tr::tr("Re-generates the CMake presets kits. The manual " Tr::tr("Re-generates the CMake presets kits. The manual "
"CMake project modifications will be lost."), "CMake project modifications will be lost."),
settings->askBeforePresetsReload, settings->askBeforePresetsReload.checkableDecider(),
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes | QMessageBox::Cancel,
QMessageBox::Yes, QMessageBox::Yes,
QMessageBox::Yes, QMessageBox::Yes,

View File

@@ -148,6 +148,7 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage)
Theme::setInitialPalette(theme); // Initialize palette before setting it Theme::setInitialPalette(theme); // Initialize palette before setting it
setCreatorTheme(theme); setCreatorTheme(theme);
InfoBar::initialize(ICore::settings()); InfoBar::initialize(ICore::settings());
CheckableMessageBox::initialize(ICore::settings());
new ActionManager(this); new ActionManager(this);
ActionManager::setPresentationModeEnabled(args.presentationMode); ActionManager::setPresentationModeEnabled(args.presentationMode);
m_mainWindow = new MainWindow; m_mainWindow = new MainWindow;

View File

@@ -753,7 +753,7 @@ bool EditorManagerPrivate::skipOpeningBigTextFile(const FilePath &filePath)
.arg(fileSizeInMB, 0, 'f', 2); .arg(fileSizeInMB, 0, 'f', 2);
bool askAgain = true; bool askAgain = true;
auto decider = CheckableMessageBox::make_decider(askAgain); CheckableDecider decider(&askAgain);
QMessageBox::StandardButton clickedButton QMessageBox::StandardButton clickedButton
= CheckableMessageBox::question(ICore::dialogParent(), title, text, decider); = CheckableMessageBox::question(ICore::dialogParent(), title, text, decider);

View File

@@ -226,14 +226,13 @@ void GeneralSettingsWidget::resetInterfaceColor()
void GeneralSettingsWidget::resetWarnings() void GeneralSettingsWidget::resetWarnings()
{ {
InfoBar::clearGloballySuppressed(); InfoBar::clearGloballySuppressed();
CheckableMessageBox::resetAllDoNotAskAgainQuestions(ICore::settings()); CheckableMessageBox::resetAllDoNotAskAgainQuestions();
m_resetWarningsButton->setEnabled(false); m_resetWarningsButton->setEnabled(false);
} }
bool GeneralSettingsWidget::canResetWarnings() bool GeneralSettingsWidget::canResetWarnings()
{ {
return InfoBar::anyGloballySuppressed() return InfoBar::anyGloballySuppressed() || CheckableMessageBox::hasSuppressedQuestions();
|| CheckableMessageBox::hasSuppressedQuestions(ICore::settings());
} }
void GeneralSettingsWidget::resetLanguage() void GeneralSettingsWidget::resetLanguage()

View File

@@ -63,8 +63,7 @@ static bool askForCreating(const QString &title, const FilePath &filePath)
= CheckableMessageBox::question(ICore::dialogParent(), = CheckableMessageBox::question(ICore::dialogParent(),
title, title,
Tr::tr("Create \"%1\"?").arg(filePath.shortNativePath()), Tr::tr("Create \"%1\"?").arg(filePath.shortNativePath()),
ICore::settings(), QString(kAlwaysCreate),
kAlwaysCreate,
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes | QMessageBox::Cancel,
QMessageBox::Cancel, QMessageBox::Cancel,
QMessageBox::Yes, QMessageBox::Yes,

View File

@@ -2697,8 +2697,7 @@ void BreakpointManager::executeDeleteAllBreakpointsDialog()
Tr::tr("Remove All Breakpoints"), Tr::tr("Remove All Breakpoints"),
Tr::tr("Are you sure you want to remove all breakpoints " Tr::tr("Are you sure you want to remove all breakpoints "
"from all files in the current session?"), "from all files in the current session?"),
ICore::settings(), QString("RemoveAllBreakpoints"));
"RemoveAllBreakpoints");
if (pressed != QMessageBox::Yes) if (pressed != QMessageBox::Yes)
return; return;

View File

@@ -2265,8 +2265,7 @@ void CdbEngine::checkQtSdkPdbFiles(const QString &module)
CheckableMessageBox::information(Core::ICore::dialogParent(), CheckableMessageBox::information(Core::ICore::dialogParent(),
Tr::tr("Missing Qt Debug Information"), Tr::tr("Missing Qt Debug Information"),
message, message,
Core::ICore::settings(), QString("CdbQtSdkPdbHint"));
"CdbQtSdkPdbHint");
showMessage("Missing Qt Debug Information Files package for " + qtName, LogMisc); showMessage("Missing Qt Debug Information Files package for " + qtName, LogMisc);
}; };
@@ -2294,8 +2293,7 @@ void CdbEngine::parseOutputLine(QString line)
"Make sure that your antivirus solution is up to date and if that does not work " "Make sure that your antivirus solution is up to date and if that does not work "
"consider adding an exception for %1.") "consider adding an exception for %1.")
.arg(m_extensionFileName), .arg(m_extensionFileName),
Core::ICore::settings(), QString("SecureInfoCdbextCannotBeLoaded"));
"SecureInfoCdbextCannotBeLoaded");
notifyEngineSetupFailed(); notifyEngineSetupFailed();
} }
static const QString creatorExtPrefix = "<qtcreatorcdbext>|"; static const QString creatorExtPrefix = "<qtcreatorcdbext>|";

View File

@@ -2716,17 +2716,14 @@ Context CppDebuggerEngine::languageContext() const
void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp) void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
{ {
static const QString warnOnInappropriateDebuggerKey = "DebuggerWarnOnInappropriateDebugger"; static const QString warnOnInappropriateDebuggerKey = "DebuggerWarnOnInappropriateDebugger";
QtcSettings *coreSettings = Core::ICore::settings();
const bool warnOnRelease = debuggerSettings()->warnOnReleaseBuilds.value() const bool warnOnRelease = debuggerSettings()->warnOnReleaseBuilds.value()
&& rp.toolChainAbi.osFlavor() != Abi::AndroidLinuxFlavor; && rp.toolChainAbi.osFlavor() != Abi::AndroidLinuxFlavor;
bool warnOnInappropriateDebugger = false; bool warnOnInappropriateDebugger = false;
QString detailedWarning; QString detailedWarning;
auto shouldAskAgain = CheckableMessageBox::make_decider(coreSettings,
warnOnInappropriateDebuggerKey);
switch (rp.toolChainAbi.binaryFormat()) { switch (rp.toolChainAbi.binaryFormat()) {
case Abi::PEFormat: { case Abi::PEFormat: {
if (CheckableMessageBox::shouldAskAgain(shouldAskAgain)) { if (CheckableDecider(warnOnInappropriateDebuggerKey).shouldAskAgain()) {
QString preferredDebugger; QString preferredDebugger;
if (rp.toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) { if (rp.toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) {
if (rp.cppEngineType == CdbEngineType) if (rp.cppEngineType == CdbEngineType)
@@ -2766,7 +2763,7 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
break; break;
} }
case Abi::ElfFormat: { case Abi::ElfFormat: {
if (CheckableMessageBox::shouldAskAgain(shouldAskAgain)) { if (CheckableDecider(warnOnInappropriateDebuggerKey).shouldAskAgain()) {
if (rp.cppEngineType == CdbEngineType) { if (rp.cppEngineType == CdbEngineType) {
warnOnInappropriateDebugger = true; warnOnInappropriateDebugger = true;
detailedWarning = Tr::tr( detailedWarning = Tr::tr(
@@ -2879,7 +2876,7 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
"Examining symbols and setting breakpoints by file name and line number " "Examining symbols and setting breakpoints by file name and line number "
"may fail.\n") "may fail.\n")
+ '\n' + detailedWarning, + '\n' + detailedWarning,
shouldAskAgain); warnOnInappropriateDebuggerKey);
} else if (warnOnRelease) { } else if (warnOnRelease) {
AsynchronousMessageBox::information(Tr::tr("Warning"), AsynchronousMessageBox::information(Tr::tr("Warning"),
Tr::tr("This does not seem to be a \"Debug\" build.\n" Tr::tr("This does not seem to be a \"Debug\" build.\n"

View File

@@ -2243,8 +2243,7 @@ bool wantRunTool(ToolMode toolMode, const QString &toolName)
if (Utils::CheckableMessageBox::question(ICore::dialogParent(), if (Utils::CheckableMessageBox::question(ICore::dialogParent(),
title, title,
message, message,
ICore::settings(), QString("AnalyzerCorrectModeWarning"))
"AnalyzerCorrectModeWarning")
!= QMessageBox::Yes) != QMessageBox::Yes)
return false; return false;
} }

View File

@@ -620,7 +620,7 @@ void DebuggerRunTool::start()
CheckableMessageBox::information(Core::ICore::dialogParent(), CheckableMessageBox::information(Core::ICore::dialogParent(),
Tr::tr("Debugger"), Tr::tr("Debugger"),
warningMessage, warningMessage,
doNotShowAgain, &doNotShowAgain,
QMessageBox::Ok); QMessageBox::Ok);
} }
} }

View File

@@ -2576,8 +2576,7 @@ void WatchModel::clearWatches()
ICore::dialogParent(), ICore::dialogParent(),
Tr::tr("Remove All Expression Evaluators"), Tr::tr("Remove All Expression Evaluators"),
Tr::tr("Are you sure you want to remove all expression evaluators?"), Tr::tr("Are you sure you want to remove all expression evaluators?"),
ICore::settings(), QString("RemoveAllWatchers"));
"RemoveAllWatchers");
if (ret != QMessageBox::Yes) if (ret != QMessageBox::Yes)
return; return;

View File

@@ -1297,8 +1297,7 @@ QStringList GitClient::setupCheckoutArguments(const FilePath &workingDirectory,
ICore::dialogParent() /*parent*/, ICore::dialogParent() /*parent*/,
Tr::tr("Create Local Branch") /*title*/, Tr::tr("Create Local Branch") /*title*/,
Tr::tr("Would you like to create a local branch?") /*message*/, Tr::tr("Would you like to create a local branch?") /*message*/,
ICore::settings(), QString("Git.CreateLocalBranchOnCheckout"), /* decider */
"Git.CreateLocalBranchOnCheckout" /*setting*/,
QMessageBox::Yes | QMessageBox::No /*buttons*/, QMessageBox::Yes | QMessageBox::No /*buttons*/,
QMessageBox::No /*default button*/, QMessageBox::No /*default button*/,
QMessageBox::No /*button to save*/) QMessageBox::No /*button to save*/)

View File

@@ -1057,8 +1057,9 @@ bool RunControl::showPromptToStopDialog(const QString &title,
if (!cancelButtonText.isEmpty()) if (!cancelButtonText.isEmpty())
buttonTexts[QMessageBox::Cancel] = cancelButtonText; buttonTexts[QMessageBox::Cancel] = cancelButtonText;
std::optional<CheckableMessageBox::Decider> decider CheckableDecider decider;
= prompt ? make_optional(CheckableMessageBox::make_decider(*prompt)) : std::nullopt; if (prompt)
decider = CheckableDecider(prompt);
auto selected = CheckableMessageBox::question(Core::ICore::dialogParent(), auto selected = CheckableMessageBox::question(Core::ICore::dialogParent(),
title, title,

View File

@@ -663,8 +663,7 @@ AlignDistribute::Dimension AlignDistribute::getDimension(Target target) const
bool AlignDistribute::executePixelPerfectDialog() const bool AlignDistribute::executePixelPerfectDialog() const
{ {
auto decider = Utils::CheckableMessageBox::make_decider(Core::ICore::settings(), Utils::CheckableDecider decider(QString("WarnAboutPixelPerfectDistribution"));
"WarnAboutPixelPerfectDistribution");
QMessageBox::StandardButton pressed = Utils::CheckableMessageBox::question( QMessageBox::StandardButton pressed = Utils::CheckableMessageBox::question(
Core::ICore::dialogParent(), Core::ICore::dialogParent(),

View File

@@ -302,8 +302,7 @@ void SquishNavigationWidget::onRecordTestCase(const QString &suiteName, const QS
Tr::tr("Do you want to record over the test case \"%1\"? The existing content will " Tr::tr("Do you want to record over the test case \"%1\"? The existing content will "
"be overwritten by the recorded script.") "be overwritten by the recorded script.")
.arg(testCase), .arg(testCase),
Core::ICore::settings(), QString("RecordWithoutApproval"));
"RecordWithoutApproval");
if (pressed != QMessageBox::Yes) if (pressed != QMessageBox::Yes)
return; return;

View File

@@ -489,8 +489,7 @@ private:
void StudioWelcomePlugin::closeSplashScreen() void StudioWelcomePlugin::closeSplashScreen()
{ {
Utils::CheckableMessageBox::doNotAskAgain(Core::ICore::settings(), Utils::CheckableDecider(DO_NOT_SHOW_SPLASHSCREEN_AGAIN_KEY).doNotAskAgain();
DO_NOT_SHOW_SPLASHSCREEN_AGAIN_KEY);
if (!s_viewWindow.isNull()) if (!s_viewWindow.isNull())
s_viewWindow->deleteLater(); s_viewWindow->deleteLater();
@@ -538,8 +537,7 @@ static bool showSplashScreen()
return true; return true;
} }
return Utils::CheckableMessageBox::shouldAskAgain(Core::ICore::settings(), return Utils::CheckableDecider(DO_NOT_SHOW_SPLASHSCREEN_AGAIN_KEY).shouldAskAgain();
DO_NOT_SHOW_SPLASHSCREEN_AGAIN_KEY);
} }
void StudioWelcomePlugin::extensionsInitialized() void StudioWelcomePlugin::extensionsInitialized()

View File

@@ -808,8 +808,7 @@ void MemcheckToolPrivate::heobAction()
.arg( .arg(
"<a " "<a "
"href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"), "href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"),
ICore::settings(), QString("HeobDwarfstackInfo"),
"HeobDwarfstackInfo",
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Ok) QMessageBox::Ok)
!= QMessageBox::Ok) != QMessageBox::Ok)

View File

@@ -26,11 +26,10 @@ const char kTakeTourSetting[] = "TakeUITour";
namespace Welcome { namespace Welcome {
namespace Internal { namespace Internal {
void IntroductionWidget::askUserAboutIntroduction(QWidget *parent, QSettings *settings) void IntroductionWidget::askUserAboutIntroduction(QWidget *parent)
{ {
auto decider = CheckableMessageBox::make_decider(settings, kTakeTourSetting);
// CheckableMessageBox for compatibility with Qt Creator < 4.11 // CheckableMessageBox for compatibility with Qt Creator < 4.11
if (!CheckableMessageBox::shouldAskAgain(decider) if (!CheckableDecider(QString(kTakeTourSetting)).shouldAskAgain()
|| !Core::ICore::infoBar()->canInfoBeAdded(kTakeTourSetting)) || !Core::ICore::infoBar()->canInfoBeAdded(kTakeTourSetting))
return; return;

View File

@@ -11,7 +11,6 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QLabel; class QLabel;
class QSettings;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Welcome { namespace Welcome {
@@ -31,7 +30,7 @@ class IntroductionWidget : public QWidget
public: public:
explicit IntroductionWidget(QWidget *parent = nullptr); explicit IntroductionWidget(QWidget *parent = nullptr);
static void askUserAboutIntroduction(QWidget *parent, QSettings *settings); static void askUserAboutIntroduction(QWidget *parent);
protected: protected:
bool event(QEvent *e) override; bool event(QEvent *e) override;

View File

@@ -132,8 +132,7 @@ public:
if (!arguments.contains("-notour")) { if (!arguments.contains("-notour")) {
connect(ICore::instance(), &ICore::coreOpened, this, []() { connect(ICore::instance(), &ICore::coreOpened, this, []() {
IntroductionWidget::askUserAboutIntroduction(ICore::dialogParent(), IntroductionWidget::askUserAboutIntroduction(ICore::dialogParent());
ICore::settings());
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
} }

View File

@@ -209,6 +209,8 @@ bool CrashHandlerDialog::runDebuggerWhileBacktraceNotFinished()
QSettings::UserScope, QSettings::UserScope,
QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR), QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR),
QLatin1String(SettingsApplication)); QLatin1String(SettingsApplication));
Utils::CheckableMessageBox::initialize(&settings);
// Ask user. // Ask user.
const QString title = tr("Run Debugger And Abort Collecting Backtrace?"); const QString title = tr("Run Debugger And Abort Collecting Backtrace?");
const QString message = tr( const QString message = tr(
@@ -222,9 +224,7 @@ bool CrashHandlerDialog::runDebuggerWhileBacktraceNotFinished()
= Utils::CheckableMessageBox::question(this, = Utils::CheckableMessageBox::question(this,
title, title,
message, message,
&settings, QString(SettingsKeySkipWarningAbortingBacktrace),
QLatin1String(
SettingsKeySkipWarningAbortingBacktrace),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes | QMessageBox::No,
QMessageBox::No); QMessageBox::No);