diff options
author | Marcus Tillmanns <marcus.tillmanns@qt.io> | 2023-04-28 08:39:20 +0200 |
---|---|---|
committer | Marcus Tillmanns <marcus.tillmanns@qt.io> | 2023-05-17 08:01:13 +0000 |
commit | 1fc2459b6219a0163f2a52bb636f6ec473791615 (patch) | |
tree | ad646664e2a7fc3d08def363e94aab1f9108181c /src | |
parent | 29371dc2f3d736b04ee706e2bd2498e8d8ea755a (diff) | |
download | qt-creator-1fc2459b6219a0163f2a52bb636f6ec473791615.tar.gz |
Utils: Unify CheckableMessageBox and make it look more native
Change-Id: I5690c16f38cfd2058e01441283bec28d44cadf75
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src')
23 files changed, 492 insertions, 640 deletions
diff --git a/src/libs/utils/checkablemessagebox.cpp b/src/libs/utils/checkablemessagebox.cpp index 5d3011ff59..92b111ed7c 100644 --- a/src/libs/utils/checkablemessagebox.cpp +++ b/src/libs/utils/checkablemessagebox.cpp @@ -3,6 +3,7 @@ #include "checkablemessagebox.h" +#include "hostosinfo.h" #include "qtcassert.h" #include "utilstr.h" @@ -30,398 +31,159 @@ static const char kDoNotAskAgainKey[] = "DoNotAskAgain"; namespace Utils { -class CheckableMessageBoxPrivate -{ -public: - CheckableMessageBoxPrivate(QDialog *q) - { - QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); - - pixmapLabel = new QLabel(q); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(pixmapLabel->sizePolicy().hasHeightForWidth()); - pixmapLabel->setSizePolicy(sizePolicy); - pixmapLabel->setVisible(false); - pixmapLabel->setFocusPolicy(Qt::NoFocus); - - auto pixmapSpacer = - new QSpacerItem(0, 5, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); - - messageLabel = new QLabel(q); - messageLabel->setMinimumSize(QSize(300, 0)); - messageLabel->setWordWrap(true); - messageLabel->setOpenExternalLinks(true); - messageLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse); - messageLabel->setFocusPolicy(Qt::NoFocus); - messageLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop); - - checkBox = new QCheckBox(q); - checkBox->setText(Tr::tr("Do not ask again")); - - const QString showText = Tr::tr("Show Details..."); - detailsButton = new QPushButton(showText, q); - detailsButton->setAutoDefault(false); - detailsButton->hide(); - detailsText = new QTextEdit(q); - detailsText->hide(); - QObject::connect(detailsButton, &QPushButton::clicked, detailsText, [this, showText] { - detailsText->setVisible(!detailsText->isVisible()); - detailsButton->setText( - detailsText->isVisible() ? Tr::tr("Hide Details...") : showText); - }); - - buttonBox = new QDialogButtonBox(q); - buttonBox->setOrientation(Qt::Horizontal); - buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); - - auto verticalLayout = new QVBoxLayout(); - verticalLayout->addWidget(pixmapLabel); - verticalLayout->addItem(pixmapSpacer); - - auto horizontalLayout_2 = new QHBoxLayout(); - horizontalLayout_2->addLayout(verticalLayout); - horizontalLayout_2->addWidget(messageLabel, 10); - - auto horizontalLayout = new QHBoxLayout(); - horizontalLayout->addWidget(checkBox); - horizontalLayout->addStretch(10); - - auto detailsButtonLayout = new QHBoxLayout; - detailsButtonLayout->addWidget(detailsButton); - detailsButtonLayout->addStretch(10); - - auto verticalLayout_2 = new QVBoxLayout(q); - verticalLayout_2->addLayout(horizontalLayout_2); - verticalLayout_2->addLayout(horizontalLayout); - verticalLayout_2->addLayout(detailsButtonLayout); - verticalLayout_2->addWidget(detailsText, 10); - verticalLayout_2->addStretch(1); - verticalLayout_2->addWidget(buttonBox); - } - - QLabel *pixmapLabel = nullptr; - QLabel *messageLabel = nullptr; - QCheckBox *checkBox = nullptr; - QDialogButtonBox *buttonBox = nullptr; - QAbstractButton *clickedButton = nullptr; - QPushButton *detailsButton = nullptr; - QTextEdit *detailsText = nullptr; - QMessageBox::Icon icon = QMessageBox::NoIcon; -}; - -CheckableMessageBox::CheckableMessageBox(QWidget *parent) : - QDialog(parent), - d(new CheckableMessageBoxPrivate(this)) -{ - setModal(true); - connect(d->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(d->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); - connect(d->buttonBox, &QDialogButtonBox::clicked, - this, [this](QAbstractButton *b) { d->clickedButton = b; }); -} - -CheckableMessageBox::~CheckableMessageBox() -{ - delete d; -} - -QAbstractButton *CheckableMessageBox::clickedButton() const -{ - return d->clickedButton; -} - -QDialogButtonBox::StandardButton CheckableMessageBox::clickedStandardButton() const -{ - if (d->clickedButton) - return d->buttonBox->standardButton(d->clickedButton); - return QDialogButtonBox::NoButton; -} - -QString CheckableMessageBox::text() const -{ - return d->messageLabel->text(); -} - -void CheckableMessageBox::setText(const QString &t) -{ - d->messageLabel->setText(t); -} - -QMessageBox::Icon CheckableMessageBox::icon() const -{ - return d->icon; -} - -// See QMessageBoxPrivate::standardIcon -static QPixmap pixmapForIcon(QMessageBox::Icon icon, QWidget *w) -{ - const QStyle *style = w ? w->style() : QApplication::style(); - const int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, nullptr, w); - QIcon tmpIcon; - switch (icon) { - case QMessageBox::Information: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, nullptr, w); - break; - case QMessageBox::Warning: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, w); - break; - case QMessageBox::Critical: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, nullptr, w); - break; - case QMessageBox::Question: - tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, nullptr, w); - break; - default: - break; - } - if (!tmpIcon.isNull()) { - QWindow *window = nullptr; - if (w) { - window = w->windowHandle(); - if (!window) { - if (const QWidget *nativeParent = w->nativeParentWidget()) - window = nativeParent->windowHandle(); - } +static QMessageBox::StandardButton exec( + QWidget *parent, + QMessageBox::Icon icon, + const QString &title, + const QString &text, + std::optional<CheckableMessageBox::Decider> decider, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton, + QMessageBox::StandardButton acceptButton, + QMap<QMessageBox::StandardButton, QString> buttonTextOverrides) +{ + QMessageBox msgBox(parent); + msgBox.setWindowTitle(title); + msgBox.setIcon(icon); + msgBox.setText(text); + msgBox.setTextFormat(Qt::RichText); + msgBox.setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse); + + if (HostOsInfo::isMacHost()) { + // Message boxes on macOS cannot display links. + // If the message contains a link, we need to disable native dialogs. + if (text.contains("<a ")) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) + msgBox.setOptions(QMessageBox::Option::DontUseNativeDialog); +#endif } - return tmpIcon.pixmap(window, QSize(iconSize, iconSize)); - } - return QPixmap(); -} - -void CheckableMessageBox::setIcon(QMessageBox::Icon icon) -{ - d->icon = icon; - const QPixmap pixmap = pixmapForIcon(icon, this); - d->pixmapLabel->setPixmap(pixmap); - d->pixmapLabel->setVisible(!pixmap.isNull()); -} - -bool CheckableMessageBox::isChecked() const -{ - return d->checkBox->isChecked(); -} - -void CheckableMessageBox::setChecked(bool s) -{ - d->checkBox->setChecked(s); -} - -QString CheckableMessageBox::checkBoxText() const -{ - return d->checkBox->text(); -} - -void CheckableMessageBox::setCheckBoxText(const QString &t) -{ - d->checkBox->setText(t); -} - -bool CheckableMessageBox::isCheckBoxVisible() const -{ - return d->checkBox->isVisible(); -} - -void CheckableMessageBox::setCheckBoxVisible(bool v) -{ - d->checkBox->setVisible(v); -} - -QString CheckableMessageBox::detailedText() const -{ - return d->detailsText->toPlainText(); -} - -void CheckableMessageBox::setDetailedText(const QString &text) -{ - d->detailsText->setText(text); - if (!text.isEmpty()) - d->detailsButton->setVisible(true); -} - -QDialogButtonBox::StandardButtons CheckableMessageBox::standardButtons() const -{ - return d->buttonBox->standardButtons(); -} - -void CheckableMessageBox::setStandardButtons(QDialogButtonBox::StandardButtons s) -{ - d->buttonBox->setStandardButtons(s); -} - -QPushButton *CheckableMessageBox::button(QDialogButtonBox::StandardButton b) const -{ - return d->buttonBox->button(b); -} - -QPushButton *CheckableMessageBox::addButton(const QString &text, QDialogButtonBox::ButtonRole role) -{ - return d->buttonBox->addButton(text, role); -} - -QDialogButtonBox::StandardButton CheckableMessageBox::defaultButton() const -{ - const QList<QAbstractButton *> buttons = d->buttonBox->buttons(); - for (QAbstractButton *b : buttons) - if (auto *pb = qobject_cast<QPushButton *>(b)) - if (pb->isDefault()) - return d->buttonBox->standardButton(pb); - return QDialogButtonBox::NoButton; -} - -void CheckableMessageBox::setDefaultButton(QDialogButtonBox::StandardButton s) -{ - if (QPushButton *b = d->buttonBox->button(s)) { - b->setDefault(true); - b->setFocus(); } -} - -QDialogButtonBox::StandardButton -CheckableMessageBox::question(QWidget *parent, - const QString &title, - const QString &question, - const QString &checkBoxText, - bool *checkBoxSetting, - QDialogButtonBox::StandardButtons buttons, - QDialogButtonBox::StandardButton defaultButton) -{ - CheckableMessageBox mb(parent); - mb.setWindowTitle(title); - mb.setIcon(QMessageBox::Question); - mb.setText(question); - mb.setCheckBoxText(checkBoxText); - mb.setChecked(*checkBoxSetting); - mb.setStandardButtons(buttons); - mb.setDefaultButton(defaultButton); - mb.exec(); - *checkBoxSetting = mb.isChecked(); - return mb.clickedStandardButton(); -} -QDialogButtonBox::StandardButton -CheckableMessageBox::information(QWidget *parent, - const QString &title, - const QString &text, - const QString &checkBoxText, - bool *checkBoxSetting, - QDialogButtonBox::StandardButtons buttons, - QDialogButtonBox::StandardButton defaultButton) -{ - CheckableMessageBox mb(parent); - mb.setWindowTitle(title); - mb.setIcon(QMessageBox::Information); - mb.setText(text); - mb.setCheckBoxText(checkBoxText); - mb.setChecked(*checkBoxSetting); - mb.setStandardButtons(buttons); - mb.setDefaultButton(defaultButton); - mb.exec(); - *checkBoxSetting = mb.isChecked(); - return mb.clickedStandardButton(); -} - -QMessageBox::StandardButton CheckableMessageBox::dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton db) -{ - return static_cast<QMessageBox::StandardButton>(int(db)); -} - -bool CheckableMessageBox::shouldAskAgain(QSettings *settings, const QString &settingsSubKey) -{ - if (QTC_GUARD(settings)) { - settings->beginGroup(QLatin1String(kDoNotAskAgainKey)); - bool shouldNotAsk = settings->value(settingsSubKey, false).toBool(); - settings->endGroup(); - if (shouldNotAsk) - return false; + if (decider) { + if (!CheckableMessageBox::shouldAskAgain(*decider)) + return acceptButton; + + msgBox.setCheckBox(new QCheckBox); + + std::visit( + [&msgBox](auto &&decider) { + using T = std::decay_t<decltype(decider)>; + msgBox.checkBox()->setText(decider.text); + if constexpr (std::is_same_v<T, CheckableMessageBox::BoolDecision>) { + msgBox.checkBox()->setChecked(decider.value); + } else if constexpr (std::is_same_v<T, CheckableMessageBox::SettingsDecision>) { + msgBox.checkBox()->setChecked( + decider.settings->value(decider.settingsSubKey, false).toBool()); + } else if constexpr (std::is_same_v<T, CheckableMessageBox::AspectDecision>) { + msgBox.checkBox()->setChecked(decider.aspect.value()); + } + }, + *decider); } - return true; -} -enum DoNotAskAgainType{Question, Information}; + msgBox.setStandardButtons(buttons); + msgBox.setDefaultButton(defaultButton); + for (auto it = buttonTextOverrides.constBegin(); it != buttonTextOverrides.constEnd(); ++it) + msgBox.button(it.key())->setText(it.value()); + msgBox.exec(); + + QMessageBox::StandardButton clickedBtn = msgBox.standardButton(msgBox.clickedButton()); + + if (decider && msgBox.checkBox()->isChecked() + && (acceptButton == QMessageBox::NoButton || clickedBtn == acceptButton)) + CheckableMessageBox::doNotAskAgain(*decider); + return clickedBtn; +} + +QMessageBox::StandardButton CheckableMessageBox::question( + QWidget *parent, + const QString &title, + const QString &question, + std::optional<Decider> decider, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton, + QMessageBox::StandardButton acceptButton, + QMap<QMessageBox::StandardButton, QString> buttonTextOverrides) +{ + return exec(parent, + QMessageBox::Question, + title, + question, + decider, + buttons, + defaultButton, + acceptButton, + buttonTextOverrides); +} + +QMessageBox::StandardButton CheckableMessageBox::information( + QWidget *parent, + const QString &title, + const QString &text, + std::optional<Decider> decider, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton, + QMap<QMessageBox::StandardButton, QString> buttonTextOverrides) +{ + return exec(parent, + QMessageBox::Information, + title, + text, + decider, + buttons, + defaultButton, + QMessageBox::NoButton, + buttonTextOverrides); +} + +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.value = 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.value; + } 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); -void initDoNotAskAgainMessageBox(CheckableMessageBox &messageBox, const QString &title, - const QString &text, QDialogButtonBox::StandardButtons buttons, - QDialogButtonBox::StandardButton defaultButton, - DoNotAskAgainType type) -{ - messageBox.setWindowTitle(title); - messageBox.setIcon(type == Information ? QMessageBox::Information : QMessageBox::Question); - messageBox.setText(text); - messageBox.setCheckBoxVisible(true); - messageBox.setCheckBoxText(type == Information ? CheckableMessageBox::msgDoNotShowAgain() - : CheckableMessageBox::msgDoNotAskAgain()); - messageBox.setChecked(false); - messageBox.setStandardButtons(buttons); - messageBox.setDefaultButton(defaultButton); + return result; } -void CheckableMessageBox::doNotAskAgain(QSettings *settings, const QString &settingsSubKey) +bool CheckableMessageBox::shouldAskAgain(QSettings *settings, const QString &key) { - if (!settings) - return; - - settings->beginGroup(QLatin1String(kDoNotAskAgainKey)); - settings->setValue(settingsSubKey, true); - settings->endGroup(); + return shouldAskAgain(make_decider(settings, key)); } -/*! - Shows a message box with given \a title and \a text, and a \gui {Do not ask again} check box. - If the user checks the check box and accepts the dialog with the \a acceptButton, - further invocations of this function with the same \a settings and \a settingsSubKey will not - show the dialog, but instantly return \a acceptButton. - - Returns the clicked button, or QDialogButtonBox::NoButton if the user rejects the dialog - with the escape key, or \a acceptButton if the dialog is suppressed. -*/ -QDialogButtonBox::StandardButton -CheckableMessageBox::doNotAskAgainQuestion(QWidget *parent, const QString &title, - const QString &text, QSettings *settings, - const QString &settingsSubKey, - QDialogButtonBox::StandardButtons buttons, - QDialogButtonBox::StandardButton defaultButton, - QDialogButtonBox::StandardButton acceptButton) - -{ - if (!shouldAskAgain(settings, settingsSubKey)) - return acceptButton; - - CheckableMessageBox messageBox(parent); - initDoNotAskAgainMessageBox(messageBox, title, text, buttons, defaultButton, Question); - messageBox.exec(); - if (messageBox.isChecked() && (messageBox.clickedStandardButton() == acceptButton)) - doNotAskAgain(settings, settingsSubKey); - - return messageBox.clickedStandardButton(); -} - -/*! - Shows a message box with given \a title and \a text, and a \gui {Do not show again} check box. - If the user checks the check box and quits the dialog, further invocations of this - function with the same \a settings and \a settingsSubKey will not show the dialog, but instantly return. - - Returns the clicked button, or QDialogButtonBox::NoButton if the user rejects the dialog - with the escape key, or \a defaultButton if the dialog is suppressed. -*/ -QDialogButtonBox::StandardButton -CheckableMessageBox::doNotShowAgainInformation(QWidget *parent, const QString &title, - const QString &text, QSettings *settings, - const QString &settingsSubKey, - QDialogButtonBox::StandardButtons buttons, - QDialogButtonBox::StandardButton defaultButton) - +void CheckableMessageBox::doNotAskAgain(QSettings *settings, const QString &key) { - if (!shouldAskAgain(settings, settingsSubKey)) - return defaultButton; - - CheckableMessageBox messageBox(parent); - initDoNotAskAgainMessageBox(messageBox, title, text, buttons, defaultButton, Information); - messageBox.exec(); - if (messageBox.isChecked()) - doNotAskAgain(settings, settingsSubKey); - - return messageBox.clickedStandardButton(); + Decider decider = make_decider(settings, key); + return doNotAskAgain(decider); } /*! diff --git a/src/libs/utils/checkablemessagebox.h b/src/libs/utils/checkablemessagebox.h index eb80e15eac..e6988fc8e9 100644 --- a/src/libs/utils/checkablemessagebox.h +++ b/src/libs/utils/checkablemessagebox.h @@ -5,7 +5,8 @@ #include "utils_global.h" -#include <QDialogButtonBox> +#include "aspects.h" + #include <QMessageBox> QT_BEGIN_NAMESPACE @@ -16,100 +17,206 @@ namespace Utils { class CheckableMessageBoxPrivate; -class QTCREATOR_UTILS_EXPORT CheckableMessageBox : public QDialog +class QTCREATOR_UTILS_EXPORT CheckableMessageBox { - Q_OBJECT - Q_PROPERTY(QString text READ text WRITE setText) - Q_PROPERTY(QMessageBox::Icon icon READ icon WRITE setIcon) - Q_PROPERTY(bool isChecked READ isChecked WRITE setChecked) - Q_PROPERTY(QString checkBoxText READ checkBoxText WRITE setCheckBoxText) - Q_PROPERTY(QDialogButtonBox::StandardButtons buttons READ standardButtons WRITE setStandardButtons) - Q_PROPERTY(QDialogButtonBox::StandardButton defaultButton READ defaultButton WRITE setDefaultButton) - public: - explicit CheckableMessageBox(QWidget *parent); - ~CheckableMessageBox() override; - - static QDialogButtonBox::StandardButton - question(QWidget *parent, - const QString &title, - const QString &question, - const QString &checkBoxText, - bool *checkBoxSetting, - QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Yes|QDialogButtonBox::No, - QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::No); - - static QDialogButtonBox::StandardButton - information(QWidget *parent, - const QString &title, - const QString &text, - const QString &checkBoxText, - bool *checkBoxSetting, - QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Ok, - QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::NoButton); - - static QDialogButtonBox::StandardButton - doNotAskAgainQuestion(QWidget *parent, - const QString &title, - const QString &text, - QSettings *settings, - const QString &settingsSubKey, - QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Yes|QDialogButtonBox::No, - QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::No, - QDialogButtonBox::StandardButton acceptButton = QDialogButtonBox::Yes); - - static QDialogButtonBox::StandardButton - doNotShowAgainInformation(QWidget *parent, - const QString &title, - const QString &text, - QSettings *settings, - const QString &settingsSubKey, - QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Ok, - QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::NoButton); - - QString text() const; - void setText(const QString &); - - bool isChecked() const; - void setChecked(bool s); - - QString checkBoxText() const; - void setCheckBoxText(const QString &); - - bool isCheckBoxVisible() const; - void setCheckBoxVisible(bool); - - QString detailedText() const; - void setDetailedText(const QString &text); - - QDialogButtonBox::StandardButtons standardButtons() const; - void setStandardButtons(QDialogButtonBox::StandardButtons s); - QPushButton *button(QDialogButtonBox::StandardButton b) const; - QPushButton *addButton(const QString &text, QDialogButtonBox::ButtonRole role); - - QDialogButtonBox::StandardButton defaultButton() const; - void setDefaultButton(QDialogButtonBox::StandardButton s); - - QMessageBox::Icon icon() const; - void setIcon(QMessageBox::Icon icon); - - // Query the result - QAbstractButton *clickedButton() const; - QDialogButtonBox::StandardButton clickedStandardButton() const; + struct BoolDecision + { + QString text; + bool &value; + }; + + 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 &value, const QString &text = msgDoNotAskAgain()) + { + return Decider{BoolDecision{text, value}}; + } + + static Decider make_decider(BoolAspect &aspect, const QString &text = msgDoNotAskAgain()) + { + return Decider{AspectDecision{text, aspect}}; + } + + static QMessageBox::StandardButton question( + QWidget *parent, + const QString &title, + const QString &question, + std::optional<Decider> decider = std::nullopt, + 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::StandardButton defaultButton = QMessageBox::No, + QMessageBox::StandardButton acceptButton = QMessageBox::Yes, + QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {}, + const QString &text = msgDoNotAskAgain()) + { + 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( + QWidget *parent, + const QString &title, + const QString &text, + std::optional<Decider> decider = std::nullopt, + 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::StandardButton defaultButton = QMessageBox::NoButton, + QMap<QMessageBox::StandardButton, QString> buttonTextOverrides = {}, + const QString &text = msgDoNotAskAgain()) + { + 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(QSettings *settings, const QString &settingsSubKey); - static void doNotAskAgain(QSettings *settings, const QString &settingsSubKey); + 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 - static QMessageBox::StandardButton dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton); static void resetAllDoNotAskAgainQuestions(QSettings *settings); static bool hasSuppressedQuestions(QSettings *settings); static QString msgDoNotAskAgain(); static QString msgDoNotShowAgain(); - -private: - CheckableMessageBoxPrivate *d; }; } // namespace Utils diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index c15cfef221..459edad2bb 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -34,7 +34,6 @@ #endif #include <coreplugin/icore.h> -#include <utils/checkablemessagebox.h> #include <utils/infobar.h> #include <languageclient/languageclientsettings.h> diff --git a/src/plugins/bookmarks/bookmarkmanager.cpp b/src/plugins/bookmarks/bookmarkmanager.cpp index 4e98648147..77bb0f4151 100644 --- a/src/plugins/bookmarks/bookmarkmanager.cpp +++ b/src/plugins/bookmarks/bookmarkmanager.cpp @@ -257,11 +257,13 @@ void BookmarkView::keyPressEvent(QKeyEvent *event) void BookmarkView::removeAll() { - if (CheckableMessageBox::doNotAskAgainQuestion(this, - Tr::tr("Remove All Bookmarks"), - Tr::tr("Are you sure you want to remove all bookmarks from all files in the current session?"), - ICore::settings(), - QLatin1String("RemoveAllBookmarks")) != QDialogButtonBox::Yes) + if (CheckableMessageBox::question(this, + Tr::tr("Remove All Bookmarks"), + Tr::tr("Are you sure you want to remove all bookmarks from " + "all files in the current session?"), + ICore::settings(), + QLatin1String("RemoveAllBookmarks")) + != QMessageBox::Yes) return; // The performance of this function could be greatly improved. diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index a4d2675065..343849458a 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -599,12 +599,12 @@ static bool continueDespiteReleaseBuild(const QString &toolName) "<p>%2</p>" "</body></html>") .arg(problem, question); - return CheckableMessageBox::doNotAskAgainQuestion(ICore::dialogParent(), - title, - message, - ICore::settings(), - "ClangToolsCorrectModeWarning") - == QDialogButtonBox::Yes; + return CheckableMessageBox::question(ICore::dialogParent(), + title, + message, + ICore::settings(), + "ClangToolsCorrectModeWarning") + == QMessageBox::Yes; } void ClangTool::startTool(ClangTool::FileSelection fileSelection, diff --git a/src/plugins/clangtools/clangtoolsutils.cpp b/src/plugins/clangtools/clangtoolsutils.cpp index 7a812d3750..a2cdd5fc7b 100644 --- a/src/plugins/clangtools/clangtoolsutils.cpp +++ b/src/plugins/clangtools/clangtoolsutils.cpp @@ -138,12 +138,11 @@ QString hintAboutBuildBeforeAnalysis() void showHintAboutBuildBeforeAnalysis() { - Utils::CheckableMessageBox::doNotShowAgainInformation( - Core::ICore::dialogParent(), - Tr::tr("Info About Build the Project Before Analysis"), - hintAboutBuildBeforeAnalysis(), - Core::ICore::settings(), - "ClangToolsDisablingBuildBeforeAnalysisHint"); + Utils::CheckableMessageBox::information(Core::ICore::dialogParent(), + Tr::tr("Info About Build the Project Before Analysis"), + hintAboutBuildBeforeAnalysis(), + Core::ICore::settings(), + "ClangToolsDisablingBuildBeforeAnalysisHint"); } FilePath fullPath(const FilePath &executable) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index d7f85a7e44..f425af569c 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -590,23 +590,18 @@ void CMakeBuildSettingsWidget::batchEditConfiguration() void CMakeBuildSettingsWidget::reconfigureWithInitialParameters() { auto settings = CMakeSpecificSettings::instance(); - bool doNotAsk = !settings->askBeforeReConfigureInitialParams.value(); - if (!doNotAsk) { - QDialogButtonBox::StandardButton reply = CheckableMessageBox::question( - Core::ICore::dialogParent(), - Tr::tr("Re-configure with Initial Parameters"), - Tr::tr("Clear CMake configuration and configure with initial parameters?"), - Tr::tr("Do not ask again"), - &doNotAsk, - QDialogButtonBox::Yes | QDialogButtonBox::No, - QDialogButtonBox::Yes); - - settings->askBeforeReConfigureInitialParams.setValue(!doNotAsk); - settings->writeSettings(Core::ICore::settings()); - - if (reply != QDialogButtonBox::Yes) { - return; - } + QMessageBox::StandardButton reply = CheckableMessageBox::question( + Core::ICore::dialogParent(), + Tr::tr("Re-configure with Initial Parameters"), + Tr::tr("Clear CMake configuration and configure with initial parameters?"), + settings->askBeforeReConfigureInitialParams, + QMessageBox::Yes | QMessageBox::No, + QMessageBox::Yes); + + settings->writeSettings(Core::ICore::settings()); + + if (reply != QMessageBox::Yes) { + return; } m_buildSystem->clearCMakeCache(); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index ab7bfb4990..a1950b6bcc 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -232,30 +232,22 @@ void CMakeManager::enableBuildFileMenus(Node *node) void CMakeManager::reloadCMakePresets() { auto settings = CMakeSpecificSettings::instance(); - bool doNotAsk = !settings->askBeforePresetsReload.value(); - if (!doNotAsk) { - CheckableMessageBox question(Core::ICore::dialogParent()); - question.setIcon(QMessageBox::Question); - question.setWindowTitle(Tr::tr("Reload CMake Presets")); - question.setText(Tr::tr("Re-generates the CMake presets kits. The manual CMake project modifications will be lost.")); - question.setCheckBoxText(Tr::tr("Do not ask again")); - question.setCheckBoxVisible(true); - question.setChecked(doNotAsk); - question.setStandardButtons(QDialogButtonBox::Cancel); - - question.addButton(Tr::tr("Reload"), QDialogButtonBox::YesRole); - question.setDefaultButton(QDialogButtonBox::Yes); - question.exec(); - - doNotAsk = question.isChecked(); - - settings->askBeforePresetsReload.setValue(!doNotAsk); - settings->writeSettings(Core::ICore::settings()); - - if (question.clickedStandardButton() == QDialogButtonBox::Cancel) - return; - } + QMessageBox::StandardButton clickedButton + = CheckableMessageBox::question(Core::ICore::dialogParent(), + Tr::tr("Reload CMake Presets"), + Tr::tr("Re-generates the CMake presets kits. The manual " + "CMake project modifications will be lost."), + settings->askBeforePresetsReload, + QMessageBox::Yes | QMessageBox::Cancel, + QMessageBox::Yes, + QMessageBox::Yes, + { + {QMessageBox::Yes, Tr::tr("Reload")}, + }); + + if (clickedButton == QMessageBox::Cancel) + return; CMakeProject *project = static_cast<CMakeProject *>(ProjectTree::currentProject()); if (!project) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 19c6b309f1..107ce249e1 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -752,17 +752,13 @@ bool EditorManagerPrivate::skipOpeningBigTextFile(const FilePath &filePath) .arg(filePath.fileName()) .arg(fileSizeInMB, 0, 'f', 2); - CheckableMessageBox messageBox(ICore::dialogParent()); - messageBox.setWindowTitle(title); - messageBox.setText(text); - messageBox.setStandardButtons(QDialogButtonBox::Yes|QDialogButtonBox::No); - messageBox.setDefaultButton(QDialogButtonBox::No); - messageBox.setIcon(QMessageBox::Question); - messageBox.setCheckBoxVisible(true); - messageBox.setCheckBoxText(CheckableMessageBox::msgDoNotAskAgain()); - messageBox.exec(); - setWarnBeforeOpeningBigFilesEnabled(!messageBox.isChecked()); - return messageBox.clickedStandardButton() != QDialogButtonBox::Yes; + bool askAgain = true; + auto decider = CheckableMessageBox::make_decider(askAgain); + + QMessageBox::StandardButton clickedButton + = CheckableMessageBox::question(ICore::dialogParent(), title, text, decider); + setWarnBeforeOpeningBigFilesEnabled(askAgain); + return clickedButton != QMessageBox::Yes; } return false; diff --git a/src/plugins/coreplugin/locator/filesystemfilter.cpp b/src/plugins/coreplugin/locator/filesystemfilter.cpp index 066be68330..32ad0a2a2b 100644 --- a/src/plugins/coreplugin/locator/filesystemfilter.cpp +++ b/src/plugins/coreplugin/locator/filesystemfilter.cpp @@ -59,25 +59,18 @@ static ILocatorFilter::MatchLevel matchLevelFor(const QRegularExpressionMatch &m static bool askForCreating(const QString &title, const FilePath &filePath) { - if (CheckableMessageBox::shouldAskAgain(ICore::settings(), kAlwaysCreate)) { - CheckableMessageBox messageBox(ICore::dialogParent()); - messageBox.setWindowTitle(title); - messageBox.setIcon(QMessageBox::Question); - messageBox.setText(Tr::tr("Create \"%1\"?").arg(filePath.shortNativePath())); - messageBox.setCheckBoxVisible(true); - messageBox.setCheckBoxText(Tr::tr("Always create")); - messageBox.setChecked(false); - messageBox.setStandardButtons(QDialogButtonBox::Cancel); - QPushButton *createButton = messageBox.addButton(Tr::tr("Create"), - QDialogButtonBox::AcceptRole); - messageBox.setDefaultButton(QDialogButtonBox::Cancel); - messageBox.exec(); - if (messageBox.clickedButton() != createButton) - return false; - if (messageBox.isChecked()) - CheckableMessageBox::doNotAskAgain(ICore::settings(), kAlwaysCreate); - } - return true; + QMessageBox::StandardButton selected + = CheckableMessageBox::question(ICore::dialogParent(), + title, + Tr::tr("Create \"%1\"?").arg(filePath.shortNativePath()), + ICore::settings(), + kAlwaysCreate, + QMessageBox::Yes | QMessageBox::Cancel, + QMessageBox::Cancel, + QMessageBox::Yes, + {{QMessageBox::Yes, Tr::tr("Create")}}, + Tr::tr("Always create")); + return selected == QMessageBox::Yes; } static void createAndOpenFile(const FilePath &filePath) diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index f13ac94d89..2b21db5be5 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -41,6 +41,7 @@ #include <QCheckBox> #include <QComboBox> #include <QDebug> +#include <QDialogButtonBox> #include <QDir> #include <QFormLayout> #include <QGroupBox> @@ -2691,14 +2692,14 @@ void BreakpointManager::gotoLocation(const GlobalBreakpoint &gbp) const void BreakpointManager::executeDeleteAllBreakpointsDialog() { - QDialogButtonBox::StandardButton pressed = - CheckableMessageBox::doNotAskAgainQuestion(ICore::dialogParent(), - Tr::tr("Remove All Breakpoints"), - Tr::tr("Are you sure you want to remove all breakpoints " - "from all files in the current session?"), - ICore::settings(), - "RemoveAllBreakpoints"); - if (pressed != QDialogButtonBox::Yes) + QMessageBox::StandardButton pressed + = CheckableMessageBox::question(ICore::dialogParent(), + Tr::tr("Remove All Breakpoints"), + Tr::tr("Are you sure you want to remove all breakpoints " + "from all files in the current session?"), + ICore::settings(), + "RemoveAllBreakpoints"); + if (pressed != QMessageBox::Yes) return; for (GlobalBreakpoint gbp : globalBreakpoints()) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 9117728f8e..52e6d71fe6 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -2262,12 +2262,11 @@ void CdbEngine::checkQtSdkPdbFiles(const QString &module) "symbols for the debugger.") .arg(qtName); - CheckableMessageBox::doNotShowAgainInformation( - Core::ICore::dialogParent(), - Tr::tr("Missing Qt Debug Information"), - message, - Core::ICore::settings(), - "CdbQtSdkPdbHint"); + CheckableMessageBox::information(Core::ICore::dialogParent(), + Tr::tr("Missing Qt Debug Information"), + message, + Core::ICore::settings(), + "CdbQtSdkPdbHint"); showMessage("Missing Qt Debug Information Files package for " + qtName, LogMisc); }; @@ -2288,7 +2287,7 @@ void CdbEngine::parseOutputLine(QString line) // An extension notification (potentially consisting of several chunks) if (!m_initialSessionIdleHandled && line.startsWith("SECURE: File not allowed to be loaded") && line.endsWith("qtcreatorcdbext.dll")) { - CheckableMessageBox::doNotShowAgainInformation( + CheckableMessageBox::information( Core::ICore::dialogParent(), Tr::tr("Debugger Start Failed"), Tr::tr("The system prevents loading of %1, which is required for debugging. " diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index a59e48ecf9..28d218929a 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -2722,9 +2722,11 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp) && rp.toolChainAbi.osFlavor() != Abi::AndroidLinuxFlavor; bool warnOnInappropriateDebugger = false; QString detailedWarning; + auto shouldAskAgain = CheckableMessageBox::make_decider(coreSettings, + warnOnInappropriateDebuggerKey); switch (rp.toolChainAbi.binaryFormat()) { case Abi::PEFormat: { - if (CheckableMessageBox::shouldAskAgain(coreSettings, warnOnInappropriateDebuggerKey)) { + if (CheckableMessageBox::shouldAskAgain(shouldAskAgain)) { QString preferredDebugger; if (rp.toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) { if (rp.cppEngineType == CdbEngineType) @@ -2764,7 +2766,7 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp) break; } case Abi::ElfFormat: { - if (CheckableMessageBox::shouldAskAgain(coreSettings, warnOnInappropriateDebuggerKey)) { + if (CheckableMessageBox::shouldAskAgain(shouldAskAgain)) { if (rp.cppEngineType == CdbEngineType) { warnOnInappropriateDebugger = true; detailedWarning = Tr::tr( @@ -2870,16 +2872,14 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp) return; } if (warnOnInappropriateDebugger) { - CheckableMessageBox::doNotShowAgainInformation( + CheckableMessageBox::information( Core::ICore::dialogParent(), Tr::tr("Warning"), - Tr::tr( - "The selected debugger may be inappropriate for the inferior.\n" - "Examining symbols and setting breakpoints by file name and line number " - "may fail.\n") + Tr::tr("The selected debugger may be inappropriate for the inferior.\n" + "Examining symbols and setting breakpoints by file name and line number " + "may fail.\n") + '\n' + detailedWarning, - Core::ICore::settings(), - warnOnInappropriateDebuggerKey); + shouldAskAgain); } else if (warnOnRelease) { AsynchronousMessageBox::information(Tr::tr("Warning"), Tr::tr("This does not seem to be a \"Debug\" build.\n" diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index e8c14d4dcc..8b14ff0e23 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2240,10 +2240,13 @@ bool wantRunTool(ToolMode toolMode, const QString &toolName) "or otherwise insufficient output.</p><p>" "Do you want to continue and run the tool in %2 mode?</p></body></html>") .arg(toolName).arg(currentMode).arg(toolModeString); - if (Utils::CheckableMessageBox::doNotAskAgainQuestion(ICore::dialogParent(), - title, message, ICore::settings(), "AnalyzerCorrectModeWarning") - != QDialogButtonBox::Yes) - return false; + if (Utils::CheckableMessageBox::question(ICore::dialogParent(), + title, + message, + ICore::settings(), + "AnalyzerCorrectModeWarning") + != QMessageBox::Yes) + return false; } return true; diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 663ad5bf6d..17da601429 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -616,14 +616,12 @@ void DebuggerRunTool::start() showMessage(warningMessage, LogWarning); - static bool checked = true; - if (checked) - CheckableMessageBox::information(Core::ICore::dialogParent(), - Tr::tr("Debugger"), - warningMessage, - Tr::tr("&Show this message again."), - &checked, - QDialogButtonBox::Ok); + static bool doNotShowAgain = false; + CheckableMessageBox::information(Core::ICore::dialogParent(), + Tr::tr("Debugger"), + warningMessage, + doNotShowAgain, + QMessageBox::Ok); } } diff --git a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp index eb17cba3de..9f3824ffce 100644 --- a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp +++ b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp @@ -9,13 +9,13 @@ #include <coreplugin/icore.h> #include <coreplugin/messagebox.h> -#include <utils/checkablemessagebox.h> #include <utils/pathchooser.h> #include <utils/temporarydirectory.h> #include <QAction> #include <QCheckBox> #include <QDebug> +#include <QDialogButtonBox> #include <QFormLayout> #include <QLabel> #include <QPushButton> diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 739c0ee4ce..d533a0d4f6 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -40,6 +40,7 @@ #include <QApplication> #include <QDebug> +#include <QDialogButtonBox> #include <QFile> #include <QFloat16> #include <QItemDelegate> @@ -52,8 +53,8 @@ #include <QPainter> #include <QSet> #include <QStringDecoder> -#include <QTableWidget> #include <QTabWidget> +#include <QTableWidget> #include <QTextEdit> #include <QTimer> #include <QToolTip> @@ -2571,11 +2572,13 @@ void WatchModel::clearWatches() if (theWatcherNames.isEmpty()) return; - const QDialogButtonBox::StandardButton ret = CheckableMessageBox::doNotAskAgainQuestion( - ICore::dialogParent(), Tr::tr("Remove All Expression Evaluators"), - Tr::tr("Are you sure you want to remove all expression evaluators?"), - ICore::settings(), "RemoveAllWatchers"); - if (ret != QDialogButtonBox::Yes) + const QMessageBox::StandardButton ret = CheckableMessageBox::question( + ICore::dialogParent(), + Tr::tr("Remove All Expression Evaluators"), + Tr::tr("Are you sure you want to remove all expression evaluators?"), + ICore::settings(), + "RemoveAllWatchers"); + if (ret != QMessageBox::Yes) return; m_watchRoot->removeChildren(); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 53268c9742..bda248be63 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1293,14 +1293,16 @@ QStringList GitClient::setupCheckoutArguments(const FilePath &workingDirectory, if (localBranches.contains(ref)) return arguments; - if (Utils::CheckableMessageBox::doNotAskAgainQuestion( - ICore::dialogParent() /*parent*/, - Tr::tr("Create Local Branch") /*title*/, - Tr::tr("Would you like to create a local branch?") /*message*/, - ICore::settings(), "Git.CreateLocalBranchOnCheckout" /*setting*/, - QDialogButtonBox::Yes | QDialogButtonBox::No /*buttons*/, - QDialogButtonBox::No /*default button*/, - QDialogButtonBox::No /*button to save*/) != QDialogButtonBox::Yes) { + if (Utils::CheckableMessageBox::question( + ICore::dialogParent() /*parent*/, + Tr::tr("Create Local Branch") /*title*/, + Tr::tr("Would you like to create a local branch?") /*message*/, + ICore::settings(), + "Git.CreateLocalBranchOnCheckout" /*setting*/, + QMessageBox::Yes | QMessageBox::No /*buttons*/, + QMessageBox::No /*default button*/, + QMessageBox::No /*button to save*/) + != QMessageBox::Yes) { return arguments; } diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index 05693d6832..82aeeba4ff 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -1051,26 +1051,23 @@ bool RunControl::showPromptToStopDialog(const QString &title, { // Show a question message box where user can uncheck this // question for this class. - Utils::CheckableMessageBox messageBox(Core::ICore::dialogParent()); - messageBox.setWindowTitle(title); - messageBox.setText(text); - messageBox.setStandardButtons(QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + QMap<QMessageBox::StandardButton, QString> buttonTexts; if (!stopButtonText.isEmpty()) - messageBox.button(QDialogButtonBox::Yes)->setText(stopButtonText); + buttonTexts[QMessageBox::Yes] = stopButtonText; if (!cancelButtonText.isEmpty()) - messageBox.button(QDialogButtonBox::Cancel)->setText(cancelButtonText); - messageBox.setDefaultButton(QDialogButtonBox::Yes); - if (prompt) { - messageBox.setCheckBoxText(Utils::CheckableMessageBox::msgDoNotAskAgain()); - messageBox.setChecked(false); - } else { - messageBox.setCheckBoxVisible(false); - } - messageBox.exec(); - const bool close = messageBox.clickedStandardButton() == QDialogButtonBox::Yes; - if (close && prompt && messageBox.isChecked()) - *prompt = false; - return close; + buttonTexts[QMessageBox::Cancel] = cancelButtonText; + + std::optional<CheckableMessageBox::Decider> decider + = prompt ? std::nullopt : make_optional(CheckableMessageBox::make_decider(*prompt)); + + auto selected = CheckableMessageBox::question(Core::ICore::dialogParent(), + title, + text, + decider, + QMessageBox::Yes | QMessageBox::Cancel, + QMessageBox::Yes); + + return selected == QMessageBox::Yes; } void RunControl::provideAskPassEntry(Environment &env) diff --git a/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp b/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp index 5d1900c494..f71f04fd39 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp @@ -663,14 +663,16 @@ AlignDistribute::Dimension AlignDistribute::getDimension(Target target) const bool AlignDistribute::executePixelPerfectDialog() const { - QDialogButtonBox::StandardButton pressed = Utils::CheckableMessageBox::doNotAskAgainQuestion( + auto decider = Utils::CheckableMessageBox::make_decider(Core::ICore::settings(), + "WarnAboutPixelPerfectDistribution"); + + QMessageBox::StandardButton pressed = Utils::CheckableMessageBox::question( Core::ICore::dialogParent(), tr("Cannot Distribute Perfectly"), tr("These objects cannot be distributed to equal pixel values. " "Do you want to distribute to the nearest possible values?"), - Core::ICore::settings(), - "WarnAboutPixelPerfectDistribution"); - return (pressed == QDialogButtonBox::Yes) ? true : false; + decider); + return (pressed == QMessageBox::Yes) ? true : false; } } // namespace QmlDesigner diff --git a/src/plugins/squish/squishnavigationwidget.cpp b/src/plugins/squish/squishnavigationwidget.cpp index 829b2312cc..1b99c338f1 100644 --- a/src/plugins/squish/squishnavigationwidget.cpp +++ b/src/plugins/squish/squishnavigationwidget.cpp @@ -296,14 +296,15 @@ void SquishNavigationWidget::onRemoveAllSharedFolderTriggered() void SquishNavigationWidget::onRecordTestCase(const QString &suiteName, const QString &testCase) { - QDialogButtonBox::StandardButton pressed = Utils::CheckableMessageBox::doNotAskAgainQuestion( - Core::ICore::dialogParent(), - Tr::tr("Record Test Case"), - Tr::tr("Do you want to record over the test case \"%1\"? The existing content will " - "be overwritten by the recorded script.").arg(testCase), - Core::ICore::settings(), - "RecordWithoutApproval"); - if (pressed != QDialogButtonBox::Yes) + QMessageBox::StandardButton pressed = Utils::CheckableMessageBox::question( + Core::ICore::dialogParent(), + Tr::tr("Record Test Case"), + Tr::tr("Do you want to record over the test case \"%1\"? The existing content will " + "be overwritten by the recorded script.") + .arg(testCase), + Core::ICore::settings(), + "RecordWithoutApproval"); + if (pressed != QMessageBox::Yes) return; SquishFileHandler::instance()->recordTestCase(suiteName, testCase); diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index 529bac9d6b..8b842ec080 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -801,19 +801,19 @@ void MemcheckToolPrivate::heobAction() const QString dwarfstack = QString("dwarfstack%1.dll").arg(abi.wordWidth()); const QString dwarfstackPath = dialog.path() + '/' + dwarfstack; if (!QFile::exists(dwarfstackPath) - && CheckableMessageBox::doNotShowAgainInformation( + && CheckableMessageBox::information( Core::ICore::dialogParent(), Tr::tr("Heob"), Tr::tr("Heob used with MinGW projects needs the %1 DLLs for proper " - "stacktrace resolution.") + "stacktrace resolution.") .arg( "<a " "href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"), ICore::settings(), "HeobDwarfstackInfo", - QDialogButtonBox::Ok | QDialogButtonBox::Cancel, - QDialogButtonBox::Ok) - != QDialogButtonBox::Ok) + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Ok) + != QMessageBox::Ok) return; } diff --git a/src/plugins/welcome/introductionwidget.cpp b/src/plugins/welcome/introductionwidget.cpp index a18287b0f6..4ee3e7868b 100644 --- a/src/plugins/welcome/introductionwidget.cpp +++ b/src/plugins/welcome/introductionwidget.cpp @@ -28,8 +28,9 @@ namespace Internal { void IntroductionWidget::askUserAboutIntroduction(QWidget *parent, QSettings *settings) { + auto decider = CheckableMessageBox::make_decider(settings, kTakeTourSetting); // CheckableMessageBox for compatibility with Qt Creator < 4.11 - if (!CheckableMessageBox::shouldAskAgain(settings, kTakeTourSetting) + if (!CheckableMessageBox::shouldAskAgain(decider) || !Core::ICore::infoBar()->canInfoBeAdded(kTakeTourSetting)) return; |