cui/inc/widgettestdlg.hxx            |    2 +
 cui/source/dialogs/widgettestdlg.cxx |   38 ++++++++++++++++++++++++++++++++---
 cui/uiconfig/ui/widgettestdialog.ui  |    3 --
 include/vcl/jsdialog/executor.hxx    |    5 ++++
 vcl/inc/jsdialog/jsdialogbuilder.hxx |    4 +++
 vcl/jsdialog/executor.cxx            |    6 +++++
 vcl/jsdialog/jsdialogbuilder.cxx     |   18 ++++++++++++++++
 vcl/source/treelist/svtabbx.cxx      |    7 +++++-
 8 files changed, 76 insertions(+), 7 deletions(-)

New commits:
commit ab4a8d550c278d2b39cd551fc1fcd8a5490404b6
Author:     Jaume Pujantell <[email protected]>
AuthorDate: Thu Feb 5 09:59:05 2026 +0100
Commit:     Jaume Pujantell <[email protected]>
CommitDate: Wed Feb 25 09:02:16 2026 +0100

    jsdialog: TreeView: handle column click and sort
    
    Added functionality to jsdialog of tree view widget to receive column
    click events, to send update on sort changes, and to send the placement
    of the sorting indicator.
    
    The widget test dialog also has been modified to be able to test this
    changes.
    
    Change-Id: I792df6f5df3daaabbbf9d736447faaac5e655f58
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198728
    Reviewed-by: Szymon Kłos <[email protected]>
    Reviewed-by: Jaume Pujantell <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199270
    (cherry picked from commit 042c1414a79e8780f6047fbcf7b9aa562158e17e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200216
    Tested-by: Jenkins

diff --git a/cui/inc/widgettestdlg.hxx b/cui/inc/widgettestdlg.hxx
index c3a02dbe5ecf..340d252db608 100644
--- a/cui/inc/widgettestdlg.hxx
+++ b/cui/inc/widgettestdlg.hxx
@@ -21,9 +21,11 @@ private:
     std::unique_ptr<weld::Button> m_xCancelButton;
     std::unique_ptr<weld::TreeView> m_xTreeView;
     std::unique_ptr<weld::TreeView> m_xTreeView2;
+    bool bIsTreeSorted = false;
 
     DECL_LINK(OkHdl, weld::Button&, void);
     DECL_LINK(CancelHdl, weld::Button&, void);
+    DECL_LINK(HeaderBarClick, int, void);
 
     void FillTreeView();
 
diff --git a/cui/source/dialogs/widgettestdlg.cxx 
b/cui/source/dialogs/widgettestdlg.cxx
index 7649328df9d8..758c3cfe1f25 100644
--- a/cui/source/dialogs/widgettestdlg.cxx
+++ b/cui/source/dialogs/widgettestdlg.cxx
@@ -23,6 +23,7 @@ WidgetTestDialog::WidgetTestDialog(weld::Window* pParent)
 
     m_xOKButton->connect_clicked(LINK(this, WidgetTestDialog, OkHdl));
     m_xCancelButton->connect_clicked(LINK(this, WidgetTestDialog, CancelHdl));
+    m_xTreeView2->connect_column_clicked(LINK(this, WidgetTestDialog, 
HeaderBarClick));
 
     FillTreeView();
 }
@@ -36,6 +37,37 @@ IMPL_LINK_NOARG(WidgetTestDialog, CancelHdl, weld::Button&, 
void)
     m_xDialog->response(RET_CANCEL);
 }
 
+IMPL_LINK(WidgetTestDialog, HeaderBarClick, int, nColumn, void)
+{
+    if (!bIsTreeSorted)
+    {
+        m_xTreeView2->make_sorted();
+        bIsTreeSorted = true;
+    }
+
+    bool bSortAtoZ = m_xTreeView2->get_sort_order();
+
+    //set new arrow positions in headerbar
+    if (nColumn == m_xTreeView2->get_sort_column())
+    {
+        bSortAtoZ = !bSortAtoZ;
+        m_xTreeView2->set_sort_order(bSortAtoZ);
+    }
+    else
+    {
+        int nOldSortColumn = m_xTreeView2->get_sort_column();
+        if (nOldSortColumn != -1)
+            m_xTreeView2->set_sort_indicator(TRISTATE_INDET, nOldSortColumn);
+        m_xTreeView2->set_sort_column(nColumn);
+    }
+
+    if (nColumn != -1)
+    {
+        //sort lists
+        m_xTreeView2->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : 
TRISTATE_FALSE, nColumn);
+    }
+}
+
 void WidgetTestDialog::FillTreeView()
 {
     OUString aImage1(RID_SVXBMP_CELL_LR);
@@ -61,10 +93,10 @@ void WidgetTestDialog::FillTreeView()
 
         int nRow = m_xTreeView2->n_children();
         m_xTreeView2->append();
-        m_xTreeView2->set_image(nRow, (nCount % 2 == 0) ? aImage1 : aImage2);
-        m_xTreeView2->set_text(nRow, u"First Column"_ustr, 0);
+        m_xTreeView2->set_image(nRow, (nCount % 2 == 0) ? aImage1 : aImage2, 
0);
+        m_xTreeView2->set_text(nRow, u"First Column"_ustr, 1);
         m_xTreeView2->set_text(
-            nRow, OUString::Concat("Row ") + 
OUString::Concat(OUString::number(nCount)), 1);
+            nRow, OUString::Concat("Row ") + 
OUString::Concat(OUString::number(nCount)), 2);
         m_xTreeView2->set_id(nRow, OUString::number(nCount));
     }
 }
diff --git a/cui/uiconfig/ui/widgettestdialog.ui 
b/cui/uiconfig/ui/widgettestdialog.ui
index d13ae9c5a473..e800bd6423e5 100644
--- a/cui/uiconfig/ui/widgettestdialog.ui
+++ b/cui/uiconfig/ui/widgettestdialog.ui
@@ -648,7 +648,6 @@
                           <object class="GtkTreeViewColumn" 
id="treeviewcolumn0">
                             <property name="resizable">True</property>
                             <property name="spacing">6</property>
-                            <property name="sort-indicator">True</property>
                             <property name="clickable">True</property>
                             <property name="title" 
translatable="no">.</property>
                             <child>
@@ -665,7 +664,6 @@
                             <property name="spacing">6</property>
                             <property name="title" translatable="no">Column 
1</property>
                             <property name="clickable">True</property>
-                            <property name="sort-indicator">True</property>
                             <child>
                               <object class="GtkCellRendererText" 
id="cellrenderer1"/>
                               <attributes>
@@ -680,7 +678,6 @@
                             <property name="spacing">6</property>
                             <property name="title" translatable="no">Column 
2</property>
                             <property name="clickable">True</property>
-                            <property name="sort-indicator">True</property>
                             <child>
                               <object class="GtkCellRendererText" 
id="cellrenderer2"/>
                               <attributes>
diff --git a/include/vcl/jsdialog/executor.hxx 
b/include/vcl/jsdialog/executor.hxx
index 04b6ca1d1ccc..e9d918a6e533 100644
--- a/include/vcl/jsdialog/executor.hxx
+++ b/include/vcl/jsdialog/executor.hxx
@@ -71,6 +71,11 @@ public:
         rTreeView.signal_command(rCommand);
     }
 
+    static void trigger_column_clicked(weld::TreeView& rTreeView, int nColumn)
+    {
+        rTreeView.signal_column_clicked(nColumn);
+    }
+
     static void trigger_activated(weld::Menu& rMenu, const OUString& rIdent)
     {
         rMenu.signal_activate(rIdent);
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx 
b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index 81fd9c7e31a2..9b93cda40890 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -743,6 +743,10 @@ public:
     virtual void expand_row(const weld::TreeIter& rIter) override;
     virtual void collapse_row(const weld::TreeIter& rIter) override;
 
+    virtual void set_sort_order(bool bAscending) override;
+    virtual void set_sort_indicator(TriState eState, int col) override;
+    virtual void set_sort_column(int col) override;
+
     virtual void do_set_cursor(const weld::TreeIter& rIter) override;
     void set_cursor_without_notify(const weld::TreeIter& rIter);
     virtual void do_set_cursor(int pos) override;
diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx
index 2d8c20fee822..15d97e18c181 100644
--- a/vcl/jsdialog/executor.cxx
+++ b/vcl/jsdialog/executor.cxx
@@ -681,6 +681,12 @@ bool ExecuteAction(const OUString& nWindowId, const 
OUString& rWidget, const Str
 
                     return true;
                 }
+                else if (sAction == "columnclick")
+                {
+                    sal_Int32 nColumn = o3tl::toInt32(rData.at(u"data"_ustr));
+                    LOKTrigger::trigger_column_clicked(*pTreeView, nColumn);
+                    return true;
+                }
             }
         }
         else if (sControlType == "iconview")
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index a60ae4ae1157..ba1bb6f9b199 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -1811,6 +1811,24 @@ void JSTreeView::collapse_row(const weld::TreeIter& 
rIter)
         sendUpdate();
 }
 
+void JSTreeView::set_sort_order(bool bAscending)
+{
+    SalInstanceTreeView::set_sort_order(bAscending);
+    sendUpdate();
+}
+
+void JSTreeView::set_sort_indicator(TriState eState, int col)
+{
+    SalInstanceTreeView::set_sort_indicator(eState, col);
+    sendUpdate();
+}
+
+void JSTreeView::set_sort_column(int col)
+{
+    SalInstanceTreeView::set_sort_column(col);
+    sendUpdate();
+}
+
 void JSTreeView::render_entry(int pos, int dpix, int dpiy)
 {
     ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::WITHOUT_ALPHA);
diff --git a/vcl/source/treelist/svtabbx.cxx b/vcl/source/treelist/svtabbx.cxx
index c21102898dd0..75c0fa5a8cb2 100644
--- a/vcl/source/treelist/svtabbx.cxx
+++ b/vcl/source/treelist/svtabbx.cxx
@@ -622,8 +622,13 @@ void 
SvHeaderTabListBox::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter)
     {
         auto aNode = rJsonWriter.startStruct();
         sal_uInt16 nItemId = pHeaderBar->GetItemId(i);
+        HeaderBarItemBits eItemBits = pHeaderBar->GetItemBits(nItemId);
         rJsonWriter.put("text", pHeaderBar->GetItemText(nItemId));
-        rJsonWriter.put("sortable", !!(pHeaderBar->GetItemBits(nItemId) & 
HeaderBarItemBits::CLICKABLE));
+        rJsonWriter.put("sortable", !!(eItemBits & 
HeaderBarItemBits::CLICKABLE));
+        if (eItemBits & HeaderBarItemBits::UPARROW)
+            rJsonWriter.put("arrow", "up");
+        else if (eItemBits & HeaderBarItemBits::DOWNARROW)
+            rJsonWriter.put("arrow", "down");
     }
 }
 

Reply via email to