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 39526f27f6aa705cefd57a0eab5ac562c8de5025
Author:     Jaume Pujantell <[email protected]>
AuthorDate: Thu Feb 5 09:59:05 2026 +0100
Commit:     Jaume Pujantell <[email protected]>
CommitDate: Tue Feb 10 09:29:28 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]>

diff --git a/cui/inc/widgettestdlg.hxx b/cui/inc/widgettestdlg.hxx
index 02ab7f317894..da00193adb5a 100644
--- a/cui/inc/widgettestdlg.hxx
+++ b/cui/inc/widgettestdlg.hxx
@@ -20,9 +20,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 690e474ded09..4c751f9d7f27 100644
--- a/cui/source/dialogs/widgettestdlg.cxx
+++ b/cui/source/dialogs/widgettestdlg.cxx
@@ -20,6 +20,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();
 }
@@ -33,6 +34,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);
@@ -58,10 +90,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 8975f96a63e1..4fd94ca4d70d 100644
--- a/cui/uiconfig/ui/widgettestdialog.ui
+++ b/cui/uiconfig/ui/widgettestdialog.ui
@@ -624,7 +624,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>
@@ -639,7 +638,6 @@
                           <object class="GtkTreeViewColumn" 
id="treeviewcolumn1">
                             <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">Column 
1</property>
                             <child>
@@ -654,7 +652,6 @@
                           <object class="GtkTreeViewColumn" 
id="treeviewcolumn2">
                             <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">Column 
2</property>
                             <child>
diff --git a/include/vcl/jsdialog/executor.hxx 
b/include/vcl/jsdialog/executor.hxx
index b08e16c0bf07..ead70c0e4570 100644
--- a/include/vcl/jsdialog/executor.hxx
+++ b/include/vcl/jsdialog/executor.hxx
@@ -57,6 +57,11 @@ public:
         rTreeView.signal_popup_menu(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 1ca26e6a2bac..2650ccabd3c5 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -744,6 +744,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 set_cursor(const weld::TreeIter& rIter) override;
     void set_cursor_without_notify(const weld::TreeIter& rIter);
     virtual void set_cursor(int pos) override;
diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx
index e53fd13ea7d3..14eb8c0cc56e 100644
--- a/vcl/jsdialog/executor.cxx
+++ b/vcl/jsdialog/executor.cxx
@@ -680,6 +680,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 89cba1114e87..bca7c6de7d69 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -1878,6 +1878,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 506de9f3e5ce..d03d24dcc3dc 100644
--- a/vcl/source/treelist/svtabbx.cxx
+++ b/vcl/source/treelist/svtabbx.cxx
@@ -658,8 +658,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