include/vcl/weld/ItemView.hxx      |    7 +-
 vcl/inc/qt5/QtInstanceItemView.hxx |    6 +-
 vcl/inc/salvtables.hxx             |    6 +-
 vcl/qt5/QtInstanceItemView.cxx     |    4 -
 vcl/source/app/salvtables.cxx      |   44 ++++++++++-----
 vcl/source/weld/ItemView.cxx       |   14 ++++
 vcl/unx/gtk3/gtkinst.cxx           |  104 ++++++++++++++++++++++---------------
 7 files changed, 118 insertions(+), 67 deletions(-)

New commits:
commit a032c05dc8dda17c649ee566213fb01a52a8b292
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Dec 18 20:16:33 2025 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Dec 19 09:20:44 2025 +0100

    vcl/gtk weld: Implement (un)select_all without forwarding
    
    In the weld::ItemView subclasses in the vcl implementation
    (SalInstanceItemView) and the gtk one (GtkInstanceTreeView
    and GtkInstanceIconView), no longer let
    
    * unselect_all() call select(-1)
    * select_all() call unselect(-1)
    
    and have logic in their weld::ItemView::select
    and weld::ItemView::unselect overrides to select all or
    clear selection all when called with those special indices.
    
    Instead, let select() and unselect() call unselect_all()
    and select_all() when called with the special indices,
    i.e. forward the other way around and move the toolkit-specific
    logic to (un)select all to the select_all()/unselect_all()
    implementations.
    
    This prepares for an upcoming commit that will
    implement the index-based weld::ItemView::select
    and weld::ItemView::unselect directly in the
    weld::ItemView base class, i.e. the previous special
    handling in the GTK and vcl implementations will
    be dropped.
    
    But the new logic to call (un)select_all() can be implemented
    directly in the weld::ItemView base class as well.
    
    No change in behavior intended.
    
    Change-Id: I440cfa39fcc24231c6a72a67e079232c29c46900
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195867
    Reviewed-by: Michael Weghorn <[email protected]>
    Tested-by: Jenkins

diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 9925e8b83478..c2109b37469a 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3551,9 +3551,21 @@ OUString SalInstanceItemView::get_selected_text() const
     return OUString();
 }
 
-void SalInstanceItemView::do_select_all() { do_unselect(-1); }
+void SalInstanceItemView::do_select_all()
+{
+    assert(m_pTreeListBox->IsUpdateMode()
+           && "don't select when frozen, select after thaw. Note selection 
doesn't survive a "
+              "freeze");
+    m_pTreeListBox->SelectAll(true);
+}
 
-void SalInstanceItemView::do_unselect_all() { do_select(-1); }
+void SalInstanceItemView::do_unselect_all()
+{
+    assert(m_pTreeListBox->IsUpdateMode()
+           && "don't select when frozen, select after thaw. Note selection 
doesn't survive a "
+              "freeze");
+    m_pTreeListBox->SelectAll(false);
+}
 
 int SalInstanceItemView::n_children() const
 {
@@ -3562,18 +3574,19 @@ int SalInstanceItemView::n_children() const
 
 void SalInstanceItemView::do_select(int pos)
 {
-    assert(m_pTreeListBox->IsUpdateMode()
-           && "don't select when frozen, select after thaw. Note selection 
doesn't survive a "
-              "freeze");
     if (pos == -1 || (pos == 0 && n_children() == 0))
-        m_pTreeListBox->SelectAll(false);
-    else
     {
-        SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry(nullptr, pos);
-        assert(pEntry && "bad pos?");
-        m_pTreeListBox->Select(pEntry, true);
-        m_pTreeListBox->MakeVisible(pEntry);
+        do_unselect_all();
+        return;
     }
+
+    assert(m_pTreeListBox->IsUpdateMode()
+           && "don't select when frozen, select after thaw. Note selection 
doesn't survive a "
+              "freeze");
+    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry(nullptr, pos);
+    assert(pEntry && "bad pos?");
+    m_pTreeListBox->Select(pEntry, true);
+    m_pTreeListBox->MakeVisible(pEntry);
 }
 
 void SalInstanceItemView::do_select(const weld::TreeIter& rIter)
@@ -3593,12 +3606,13 @@ void SalInstanceItemView::do_unselect(int pos)
            && "don't select when frozen, select after thaw. Note selection 
doesn't survive a "
               "freeze");
     if (pos == -1)
-        m_pTreeListBox->SelectAll(true);
-    else
     {
-        SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry(nullptr, pos);
-        m_pTreeListBox->Select(pEntry, false);
+        do_select_all();
+        return;
     }
+
+    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry(nullptr, pos);
+    m_pTreeListBox->Select(pEntry, false);
 }
 
 void SalInstanceItemView::do_unselect(const weld::TreeIter& rIter)
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index ac3dbb66701a..853cd80350be 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -15200,9 +15200,21 @@ public:
         gtk_tree_sortable_sort_column_changed(pSortable);
     }
 
-    virtual void do_select_all() override { do_unselect(-1); }
+    virtual void do_select_all() override
+    {
+        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
+        disable_notify_events();
+        
gtk_tree_selection_select_all(gtk_tree_view_get_selection(m_pTreeView));
+        enable_notify_events();
+    }
 
-    virtual void do_unselect_all() override { do_select(-1); }
+    virtual void do_unselect_all() override
+    {
+        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
+        disable_notify_events();
+        
gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(m_pTreeView));
+        enable_notify_events();
+    }
 
     virtual int n_children() const override
     {
@@ -15217,19 +15229,18 @@ public:
 
     virtual void do_select(int pos) override
     {
-        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
-        disable_notify_events();
         if (pos == -1 || (pos == 0 && n_children() == 0))
         {
-            
gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(m_pTreeView));
-        }
-        else
-        {
-            GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
-            
gtk_tree_selection_select_path(gtk_tree_view_get_selection(m_pTreeView), path);
-            gtk_tree_view_scroll_to_cell(m_pTreeView, path, nullptr, false, 0, 
0);
-            gtk_tree_path_free(path);
+            do_unselect_all();
+            return;
         }
+
+        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
+        disable_notify_events();
+        GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
+        
gtk_tree_selection_select_path(gtk_tree_view_get_selection(m_pTreeView), path);
+        gtk_tree_view_scroll_to_cell(m_pTreeView, path, nullptr, false, 0, 0);
+        gtk_tree_path_free(path);
         enable_notify_events();
     }
 
@@ -15269,18 +15280,17 @@ public:
 
     virtual void do_unselect(int pos) override
     {
-        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
-        disable_notify_events();
         if (pos == -1 || (pos == 0 && n_children() == 0))
         {
-            
gtk_tree_selection_select_all(gtk_tree_view_get_selection(m_pTreeView));
-        }
-        else
-        {
-            GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
-            
gtk_tree_selection_unselect_path(gtk_tree_view_get_selection(m_pTreeView), 
path);
-            gtk_tree_path_free(path);
+            do_select_all();
+            return;
         }
+
+        assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
+        disable_notify_events();
+        GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
+        
gtk_tree_selection_unselect_path(gtk_tree_view_get_selection(m_pTreeView), 
path);
+        gtk_tree_path_free(path);
         enable_notify_events();
     }
 
@@ -17176,19 +17186,18 @@ public:
 
     virtual void do_select(int pos) override
     {
-        assert(gtk_icon_view_get_model(m_pIconView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
-        disable_notify_events();
         if (pos == -1 || (pos == 0 && n_children() == 0))
         {
-            gtk_icon_view_unselect_all(m_pIconView);
-        }
-        else
-        {
-            GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
-            gtk_icon_view_select_path(m_pIconView, path);
-            gtk_icon_view_scroll_to_path(m_pIconView, path, false, 0, 0);
-            gtk_tree_path_free(path);
+            do_unselect_all();
+            return;
         }
+
+        assert(gtk_icon_view_get_model(m_pIconView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
+        disable_notify_events();
+        GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
+        gtk_icon_view_select_path(m_pIconView, path);
+        gtk_icon_view_scroll_to_path(m_pIconView, path, false, 0, 0);
+        gtk_tree_path_free(path);
         enable_notify_events();
     }
 
@@ -17207,18 +17216,17 @@ public:
 
     virtual void do_unselect(int pos) override
     {
-        assert(gtk_icon_view_get_model(m_pIconView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
-        disable_notify_events();
         if (pos == -1 || (pos == 0 && n_children() == 0))
         {
-            gtk_icon_view_select_all(m_pIconView);
-        }
-        else
-        {
-            GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
-            gtk_icon_view_unselect_path(m_pIconView, path);
-            gtk_tree_path_free(path);
+            do_select_all();
+            return;
         }
+
+        assert(gtk_icon_view_get_model(m_pIconView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
+        disable_notify_events();
+        GtkTreePath* path = gtk_tree_path_new_from_indices(pos, -1);
+        gtk_icon_view_unselect_path(m_pIconView, path);
+        gtk_tree_path_free(path);
         enable_notify_events();
     }
 
@@ -17307,9 +17315,21 @@ public:
         g_list_free_full(pList, 
reinterpret_cast<GDestroyNotify>(gtk_tree_path_free));
     }
 
-    virtual void do_select_all() override { do_unselect(-1); }
+    virtual void do_select_all() override
+    {
+        assert(gtk_icon_view_get_model(m_pIconView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
+        disable_notify_events();
+        gtk_icon_view_select_all(m_pIconView);
+        enable_notify_events();
+    }
 
-    virtual void do_unselect_all() override { do_select(-1); }
+    virtual void do_unselect_all() override
+    {
+        assert(gtk_icon_view_get_model(m_pIconView) && "don't select when 
frozen, select after thaw. Note selection doesn't survive a freeze");
+        disable_notify_events();
+        gtk_icon_view_unselect_all(m_pIconView);
+        enable_notify_events();
+    }
 
     virtual int n_children() const override
     {
commit ef8817e5793fcbf3324f351087d0b9623b68c1ce
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Dec 18 19:54:25 2025 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Dec 19 09:20:37 2025 +0100

    tdf#130857 weld: Move signal blocking to ItemView::{un,}select_all
    
    This is similar to
    
        commit 039f89a0b91ee03b9357b2082bfe17e8769e1573
        Author: Michael Weghorn <[email protected]>
        Date:   Fri Oct 17 22:11:02 2025 +0200
    
            tdf#130857 weld: Move signal blocking to TextView::select_region
    
    , but for a different method:
    
    The GTK and vcl/SalInstance implementations of
    select_all() and unselect_all() implicitly block
    signals by calling unselect() and select() with a
    special index of -1. Then, weld::ItemView::unselect
    and weld::ItemView::select would take care of blocking
    signals while calling do_unselect() and do_select().
    
    The QtInstanceItemView implementations on the other
    hand implement the logic directly, so would not
    block the signals.
    
    This also prepares for implementing the logic
    to (un)select all directly in the GTK and vcl
    implementations in an upcoming commit, in order
    to prepare for further refactoring.
    
    Change-Id: Ie0453f63715b05339df530975faec095b472fedb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195866
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/include/vcl/weld/ItemView.hxx b/include/vcl/weld/ItemView.hxx
index 27f1f3b82723..534138dac574 100644
--- a/include/vcl/weld/ItemView.hxx
+++ b/include/vcl/weld/ItemView.hxx
@@ -26,6 +26,9 @@ protected:
     virtual void do_unselect(int pos) = 0;
     virtual void do_unselect(const TreeIter& rIter) = 0;
 
+    virtual void do_select_all() = 0;
+    virtual void do_unselect_all() = 0;
+
     virtual void do_clear() = 0;
 
 public:
@@ -46,8 +49,8 @@ public:
     void unselect(int pos);
     void unselect(const TreeIter& rIter);
 
-    virtual void select_all() = 0;
-    virtual void unselect_all() = 0;
+    void select_all();
+    void unselect_all();
 
     // return the number of toplevel nodes
     virtual int n_children() const = 0;
diff --git a/vcl/inc/qt5/QtInstanceItemView.hxx 
b/vcl/inc/qt5/QtInstanceItemView.hxx
index 52cc27a81fc2..2c039ddf3cd5 100644
--- a/vcl/inc/qt5/QtInstanceItemView.hxx
+++ b/vcl/inc/qt5/QtInstanceItemView.hxx
@@ -24,6 +24,9 @@ class QtInstanceItemView : public QtInstanceWidget, public 
virtual weld::ItemVie
     QAbstractItemModel& m_rModel;
 
 protected:
+    virtual void do_select_all() override;
+    virtual void do_unselect_all() override;
+
     void do_clear() override;
 
 public:
@@ -34,9 +37,6 @@ public:
 
     virtual std::unique_ptr<weld::TreeIter> get_iterator(int nPos) const 
override;
 
-    virtual void select_all() override;
-    virtual void unselect_all() override;
-
 protected:
     QModelIndex modelIndex(int nRow, int nCol = 0,
                            const QModelIndex& rParentIndex = QModelIndex()) 
const;
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index bbb9602b30c2..5bebf85307ff 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -1502,6 +1502,9 @@ protected:
     virtual void do_unselect(int pos) override;
     virtual void do_unselect(const weld::TreeIter& rIter) override;
 
+    virtual void do_select_all() override;
+    virtual void do_unselect_all() override;
+
     virtual void do_clear() override;
 
 public:
@@ -1513,9 +1516,6 @@ public:
     virtual OUString get_selected_id() const override;
     virtual OUString get_selected_text() const override;
 
-    virtual void select_all() override;
-    virtual void unselect_all() override;
-
     virtual int n_children() const override;
 };
 
diff --git a/vcl/qt5/QtInstanceItemView.cxx b/vcl/qt5/QtInstanceItemView.cxx
index 8612af62de7d..19281ede8438 100644
--- a/vcl/qt5/QtInstanceItemView.cxx
+++ b/vcl/qt5/QtInstanceItemView.cxx
@@ -31,13 +31,13 @@ std::unique_ptr<weld::TreeIter> 
QtInstanceItemView::get_iterator(int nPos) const
     return {};
 }
 
-void QtInstanceItemView::select_all()
+void QtInstanceItemView::do_select_all()
 {
     SolarMutexGuard g;
     GetQtInstance().RunInMainThread([&] { getItemView().selectAll(); });
 }
 
-void QtInstanceItemView::unselect_all()
+void QtInstanceItemView::do_unselect_all()
 {
     SolarMutexGuard g;
     GetQtInstance().RunInMainThread([&] { getItemView().clearSelection(); });
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index d328ac42e253..9925e8b83478 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3551,9 +3551,9 @@ OUString SalInstanceItemView::get_selected_text() const
     return OUString();
 }
 
-void SalInstanceItemView::select_all() { unselect(-1); }
+void SalInstanceItemView::do_select_all() { do_unselect(-1); }
 
-void SalInstanceItemView::unselect_all() { select(-1); }
+void SalInstanceItemView::do_unselect_all() { do_select(-1); }
 
 int SalInstanceItemView::n_children() const
 {
diff --git a/vcl/source/weld/ItemView.cxx b/vcl/source/weld/ItemView.cxx
index 0b866abadfa8..bc64a59a2716 100644
--- a/vcl/source/weld/ItemView.cxx
+++ b/vcl/source/weld/ItemView.cxx
@@ -39,6 +39,20 @@ void ItemView::unselect(const TreeIter& rIter)
     enable_notify_events();
 }
 
+void ItemView::select_all()
+{
+    disable_notify_events();
+    do_select_all();
+    enable_notify_events();
+}
+
+void ItemView::unselect_all()
+{
+    disable_notify_events();
+    do_unselect_all();
+    enable_notify_events();
+}
+
 void ItemView::clear()
 {
     disable_notify_events();
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 0a0ef160bb06..ac3dbb66701a 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -15200,9 +15200,9 @@ public:
         gtk_tree_sortable_sort_column_changed(pSortable);
     }
 
-    virtual void select_all() override { unselect(-1); }
+    virtual void do_select_all() override { do_unselect(-1); }
 
-    virtual void unselect_all() override { select(-1); }
+    virtual void do_unselect_all() override { do_select(-1); }
 
     virtual int n_children() const override
     {
@@ -17307,9 +17307,9 @@ public:
         g_list_free_full(pList, 
reinterpret_cast<GDestroyNotify>(gtk_tree_path_free));
     }
 
-    virtual void select_all() override { unselect(-1); }
+    virtual void do_select_all() override { do_unselect(-1); }
 
-    virtual void unselect_all() override { select(-1); }
+    virtual void do_unselect_all() override { do_select(-1); }
 
     virtual int n_children() const override
     {

Reply via email to