From fcb752ff9c0314fa7024a03c5e70e4e59a8e225f Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 9 Jan 2024 12:53:48 +0100 Subject: [PATCH] Utils: Add async methods to CheckableMessageBox Change-Id: I296cb34453f5c12f712afedfe35b8962be8d7eec Reviewed-by: David Schulz --- src/libs/utils/checkablemessagebox.cpp | 143 +++++++++++++++++++++---- src/libs/utils/checkablemessagebox.h | 25 +++++ 2 files changed, 150 insertions(+), 18 deletions(-) diff --git a/src/libs/utils/checkablemessagebox.cpp b/src/libs/utils/checkablemessagebox.cpp index 91f3c1855c0..b6bf66e2761 100644 --- a/src/libs/utils/checkablemessagebox.cpp +++ b/src/libs/utils/checkablemessagebox.cpp @@ -34,19 +34,16 @@ namespace Utils { static QtcSettings *theSettings; -static QMessageBox::StandardButton exec( - QWidget *parent, - QMessageBox::Icon icon, - const QString &title, - const QString &text, - const CheckableDecider &decider, - QMessageBox::StandardButtons buttons, - QMessageBox::StandardButton defaultButton, - QMessageBox::StandardButton acceptButton, - QMap buttonTextOverrides, - const QString &msg) +static void prepare(QMessageBox::Icon icon, + const QString &title, + const QString &text, + const CheckableDecider &decider, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton, + QMap buttonTextOverrides, + const QString &msg, + QMessageBox &msgBox) { - QMessageBox msgBox(parent); msgBox.setWindowTitle(title); msgBox.setIcon(icon); msgBox.setText(text); @@ -60,7 +57,7 @@ static QMessageBox::StandardButton exec( if (text.contains("setChecked(false); msgBox.checkBox()->setText(msg); @@ -81,6 +75,27 @@ static QMessageBox::StandardButton exec( msgBox.setDefaultButton(defaultButton); for (auto it = buttonTextOverrides.constBegin(); it != buttonTextOverrides.constEnd(); ++it) msgBox.button(it.key())->setText(it.value()); +} + +static QMessageBox::StandardButton exec( + QWidget *parent, + QMessageBox::Icon icon, + const QString &title, + const QString &text, + const CheckableDecider &decider, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton, + QMessageBox::StandardButton acceptButton, + QMap buttonTextOverrides, + const QString &msg) +{ + if (decider.shouldAskAgain) { + if (!decider.shouldAskAgain()) + return acceptButton; + } + + QMessageBox msgBox(parent); + prepare(icon, title, text, decider, buttons, defaultButton, buttonTextOverrides, msg, msgBox); msgBox.exec(); QMessageBox::StandardButton clickedBtn = msgBox.standardButton(msgBox.clickedButton()); @@ -91,6 +106,45 @@ static QMessageBox::StandardButton exec( return clickedBtn; } +static void show(QWidget *parent, + QMessageBox::Icon icon, + const QString &title, + const QString &text, + CheckableDecider decider, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton, + QMessageBox::StandardButton acceptButton, + QMap buttonTextOverrides, + const QString &msg, + QObject *guard, + const std::function &callback) +{ + if (decider.shouldAskAgain && !decider.shouldAskAgain()) { + if (callback) { + QMetaObject::invokeMethod( + guard, [callback, acceptButton] { callback(acceptButton); }, Qt::QueuedConnection); + } + return; + } + + QMessageBox *msgBox = new QMessageBox(parent); + prepare(icon, title, text, decider, buttons, defaultButton, buttonTextOverrides, msg, *msgBox); + + QObject::connect(msgBox, &QMessageBox::finished, guard, [msgBox, callback, decider, acceptButton] { + QMessageBox::StandardButton clickedBtn = msgBox->standardButton(msgBox->clickedButton()); + + if (decider.doNotAskAgain && msgBox->checkBox()->isChecked() + && (acceptButton == QMessageBox::NoButton || clickedBtn == acceptButton)) + decider.doNotAskAgain(); + if (callback) + callback(clickedBtn); + + msgBox->deleteLater(); + }); + + msgBox->show(); +} + CheckableDecider::CheckableDecider(const Key &settingsSubKey) { QTC_ASSERT(theSettings, return); @@ -100,7 +154,7 @@ CheckableDecider::CheckableDecider(const Key &settingsSubKey) theSettings->endGroup(); return !shouldNotAsk; }; - doNotAskAgain = [settingsSubKey] { + doNotAskAgain = [settingsSubKey] { theSettings->beginGroup(kDoNotAskAgainKey); theSettings->setValue(settingsSubKey, true); theSettings->endGroup(); @@ -136,6 +190,33 @@ QMessageBox::StandardButton CheckableMessageBox::question( msg.isEmpty() ? msgDoNotAskAgain() : msg); } +void CheckableMessageBox::question_async( + QWidget *parent, + const QString &title, + const QString &question, + const CheckableDecider &decider, + QObject *guard, + std::function callback, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton, + QMessageBox::StandardButton acceptButton, + QMap buttonTextOverrides, + const QString &msg) +{ + show(parent, + QMessageBox::Question, + title, + question, + decider, + buttons, + defaultButton, + acceptButton, + buttonTextOverrides, + msg.isEmpty() ? msgDoNotAskAgain() : msg, + guard, + callback); +} + QMessageBox::StandardButton CheckableMessageBox::information( QWidget *parent, const QString &title, @@ -153,11 +234,37 @@ QMessageBox::StandardButton CheckableMessageBox::information( decider, buttons, defaultButton, - QMessageBox::NoButton, + defaultButton, buttonTextOverrides, msg.isEmpty() ? msgDoNotShowAgain() : msg); } +void CheckableMessageBox::information_async( + QWidget *parent, + const QString &title, + const QString &text, + const CheckableDecider &decider, + QObject *guard, + std::function callback, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton, + QMap buttonTextOverrides, + const QString &msg) +{ + show(parent, + QMessageBox::Information, + title, + text, + decider, + buttons, + defaultButton, + defaultButton, + buttonTextOverrides, + msg.isEmpty() ? msgDoNotShowAgain() : msg, + guard, + callback); +} + /*! Resets all suppression settings for doNotAskAgainQuestion() so all these message boxes are shown again. diff --git a/src/libs/utils/checkablemessagebox.h b/src/libs/utils/checkablemessagebox.h index de5f73ca90a..4245cf6e1ff 100644 --- a/src/libs/utils/checkablemessagebox.h +++ b/src/libs/utils/checkablemessagebox.h @@ -41,6 +41,19 @@ public: QMap buttonTextOverrides = {}, const QString &msg = {}); + static void question_async( + QWidget *parent, + const QString &title, + const QString &question, + const CheckableDecider &decider, + QObject *guard = nullptr, + std::function callback = nullptr, + QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No, + QMessageBox::StandardButton defaultButton = QMessageBox::No, + QMessageBox::StandardButton acceptButton = QMessageBox::Yes, + QMap buttonTextOverrides = {}, + const QString &msg = {}); + static QMessageBox::StandardButton information( QWidget *parent, const QString &title, @@ -51,6 +64,18 @@ public: QMap buttonTextOverrides = {}, const QString &msg = {}); + static void information_async( + QWidget *parent, + const QString &title, + const QString &text, + const CheckableDecider &decider, + QObject *guard = nullptr, + std::function callback = nullptr, + QMessageBox::StandardButtons buttons = QMessageBox::Ok, + QMessageBox::StandardButton defaultButton = QMessageBox::NoButton, + QMap buttonTextOverrides = {}, + const QString &msg = {}); + // Conversion convenience static void resetAllDoNotAskAgainQuestions(); static bool hasSuppressedQuestions();