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)

Reply via email to