Files
libreoffice/vcl/qt5/QtInstanceMessageDialog.cxx

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

126 lines
4.3 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <QtInstanceMessageDialog.hxx>
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 <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-23 13:47:21 +01:00
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)
{
}
void QtInstanceMessageDialog::set_primary_text(const rtl::OUString& rText)
{
m_pMessageDialog->setText(toQString(rText));
}
void QtInstanceMessageDialog::set_secondary_text(const rtl::OUString& rText)
{
m_pMessageDialog->setInformativeText(toQString(rText));
}
weld::Container* QtInstanceMessageDialog::weld_message_area() { return nullptr; }
OUString QtInstanceMessageDialog::get_primary_text() const
{
assert(m_pMessageDialog);
return toOUString(m_pMessageDialog->text());
}
OUString QtInstanceMessageDialog::get_secondary_text() const
{
assert(m_pMessageDialog);
return toOUString(m_pMessageDialog->informativeText());
}
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 <omkaracharekar12@gmail.com> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-01-23 13:47:21 +01:00
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: */