diff options
author | Tor Arne Vestbø <[email protected]> | 2023-10-24 17:47:12 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <[email protected]> | 2023-11-03 20:19:21 +0000 |
commit | dc0313146ae4aa6ba5968d10d0068cce1185482f (patch) | |
tree | fbf17126f79e1e82438fd2daaf3e740aad226324 | |
parent | 8bad1c5486077e5550fd9f1dcdeb1a96c1bd8be8 (diff) |
QMessageBox: Detect modifications to standard button text
The addButton(StandardButton) and button(StandardButton) APIs return
a QAbstractButton, that the user can in theory modify to their heart's
content. This causes problems when the native dialog backend is not
aware of these modifications.
We documented this limitation in e9a1c5321, but it turns out to be
more common than we first though. In particular, a typical case is
modifying the text of the button.
We now try to detect if the button has a non-standard text, and if
so turn it into a custom button when passing it on to the native
backend. From the point of view of QMessageBox it's still a standard
button, and will be reported as such in the result of exec().
To make this work the QMessageDialogOptions::CustomButton needs to
learn about custom button identifiers, so we can pass the original
standard button though.
This moves us closer to a world where the QMessageDialogOptions
represent both standard buttons and custom buttons using the same
structure, which is what we want anyways, so that we e.g. respect
the added order of standard buttons with the same role.
Fixes: QTBUG-118241
Change-Id: Ifb7f7bd537fe71293f14ef6a006999e350bd0b52
Reviewed-by: Richard Moe Gustavsen <[email protected]>
(cherry picked from commit bafeffff9d1b9b2c8108e74cb6857899f7dd5b5e)
Reviewed-by: Tor Arne Vestbø <[email protected]>
(cherry picked from commit 77dff1f5edcab44f45449536fd01d85b0bbed15d)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
-rw-r--r-- | src/gui/kernel/qplatformdialoghelper.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qplatformdialoghelper.h | 2 | ||||
-rw-r--r-- | src/widgets/dialogs/qmessagebox.cpp | 19 |
3 files changed, 20 insertions, 5 deletions
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp index 278f55a9e0a..48db7f07162 100644 --- a/src/gui/kernel/qplatformdialoghelper.cpp +++ b/src/gui/kernel/qplatformdialoghelper.cpp @@ -882,9 +882,9 @@ QPlatformDialogHelper::StandardButtons QMessageDialogOptions::standardButtons() } int QMessageDialogOptions::addButton(const QString &label, QPlatformDialogHelper::ButtonRole role, - void *buttonImpl) + void *buttonImpl, int buttonId) { - const CustomButton b(d->nextCustomButtonId++, label, role, buttonImpl); + const CustomButton b(buttonId ? buttonId : d->nextCustomButtonId++, label, role, buttonImpl); d->customButtons.append(b); return b.id; } diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h index 315f1bb511a..c2aeaeaaa67 100644 --- a/src/gui/kernel/qplatformdialoghelper.h +++ b/src/gui/kernel/qplatformdialoghelper.h @@ -446,7 +446,7 @@ public: }; int addButton(const QString &label, QPlatformDialogHelper::ButtonRole role, - void *buttonImpl = nullptr); + void *buttonImpl = nullptr, int buttonId = 0); void removeButton(int id); const QList<CustomButton> &customButtons(); const CustomButton *customButton(int id); diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 09740197248..982481ac347 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -2750,22 +2750,37 @@ void QMessageBoxPrivate::helperPrepareShow(QPlatformDialogHelper *) options->setIcon(helperIcon(q->icon())); options->setIconPixmap(q->iconPixmap()); + // Clear up front, since we might have prepared earlier + options->clearCustomButtons(); + // Add standard buttons and resolve default/escape button - options->setStandardButtons(helperStandardButtons(q)); + auto standardButtons = helperStandardButtons(q); for (int button = QDialogButtonBox::StandardButton::FirstButton; button <= QDialogButtonBox::StandardButton::LastButton; button <<= 1) { auto *standardButton = buttonBox->button(QDialogButtonBox::StandardButton(button)); if (!standardButton) continue; + if (auto *platformTheme = QGuiApplicationPrivate::platformTheme()) { + if (standardButton->text() != platformTheme->standardButtonText(button)) { + // The standard button has been customized, so add it as + // a custom button instead. + const auto buttonRole = buttonBox->buttonRole(standardButton); + options->addButton(standardButton->text(), + static_cast<QPlatformDialogHelper::ButtonRole>(buttonRole), + standardButton, button); + standardButtons &= ~QPlatformDialogHelper::StandardButton(button); + } + } + if (standardButton == defaultButton) options->setDefaultButton(button); else if (standardButton == detectedEscapeButton) options->setEscapeButton(button); } + options->setStandardButtons(standardButtons); // Add custom buttons and resolve default/escape button - options->clearCustomButtons(); for (auto *customButton : customButtonList) { // Unless it's the details button, since we don't do any // plumbing for the button's action in that case. |