vcl/inc/qt5/QtInstanceMessageDialog.hxx | 2 +- vcl/qt5/QtInstanceMessageDialog.cxx | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-)
New commits: commit d09d595347695315a3f909cdde74d7f64949f3ed Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed Dec 18 16:05:30 2024 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Wed Dec 18 22:27:20 2024 +0100 tdf#164353 tdf#130857 qt weld: Keep extra msg dialog widget in place Both, QMessageBox::setText, and QMessageBox::setInformativeText call QMessageBoxPrivate::setupLayout [1], and that one deletes the QMessageBox's previous layout, creates a new QGridLayout and sets that as the dialog's new layout. As a consequence, adding the widget that can hold extra controls to the dialog's layout only once by calling QtInstanceMessageDialog::addWidgetForExtraItems from the QtInstanceMessageDialog ctor isn't sufficient, but needs to be repeated each time the dialog layout may have changed. (Otherwise the widget is not contained in the layout, and "randomly" placed in the dialog, so it can e.g. overlap other UI elements in the dialog, see tdf#164353). Therefore, rework QtInstanceMessageDialog::addWidgetForExtraItems a bit, rename it to QtInstanceMessageDialog::positionExtraControlsContainer and call it also after updating texts. [1] https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/dialogs/qmessagebox.cpp#n290 Change-Id: Ib17b5867393a0694701c56b0ab74165021a8bc51 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178726 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> (cherry picked from commit ffbe93aa93c0300dd4ff5f4d55dfb33e4c7a394d) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178740 diff --git a/vcl/inc/qt5/QtInstanceMessageDialog.hxx b/vcl/inc/qt5/QtInstanceMessageDialog.hxx index a775b8618050..f8430e98a609 100644 --- a/vcl/inc/qt5/QtInstanceMessageDialog.hxx +++ b/vcl/inc/qt5/QtInstanceMessageDialog.hxx @@ -43,7 +43,7 @@ public: virtual int run() override; private: - QWidget* addWidgetForExtraItems(); + void positionExtraControlsContainer(); virtual QPushButton* buttonForResponseCode(int nResponse); protected slots: diff --git a/vcl/qt5/QtInstanceMessageDialog.cxx b/vcl/qt5/QtInstanceMessageDialog.cxx index fb27aa544cb6..c9217609a9d5 100644 --- a/vcl/qt5/QtInstanceMessageDialog.cxx +++ b/vcl/qt5/QtInstanceMessageDialog.cxx @@ -22,8 +22,9 @@ QtInstanceMessageDialog::QtInstanceMessageDialog(QMessageBox* pMessageDialog) { assert(m_pMessageDialog); - m_pExtraControlsContainer = addWidgetForExtraItems(); - assert(m_pExtraControlsContainer); + m_pExtraControlsContainer = new QWidget; + m_pExtraControlsContainer->setLayout(new QVBoxLayout); + positionExtraControlsContainer(); } void QtInstanceMessageDialog::set_primary_text(const rtl::OUString& rText) @@ -36,7 +37,10 @@ void QtInstanceMessageDialog::set_primary_text(const rtl::OUString& rText) return; } + // update text and ensure that extra controls are contained in the + // dialog's layout (new layout gets set when setting text) m_pMessageDialog->setText(toQString(rText)); + positionExtraControlsContainer(); } void QtInstanceMessageDialog::set_secondary_text(const rtl::OUString& rText) @@ -49,7 +53,10 @@ void QtInstanceMessageDialog::set_secondary_text(const rtl::OUString& rText) return; } + // update text and ensure that extra controls are contained in the + // dialog's layout (new layout gets set when setting text) m_pMessageDialog->setInformativeText(toQString(rText)); + positionExtraControlsContainer(); } std::unique_ptr<weld::Container> QtInstanceMessageDialog::weld_message_area() @@ -173,14 +180,19 @@ void QtInstanceMessageDialog::dialogFinished(int nResult) QtInstanceDialog::dialogFinished(nResponseCode); } - -QWidget* QtInstanceMessageDialog::addWidgetForExtraItems() +void QtInstanceMessageDialog::positionExtraControlsContainer() { + assert(m_pExtraControlsContainer); + // make use of implementation detail that QMessageBox uses QGridLayout for its layout // (logic here will need to be adjusted if that ever changes) QGridLayout* pDialogLayout = qobject_cast<QGridLayout*>(m_pMessageDialog->layout()); assert(pDialogLayout && "QMessageBox has unexpected layout"); + // no need to reposition if layout didn't change + if (pDialogLayout->indexOf(m_pExtraControlsContainer) >= 0) + return; + // find last label const int nItemCount = pDialogLayout->count(); int nLastLabelIndex = -1; @@ -219,11 +231,7 @@ QWidget* QtInstanceMessageDialog::addWidgetForExtraItems() int nLabelColSpan = 0; pDialogLayout->getItemPosition(nLastLabelIndex, &nLabelRow, &nLabelCol, &nLabelRowSpan, &nLabelColSpan); - QWidget* pWidget = new QWidget; - pWidget->setLayout(new QVBoxLayout); - pDialogLayout->addWidget(pWidget, nLabelRow + 1, nLabelCol); - - return pWidget; + pDialogLayout->addWidget(m_pExtraControlsContainer, nLabelRow + 1, nLabelCol); } QPushButton* QtInstanceMessageDialog::buttonForResponseCode(int nResponse)