diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-06-28 16:58:58 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-06-29 18:49:46 +0200 |
commit | 1f70c073d4325bc0eb9b0cec5156c3b89ce1b4df (patch) | |
tree | e162a9fe518770210a7dedb1f091b0dbbef38103 | |
parent | 4a4283e3e98d779e6eb6cb47d408fe4fd402cdf8 (diff) |
QMessageBox: Respect clients overriding QDialog::done()
As a result of d8bbb5ee0e60d44a70d29306e607a59caf7fe5bc, we
were no longer calling QDialog::done(), which users may have
overridden.
We now pull out the dialog code to determine whether to
emit accepted/rejected directly in done(), so that we
can go back to calling QDialog::done().
Pick-to: 6.6 6.5
Change-Id: Ie08270123d61d9010acd8c989b66986f71960ad0
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r-- | src/widgets/dialogs/qdialog.cpp | 36 | ||||
-rw-r--r-- | src/widgets/dialogs/qdialog_p.h | 4 | ||||
-rw-r--r-- | src/widgets/dialogs/qmessagebox.cpp | 37 | ||||
-rw-r--r-- | tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp | 41 |
4 files changed, 76 insertions, 42 deletions
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index d0e54e013c..a4c9813965 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -149,27 +149,6 @@ void QDialogPrivate::close(int resultCode) resetModalitySetByOpen(); } -/*! - \internal - - Emits finished() signal with \a resultCode. If the \a dialogCode - is equal to 0 emits rejected(), if the \a dialogCode is equal to - 1 emits accepted(). - */ -void QDialogPrivate::finalize(int resultCode, int dialogCode) -{ - Q_Q(QDialog); - QPointer<QDialog> guard(q); - - if (dialogCode == QDialog::Accepted) - emit q->accepted(); - else if (dialogCode == QDialog::Rejected) - emit q->rejected(); - - if (guard) - emit q->finished(resultCode); -} - QWindow *QDialogPrivate::transientParentWindow() const { Q_Q(const QDialog); @@ -618,9 +597,22 @@ int QDialog::exec() void QDialog::done(int r) { + QPointer<QDialog> guard(this); + Q_D(QDialog); d->close(r); - d->finalize(r, r); + + if (!guard) + return; + + int dialogCode = d->dialogCode(); + if (dialogCode == QDialog::Accepted) + emit accepted(); + else if (dialogCode == QDialog::Rejected) + emit rejected(); + + if (guard) + emit finished(r); } /*! diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h index 1d06c116fb..bac33bdea9 100644 --- a/src/widgets/dialogs/qdialog_p.h +++ b/src/widgets/dialogs/qdialog_p.h @@ -88,7 +88,9 @@ public: virtual bool canBeNativeDialog() const; void close(int resultCode); - void finalize(int resultCode, int dialogCode); + +protected: + virtual int dialogCode() const { return rescode; } private: virtual void initHelper(QPlatformDialogHelper *) {} diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index d40d35bea0..2c6b01a0d9 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -187,8 +187,6 @@ public: QAbstractButton *abstractButtonForId(int id) const; int execReturnCode(QAbstractButton *button); - int dialogCodeForButtonRole(QMessageBox::ButtonRole buttonRole) const; - void detectEscapeButton(); void updateSize(); int layoutMinimumWidth(); @@ -239,6 +237,7 @@ public: private: void initHelper(QPlatformDialogHelper *) override; void helperPrepareShow(QPlatformDialogHelper *) override; + int dialogCode() const override; }; void QMessageBoxPrivate::init(const QString &title, const QString &text) @@ -442,23 +441,24 @@ int QMessageBoxPrivate::execReturnCode(QAbstractButton *button) return ret; } -/*! - \internal +int QMessageBoxPrivate::dialogCode() const +{ + Q_Q(const QMessageBox); - Returns 0 for RejectedRole and NoRole, 1 for AcceptedRole and YesRole, -1 otherwise - */ -int QMessageBoxPrivate::dialogCodeForButtonRole(QMessageBox::ButtonRole buttonRole) const -{ - switch (buttonRole) { - case QMessageBox::AcceptRole: - case QMessageBox::YesRole: - return QDialog::Accepted; - case QMessageBox::RejectRole: - case QMessageBox::NoRole: - return QDialog::Rejected; - default: - return -1; + if (clickedButton) { + switch (q->buttonRole(clickedButton)) { + case QMessageBox::AcceptRole: + case QMessageBox::YesRole: + return QDialog::Accepted; + case QMessageBox::RejectRole: + case QMessageBox::NoRole: + return QDialog::Rejected; + default: + ; + } } + + return QDialogPrivate::dialogCode(); } void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button) @@ -492,8 +492,7 @@ void QMessageBoxPrivate::setClickedButton(QAbstractButton *button) emit q->buttonClicked(clickedButton); auto resultCode = execReturnCode(button); - close(resultCode); - finalize(resultCode, dialogCodeForButtonRole(q->buttonRole(button))); + q->done(resultCode); } void QMessageBoxPrivate::_q_helperClicked(QPlatformDialogHelper::StandardButton helperButton, QPlatformDialogHelper::ButtonRole role) diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index afdf18fedc..0d52f197a0 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -58,6 +58,9 @@ private slots: void acceptedRejectedSignals(); void acceptedRejectedSignals_data(); + void overrideDone_data(); + void overrideDone(); + void cleanup(); }; @@ -152,6 +155,44 @@ void tst_QMessageBox::init() qApp->setAttribute(Qt::AA_DontUseNativeDialogs, !useNativeDialog); } +class OverridingMessageBox : public QMessageBox +{ +public: + void done(int result) override { + doneResult = result; + QMessageBox::done(result); + } + std::optional<int> doneResult; +}; + +void tst_QMessageBox::overrideDone_data() +{ + QTest::addColumn<QMessageBox::StandardButton>("button"); + QTest::addColumn<int>("closeAction"); + QTest::addColumn<int>("result"); + + QTest::newRow("close") << QMessageBox::Help << int(ExecCloseHelper::CloseWindow) << 0; + QTest::newRow("yes") << QMessageBox::Yes << int(Qt::Key_Enter) << int(QMessageBox::Yes); + QTest::newRow("no") << QMessageBox::No << int(Qt::Key_Enter) << int(QMessageBox::No); +} + +void tst_QMessageBox::overrideDone() +{ + QFETCH(QMessageBox::StandardButton, button); + QFETCH(int, closeAction); + QFETCH(int, result); + + OverridingMessageBox messageBox; + messageBox.addButton(button); + messageBox.setDefaultButton(button); + ExecCloseHelper closeHelper; + closeHelper.start(closeAction, &messageBox); + messageBox.exec(); + QVERIFY(messageBox.doneResult.has_value()); + QCOMPARE(*messageBox.doneResult, result); + +} + void tst_QMessageBox::cleanup() { QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty()); // OS X requires TRY |