dbaccess/source/ui/dlg/sqlmessage.cxx |   19 +++++++++------
 vcl/inc/qt5/QtBuilder.hxx             |    3 ++
 vcl/inc/qt5/QtInstanceTreeView.hxx    |    9 +++++++
 vcl/qt5/QtBuilder.cxx                 |   43 ++++++++++++++++++++++++++++++----
 vcl/qt5/QtInstanceBuilder.cxx         |    1 
 vcl/qt5/QtInstanceTreeView.cxx        |   32 +++++++++++++++++++++----
 6 files changed, 91 insertions(+), 16 deletions(-)

New commits:
commit 8e33908b538c7700be6f766c472f069d7f4dd15b
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Sun Aug 3 22:17:34 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Mon Aug 4 09:01:19 2025 +0200

    tdf#130857 qt weld: Evaluate GtkCellRenderers to know supported types
    
    So far, The GtkCellRenderer objects in .ui files were ignored
    by QtBuilder.
    However, for the automatic detection of what is the first column
    of a specific type (e.g. the first text column), that information
    is relevant, and e.g. the GTK implementation in GtkInstanceTreeView
    sets `GtkInstanceTreeView::m_nTextCol` based on that, then uses
    it when inserting text via the weld::TreeView::insert method.
    
    Extend the logic in QtBuilder and QtInstanceTreeView to also
    evaluate the cell renderers set in the .ui file and store the
    item data roles supported for each column based on those renderers.
    
    The Qt data model allows setting any of the roles exactly once for
    each item, so there is generally no need to explicitly enable
    something. But in order to adhere to the weld::TreeView logic/API,
    that kind of information is relevant.
    
    Let QtBuilder store a list of supported roles for each column
    (i.e. use a list of lists for all columns) in a property set
    for the QTreeView, and then use that property in the
    QtInstanceTreeView ctor to set the newly introduced
    QtInstanceTreeView::m_pColumnRoles member.
    
    Adjust QtInstanceTreeView::firstTextColumnModelIndex to
    make use of those stored roles, to reliably detect what
    is the first text column according to the GTK/weld::TreeView
    model, without requiring any entries to have been inserted
    previously.
    
    This is one step towards addressing the issue mentioned in
    previous commit
    
        Change-Id: Id94e22e879f712bd967431ec0f9dc34e4480e3dd
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Sun Aug 3 22:15:20 2025 +0200
    
            tdf#130857 qt weld: Support Java "Class Path" dialog
    
    > Currently, both the icon and the path are displayed
    > in the first column of the tree view and the second
    > column remains empty. This will be addressed in
    > upcoming commits.
    
    Change-Id: Ic8a59b254f3bac14c3b812f00d0cbfa3740432f2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188891
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/inc/qt5/QtBuilder.hxx b/vcl/inc/qt5/QtBuilder.hxx
index fbd6ec17a9c4..c2e06d87669b 100644
--- a/vcl/inc/qt5/QtBuilder.hxx
+++ b/vcl/inc/qt5/QtBuilder.hxx
@@ -22,6 +22,7 @@
 #include <QtWidgets/QPushButton>
 #include <QtWidgets/QSlider>
 #include <QtWidgets/QToolButton>
+#include <QtWidgets/QTreeView>
 
 #include <rtl/ustring.hxx>
 #include <unotools/resmgr.hxx>
@@ -84,6 +85,8 @@ public:
 
 private:
     static void deleteObject(QObject* pObject);
+    static QTreeView* enableTreeViewColumnDataRole(QWidget* pParentWidget,
+                                                   Qt::ItemDataRole eDataRole);
     // remove pOldWidget from the widget hierarchy and set (child widget) 
pNewWidget in its place
     static void replaceWidget(QWidget* pOldWidget, QWidget* pNewWidget);
     void setButtonProperties(QAbstractButton& rButton, stringmap& rProps, 
QWidget* pParentWidget);
diff --git a/vcl/inc/qt5/QtInstanceTreeView.hxx 
b/vcl/inc/qt5/QtInstanceTreeView.hxx
index cab92ffb69f2..aa78075d38aa 100644
--- a/vcl/inc/qt5/QtInstanceTreeView.hxx
+++ b/vcl/inc/qt5/QtInstanceTreeView.hxx
@@ -31,6 +31,9 @@ class QtInstanceTreeView : public QtInstanceWidget, public 
virtual weld::TreeVie
 
     QItemSelectionModel* m_pSelectionModel;
 
+    /** List containing a list of item data roles supported by each column. */
+    QList<QList<Qt::ItemDataRole>> m_pColumnRoles;
+
     bool m_bExtraToggleButtonsEnabled = false;
 
 public:
@@ -200,6 +203,12 @@ public:
     using QtInstanceWidget::set_sensitive;
     using QtInstanceWidget::get_sensitive;
 
+    // methods to get/set which roles are supported by the individual columns
+    // based on the underlying GtkTreeViewColumns and their GtkCellRenderers
+    static QList<QList<Qt::ItemDataRole>> columnRoles(QTreeView& rTreeView);
+    static void setColumnRoles(QTreeView& rTreeView,
+                               const QList<QList<Qt::ItemDataRole>>& 
rDataRoles);
+
 private:
     QModelIndex modelIndex(int nRow, int nCol = 0,
                            const QModelIndex& rParentIndex = QModelIndex()) 
const;
diff --git a/vcl/qt5/QtBuilder.cxx b/vcl/qt5/QtBuilder.cxx
index cda06da766a1..17050ddf48a3 100644
--- a/vcl/qt5/QtBuilder.cxx
+++ b/vcl/qt5/QtBuilder.cxx
@@ -14,6 +14,7 @@
 #include <QtInstanceMenu.hxx>
 #include <QtInstanceMessageDialog.hxx>
 #include <QtInstanceNotebook.hxx>
+#include <QtInstanceTreeView.hxx>
 #include <QtHyperlinkLabel.hxx>
 
 #include <vcl/qt/QtUtils.hxx>
@@ -47,7 +48,6 @@
 #include <QtWidgets/QTabWidget>
 #include <QtWidgets/QToolBar>
 #include <QtWidgets/QToolButton>
-#include <QtWidgets/QTreeView>
 #include <QtWidgets/QWizard>
 
 namespace
@@ -123,9 +123,8 @@ QObject* QtBuilder::makeObject(QObject* pParent, 
std::u16string_view sName, std:
     if (sName.empty())
         return nullptr;
 
-    // nothing to do for these
-    if (sName == u"GtkCellRendererPixbuf" || sName == u"GtkCellRendererText"
-        || sName == u"GtkCellRendererToggle" || sName == u"GtkTreeSelection")
+    // nothing to do for this one
+    if (sName == u"GtkTreeSelection")
         return nullptr;
 
     QWidget* pParentWidget = qobject_cast<QWidget*>(pParent);
@@ -203,6 +202,18 @@ QObject* QtBuilder::makeObject(QObject* pParent, 
std::u16string_view sName, std:
     {
         pObject = new QCalendarWidget(pParentWidget);
     }
+    else if (sName == u"GtkCellRendererPixbuf")
+    {
+        enableTreeViewColumnDataRole(pParentWidget, Qt::DecorationRole);
+    }
+    else if (sName == u"GtkCellRendererText")
+    {
+        enableTreeViewColumnDataRole(pParentWidget, Qt::DisplayRole);
+    }
+    else if (sName == u"GtkCellRendererToggle")
+    {
+        enableTreeViewColumnDataRole(pParentWidget, Qt::CheckStateRole);
+    }
     else if (sName == u"GtkCheckButton")
     {
         QCheckBox* pCheckBox = new QCheckBox(pParentWidget);
@@ -416,6 +427,12 @@ QObject* QtBuilder::makeObject(QObject* pParent, 
std::u16string_view sName, std:
         pModel->insertColumn(nCol);
         pModel->setHeaderData(nCol, Qt::Horizontal, 
toQString(extractTitle(rMap)));
 
+        // add initially empty list of supported roles for the new column that 
will
+        // be extended based on the GtkCellRenderer children of the column
+        QList<QList<Qt::ItemDataRole>> aColumnRoles = 
QtInstanceTreeView::columnRoles(*pTreeView);
+        aColumnRoles.push_back({});
+        QtInstanceTreeView::setColumnRoles(*pTreeView, aColumnRoles);
+
         // nothing else to do, return tree view parent for the widget
         return pTreeView;
     }
@@ -826,6 +843,24 @@ void QtBuilder::deleteObject(QObject* pObject)
     pObject->deleteLater();
 }
 
+QTreeView* QtBuilder::enableTreeViewColumnDataRole(QWidget* pParentWidget,
+                                                   Qt::ItemDataRole eDataRole)
+{
+    QTreeView* pTreeView = qobject_cast<QTreeView*>(pParentWidget);
+    assert(pTreeView && "No tree view for cell renderer");
+
+    // Mark support for the new role for the tree view's last inserted column
+    // (the GtkCellRenderer is a child object of the GtkTreeViewColumn)
+    QList<QList<Qt::ItemDataRole>> aColumnRoles = 
QtInstanceTreeView::columnRoles(*pTreeView);
+    assert(!aColumnRoles.empty() && "Missing list of column data roles");
+    assert(!aColumnRoles.back().contains(eDataRole)
+           && "Using the same role multiple times in one column is not 
supported");
+    aColumnRoles.back().push_back(eDataRole);
+    QtInstanceTreeView::setColumnRoles(*pTreeView, aColumnRoles);
+
+    return pTreeView;
+}
+
 void QtBuilder::replaceWidget(QWidget* pOldWidget, QWidget* pNewWidget)
 {
     QWidget* pParent = pOldWidget->parentWidget();
diff --git a/vcl/qt5/QtInstanceTreeView.cxx b/vcl/qt5/QtInstanceTreeView.cxx
index 413eb30f8614..41b94fe9eea7 100644
--- a/vcl/qt5/QtInstanceTreeView.cxx
+++ b/vcl/qt5/QtInstanceTreeView.cxx
@@ -17,6 +17,9 @@
 // role used for the ID in the QStandardItem
 constexpr int ROLE_ID = Qt::UserRole + 1000;
 
+// Property used to store the supported roles for each of the columns
+const char* const PROPERTY_COLUMN_ROLES = "column-roles";
+
 QtInstanceTreeView::QtInstanceTreeView(QTreeView* pTreeView)
     : QtInstanceWidget(pTreeView)
     , m_pTreeView(pTreeView)
@@ -32,6 +35,9 @@ QtInstanceTreeView::QtInstanceTreeView(QTreeView* pTreeView)
     m_pSelectionModel = m_pTreeView->selectionModel();
     assert(m_pSelectionModel);
 
+    m_pColumnRoles = columnRoles(*pTreeView);
+    assert(m_pColumnRoles.size() == m_pModel->columnCount() && "column count 
doesn't match");
+
     connect(m_pTreeView, &QTreeView::activated, this, 
&QtInstanceTreeView::handleActivated);
     connect(m_pSelectionModel, &QItemSelectionModel::selectionChanged, this,
             &QtInstanceTreeView::handleSelectionChanged);
@@ -1008,6 +1014,24 @@ QAbstractItemView::SelectionMode 
QtInstanceTreeView::mapSelectionMode(SelectionM
     }
 }
 
+QList<QList<Qt::ItemDataRole>> QtInstanceTreeView::columnRoles(QTreeView& 
rTreeView)
+{
+    QVariant aVariant = rTreeView.property(PROPERTY_COLUMN_ROLES);
+    if (aVariant.isValid())
+    {
+        assert(aVariant.canConvert<QList<QList<Qt::ItemDataRole>>>());
+        return aVariant.value<QList<QList<Qt::ItemDataRole>>>();
+    }
+
+    return {};
+}
+
+void QtInstanceTreeView::setColumnRoles(QTreeView& rTreeView,
+                                        const QList<QList<Qt::ItemDataRole>>& 
rDataRoles)
+{
+    rTreeView.setProperty(PROPERTY_COLUMN_ROLES, 
QVariant::fromValue(rDataRoles));
+}
+
 QModelIndex QtInstanceTreeView::modelIndex(int nRow, int nCol,
                                            const QModelIndex& rParentIndex) 
const
 {
@@ -1042,12 +1066,10 @@ QModelIndex 
QtInstanceTreeView::toggleButtonModelIndex(const weld::TreeIter& rIt
 
 QModelIndex QtInstanceTreeView::firstTextColumnModelIndex(const 
weld::TreeIter& rIter) const
 {
-    for (int i = 0; i < m_pModel->columnCount(); i++)
+    for (qsizetype i = 0; i < m_pColumnRoles.size(); i++)
     {
-        const QModelIndex aIndex = modelIndex(rIter, i);
-        QVariant data = m_pModel->data(aIndex, Qt::DisplayRole);
-        if (data.canConvert<QString>())
-            return aIndex;
+        if (m_pColumnRoles.at(i).contains(Qt::DisplayRole))
+            return modelIndex(rIter, i);
     }
 
     assert(false && "No text column found");
commit ea3259d1c109c87135f54ef065fa1beb30cadb28
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Sun Aug 3 22:15:20 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Mon Aug 4 09:01:13 2025 +0200

    tdf#130857 qt weld: Support Java "Class Path" dialog
    
    This means that native Qt widgets are used for that dialog
    now when using the qt5 or qt6 VCL plugin and starting LO with
    environment variable SAL_VCL_QT_USE_WELDED_WIDGETS=1 set.
    
    The dialog can be triggered as follows:
    
    * "Tools" -> "Options"
    * "LibreOfficDev" -> "Advanced"
    * select a JVM in the treeview
    * click the "Class Path" button
    
    Currently, both the icon and the path are displayed
    in the first column of the tree view and the second
    column remains empty. This will be addressed in
    upcoming commits.
    
    Change-Id: Id94e22e879f712bd967431ec0f9dc34e4480e3dd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188890
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx
index 718a53ece436..4eb3ceea0e14 100644
--- a/vcl/qt5/QtInstanceBuilder.cxx
+++ b/vcl/qt5/QtInstanceBuilder.cxx
@@ -75,6 +75,7 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& 
rUIFile, const weld::W
         u"cui/ui/graphictestdlg.ui"_ustr,
         u"cui/ui/imageviewer.ui"_ustr,
         u"cui/ui/insertrowcolumn.ui"_ustr,
+        u"cui/ui/javaclasspathdialog.ui"_ustr,
         u"cui/ui/javastartparametersdialog.ui"_ustr,
         u"cui/ui/linedialog.ui"_ustr,
         u"cui/ui/namedialog.ui"_ustr,
commit 54160ef0a5e6faa052f04a8d3ca3744943f6a8ef
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Sat Aug 2 23:49:53 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Mon Aug 4 09:01:07 2025 +0200

    dbaccess: Switch static helper to OExceptionChainDialog method
    
    This allows to use the m_xExceptionList member
    directly instead of passing it as a param.
    
    Change-Id: I74881c1ab5577a5b9dea424c887977f492b377ed
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188881
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/dbaccess/source/ui/dlg/sqlmessage.cxx 
b/dbaccess/source/ui/dlg/sqlmessage.cxx
index 3d15c662ea17..9fe71ae4b44f 100644
--- a/dbaccess/source/ui/dlg/sqlmessage.cxx
+++ b/dbaccess/source/ui/dlg/sqlmessage.cxx
@@ -247,11 +247,6 @@ namespace
             }
         }
     }
-
-    void lcl_insertExceptionEntry(weld::TreeView& rList, size_t nElementPos, 
const ExceptionDisplayInfo& rEntry)
-    {
-        rList.append(OUString::number(nElementPos), 
rEntry.pLabelProvider->getLabel(), rEntry.pImageProvider->getImage());
-    }
 }
 
 namespace {
@@ -271,6 +266,9 @@ public:
 
 protected:
     DECL_LINK(OnExceptionSelected, weld::TreeView&, void);
+
+private:
+    void insertExceptionEntry(size_t nElementPos, const ExceptionDisplayInfo& 
rEntry);
 };
 
 }
@@ -298,7 +296,7 @@ OExceptionChainDialog::OExceptionChainDialog(weld::Window* 
pParent, ExceptionDis
 
     for (auto const& elem : m_aExceptions)
     {
-        lcl_insertExceptionEntry(*m_xExceptionList, elementPos, elem);
+        insertExceptionEntry(elementPos, elem);
         bHave22018 = elem.sSQLState == "22018";
         ++elementPos;
     }
@@ -315,7 +313,7 @@ OExceptionChainDialog::OExceptionChainDialog(weld::Window* 
pParent, ExceptionDis
         aInfo22018.pImageProvider = aProviderFactory.getImageProvider( 
SQLExceptionInfo::TYPE::SQLContext );
         m_aExceptions.push_back( aInfo22018 );
 
-        lcl_insertExceptionEntry(*m_xExceptionList, m_aExceptions.size() - 1, 
aInfo22018);
+        insertExceptionEntry(m_aExceptions.size() - 1, aInfo22018);
     }
 
     if (m_xExceptionList->n_children())
@@ -325,6 +323,13 @@ OExceptionChainDialog::OExceptionChainDialog(weld::Window* 
pParent, ExceptionDis
     }
 }
 
+void OExceptionChainDialog::insertExceptionEntry(size_t nElementPos,
+                                                 const ExceptionDisplayInfo& 
rEntry)
+{
+    m_xExceptionList->append(OUString::number(nElementPos), 
rEntry.pLabelProvider->getLabel(),
+                             rEntry.pImageProvider->getImage());
+}
+
 IMPL_LINK_NOARG(OExceptionChainDialog, OnExceptionSelected, weld::TreeView&, 
void)
 {
     OUString sText;

Reply via email to