vcl/inc/qt5/QtInstanceMessageDialog.hxx | 5 + vcl/qt5/QtInstanceMessageDialog.cxx | 83 ++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+)
New commits: commit bb0c0e422788b6c461387491c59911ad84c27b83 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Tue Jan 23 13:47:21 2024 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Wed Jan 24 17:15:07 2024 +0100 tdf#154381 qt weld: Add button handling for message box Override the `QtInstanceDialog` methods `add_button` and `run` in `QtInstanceMessageDialog`, and implement handling for these buttons with the native `QMessageBox` that is used internally: Implement `QtInstanceMessageDialog::add_button` to make adding buttons to the welded message dialog work. Map the VCL response type to a corresponding `QMessageBox::ButtonRole`. Some mappings are straightforward, others are a bit more arbitrary, but the only essential thing is that the mapping back to the VCL response code is consistent. `QMessageBox::exec` [1] overrides `QDialog::exec` [2], and while the int returned by the latter corresponds to a `QDialog::DialogCode` code, the int returned by the former corresponds to a `QMessageBox::StandardButton` value. Since the current `QtInstanceDialog::run` implementation relies on the `QDialog` behaviour, override it for the message dialog case. Since the `QMessageBox::ButtonRole` is set in `QtInstanceMessageDialog::add_button`, retrieve the corresponding role from the clicked button instead of using the return value of the `QMessageBox::exec` to be able to get the correct VCL return code again. With this in place, the qt6 welded message dialog that shows up when opening a file that's already open in another instance of LibreOffice (s. `AlreadyOpenQueryBox::AlreadyOpenQueryBox`) shows buttons and clicking any of them behaves as expected, just as is the case for the non-welded one (whose use can be forced by setting env var `SAL_VCL_QT_NO_WELDED_WIDGETS=1`). [1] https://doc.qt.io/qt-6/qmessagebox.html#exec` [2] https://doc.qt.io/qt-6/qdialog.html#exec Change-Id: Ie37573951302f13eab758f889d478dc9351e9c07 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162440 Tested-by: Jenkins Reviewed-by: Omkar Acharekar <omkarachareka...@gmail.com> Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/inc/qt5/QtInstanceMessageDialog.hxx b/vcl/inc/qt5/QtInstanceMessageDialog.hxx index 68d2010cb1fa..0c585a9ed916 100644 --- a/vcl/inc/qt5/QtInstanceMessageDialog.hxx +++ b/vcl/inc/qt5/QtInstanceMessageDialog.hxx @@ -29,6 +29,11 @@ public: virtual OUString get_primary_text() const override; virtual OUString get_secondary_text() const override; + + // weld::Dialog overrides + virtual void add_button(const OUString& rText, int nResponse, + const OUString& rHelpId = {}) override; + virtual int run() override; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qt5/QtInstanceMessageDialog.cxx b/vcl/qt5/QtInstanceMessageDialog.cxx index 2ba386ded5c5..6f252c79c816 100644 --- a/vcl/qt5/QtInstanceMessageDialog.cxx +++ b/vcl/qt5/QtInstanceMessageDialog.cxx @@ -9,6 +9,69 @@ #include <QtInstanceMessageDialog.hxx> +namespace +{ +QMessageBox::ButtonRole lcl_vclResponseTypeToQtMessageBoxButtonRole(int nResponseType) +{ + // RET_CANCEL, RET_HELP, RET_YES, RET_NO and RET_OK have a matching equivalent + // in Qt, the others are a bit more arbitrary; what really matters about these + // is only that the mapping here and the other way around + // (in lcl_qtMessageBoxButtonRoleToVclResponseType) is consistent + switch (nResponseType) + { + case RET_CANCEL: + return QMessageBox::ButtonRole::RejectRole; + case RET_HELP: + return QMessageBox::ButtonRole::HelpRole; + case RET_YES: + return QMessageBox::ButtonRole::YesRole; + case RET_NO: + return QMessageBox::ButtonRole::NoRole; + case RET_OK: + return QMessageBox::ButtonRole::AcceptRole; + case RET_RETRY: + return QMessageBox::ButtonRole::ResetRole; + case RET_IGNORE: + return QMessageBox::ButtonRole::ActionRole; + case RET_CLOSE: + return QMessageBox::ButtonRole::DestructiveRole; + default: + assert(false && "Unhandled vcl response type"); + return QMessageBox::InvalidRole; + } +} + +VclResponseType lcl_qtMessageBoxButtonRoleToVclResponseType(int nRet) +{ + // AcceptRole, HelpRole, NoRole, RejectRole and YesRole have a matching equivalent + // in VCL, the others are a bit more arbitrary; what really matters about these + // is only that the mapping here and the other way around + // (in lcl_vclResponseTypeToQtMessageBoxButtonRole) is consistent + switch (nRet) + { + case QMessageBox::ButtonRole::AcceptRole: + return RET_OK; + case QMessageBox::ButtonRole::HelpRole: + return RET_HELP; + case QMessageBox::ButtonRole::NoRole: + return RET_NO; + case QMessageBox::ButtonRole::RejectRole: + return RET_CANCEL; + case QMessageBox::ButtonRole::YesRole: + return RET_YES; + case QMessageBox::ButtonRole::ResetRole: + return RET_RETRY; + case QMessageBox::ButtonRole::ActionRole: + return RET_IGNORE; + case QMessageBox::ButtonRole::DestructiveRole: + return RET_CLOSE; + default: + assert(false && "Unhandled QMessageBox::ButtonRole"); + return RET_CANCEL; + } +} +} + QtInstanceMessageDialog::QtInstanceMessageDialog(QMessageBox* pMessageDialog) : QtInstanceDialog(pMessageDialog) , m_pMessageDialog(pMessageDialog) @@ -39,4 +102,24 @@ OUString QtInstanceMessageDialog::get_secondary_text() const return toOUString(m_pMessageDialog->informativeText()); } +void QtInstanceMessageDialog::add_button(const OUString& rText, int nResponse, const OUString&) +{ + assert(m_pMessageDialog); + m_pMessageDialog->addButton(vclToQtStringWithAccelerator(rText), + lcl_vclResponseTypeToQtMessageBoxButtonRole(nResponse)); +} + +int QtInstanceMessageDialog::run() +{ + // cannot use the QMessageBox::exec() return value right away, because it returns the + // QMessageBox::StandardButton value or an opaque value, so use the clicked + // button to retrieve its role instead and map that to the VCL response + m_pMessageDialog->exec(); + QAbstractButton* pClickedButton = m_pMessageDialog->clickedButton(); + if (!pClickedButton) + return RET_CLOSE; + return lcl_qtMessageBoxButtonRoleToVclResponseType( + m_pMessageDialog->buttonRole(pClickedButton)); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */