diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-10-24 17:47:12 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-10-31 11:28:10 +0200 |
commit | bafeffff9d1b9b2c8108e74cb6857899f7dd5b5e (patch) | |
tree | c9ac2b1108ce482b131e42a1413570f7d068a675 | |
parent | db17487c9350d321905ce61a88bedb1b9f7abf3a (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.
Pick-to: 6.5 6.6
Change-Id: Ifb7f7bd537fe71293f14ef6a006999e350bd0b52
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
-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 847a841cee..93de7933d4 100644 --- a/src/gui/kernel/qplatformdialoghelper.cpp +++ b/src/gui/kernel/qplatformdialoghelper.cpp @@ -883,9 +883,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 7483ded396..0569a7e2f9 100644 --- a/src/gui/kernel/qplatformdialoghelper.h +++ b/src/gui/kernel/qplatformdialoghelper.h @@ -459,7 +459,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 8f06806de7..b9c54ea7a8 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -2840,22 +2840,37 @@ void QMessageBoxPrivate::helperPrepareShow(QPlatformDialogHelper *) options->setStandardIcon(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. |