include/vcl/weld/IconView.hxx        |    4 +-
 include/vcl/weld/ItemView.hxx        |    3 -
 sd/source/ui/sidebar/LayoutMenu.cxx  |   15 +------
 vcl/inc/jsdialog/jsdialogbuilder.hxx |    5 --
 vcl/inc/qt5/QtInstanceIconView.hxx   |    3 -
 vcl/inc/qt5/QtInstanceTreeView.hxx   |    2 -
 vcl/inc/salvtables.hxx               |    3 -
 vcl/jsdialog/jsdialogbuilder.cxx     |   41 ---------------------
 vcl/qt5/QtInstanceIconView.cxx       |    4 --
 vcl/qt5/QtInstanceTreeView.cxx       |    4 --
 vcl/source/app/salvtables.cxx        |   32 ----------------
 vcl/source/weld/IconView.cxx         |   15 +++++++
 vcl/source/weld/ItemView.cxx         |   22 ++++++++---
 vcl/unx/gtk3/gtkinst.cxx             |   66 -----------------------------------
 14 files changed, 36 insertions(+), 183 deletions(-)

New commits:
commit 0e323f194be7065a23dc6a55b1dc994adf647467
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Dec 18 21:26:41 2025 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Dec 19 09:21:02 2025 +0100

    tdf#168594 weld: Add IconView::get_item_at_rect
    
    This method returns an iter to the item at the
    given position.
    
    Corresponding GTK API: gtk_icon_view_get_item_at_pos [1].
    Qt also has similar API with QAbstractItemView::indexAt [2].
    
    Initially, take over the logic already implemented in
    LayoutMenu::CommandHdl (though the logic there uses indices
    instead of iters) and use the newly added method in there.
    (Using the mentioned GTK or Qt API for those VCL plugins
    in the future could be an option.)
    
    No change in behavior intended or seen in a quick test of
    the scenario described in
    
        commit 3e0e0429aab01faafeb4faccbb5aa2800cbd9315
        Author: Michael Weghorn <[email protected]>
        Date:   Wed Dec 17 17:15:08 2025 +0100
    
            weld: Add weld::IconView::get_rect taking iter param
    
    Having the logic in weld::IconView allows it to be
    reused from elsewhere in upcoming commits.
    
    [1] https://docs.gtk.org/gtk3/method.IconView.get_item_at_pos.html
    [2] https://doc.qt.io/qt-6/qabstractitemview.html#indexAt
    
    Change-Id: I637c6c59263b0238ba21bfe39ea866666b964778
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195870
    Reviewed-by: Michael Weghorn <[email protected]>
    Tested-by: Jenkins

diff --git a/include/vcl/weld/IconView.hxx b/include/vcl/weld/IconView.hxx
index 65d109c96fc1..1ef8c9aca6cc 100644
--- a/include/vcl/weld/IconView.hxx
+++ b/include/vcl/weld/IconView.hxx
@@ -134,10 +134,10 @@ public:
     }
 
     tools::Rectangle get_rect(int pos) const;
-
-    //via iter
     virtual tools::Rectangle get_rect(const TreeIter& rIter) const = 0;
 
+    std::unique_ptr<weld::TreeIter> get_item_at_pos(const Point& rPos);
+
     void set_cursor(const TreeIter& rIter)
     {
         disable_notify_events();
diff --git a/sd/source/ui/sidebar/LayoutMenu.cxx 
b/sd/source/ui/sidebar/LayoutMenu.cxx
index 95afba573d26..3cb443003e41 100644
--- a/sd/source/ui/sidebar/LayoutMenu.cxx
+++ b/sd/source/ui/sidebar/LayoutMenu.cxx
@@ -234,19 +234,10 @@ IMPL_LINK(LayoutMenu, CommandHdl, const CommandEvent&, 
rEvent, bool)
     if (rEvent.IsMouseEvent())
     {
         aPos = rEvent.GetMousePosPixel();
-        bool bFound = false;
-        for (int i = 0; i < mxLayoutIconView->n_children(); i++)
-        {
-            const ::tools::Rectangle aRect = mxLayoutIconView->get_rect(i);
-            if (aRect.Contains(aPos))
-            {
-                mxLayoutIconView->select(i);
-                bFound = true;
-                break;
-            }
-        }
-        if (!bFound)
+        std::unique_ptr<weld::TreeIter> pIter = 
mxLayoutIconView->get_item_at_pos(aPos);
+        if (!pIter)
             return false;
+        mxLayoutIconView->select(*pIter);
     }
     else
     {
diff --git a/vcl/source/weld/IconView.cxx b/vcl/source/weld/IconView.cxx
index 810b700c4e45..f1baedc4fd85 100644
--- a/vcl/source/weld/IconView.cxx
+++ b/vcl/source/weld/IconView.cxx
@@ -18,6 +18,21 @@ tools::Rectangle IconView::get_rect(int pos) const
 
     return {};
 }
+
+std::unique_ptr<weld::TreeIter> IconView::get_item_at_pos(const Point& rPos)
+{
+    std::unique_ptr<weld::TreeIter> pIter = make_iterator();
+    bool bIterValid = get_iter_first(*pIter);
+    while (bIterValid)
+    {
+        if (get_rect(*pIter).Contains(rPos))
+            return pIter;
+
+        bIterValid = iter_next_sibling(*pIter);
+    }
+
+    return {};
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
commit fc46e40c0e624f632cd96b2ee96c324c277a0a47
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Dec 18 20:26:56 2025 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Fri Dec 19 09:20:54 2025 +0100

    weld: Implement index-based ItemView (un)selection in base class
    
    This replaces the toolkit-specific implementations
    of weld::ItemView::select and weld::ItemView::unselect
    taking an index by implementing the logic directly
    in the abstract weld::ItemView base class, using
    the toolkit-specific weld::ItemView::select
    weld::ItemView::unselect implementations taking
    a TreeIter param instead.
    
    Take over the special handling (for an index of -1
    or empty view) from the SalInstanceItemView implementation.
    (The gtk implementation is similar. The qt implementation
    didn't have this yet.)
    
    This allows deduplicating and simplifying the toolkit
    specific implementations.
    
    This implements what was previous mentioned in
    
        Change-Id: Iec7a4704b89c42ec692c7a22beb0dfc0ecb98a8c
        Author: Michael Weghorn <[email protected]>
        Date:   Thu Dec 18 18:53:52 2025 +0100
    
            weld: Add iter-based IconView::(un)select
    
            [...]
            While this temporarily adds more duplication, this
            will be reduced again in an upcoming commit when
            the index-based implementations will be implemented
            in the weld::ItemView base class right away (based
            on the new one taking an iter, similar to what
            IconView::get_rect already does), allowing to drop the
            toolkit-specific implementations taking an index for
            both, weld::TreeView and weld::IconView.
    
    Change-Id: Idefeb3d1514ccf8f64723abfa75e3495f8233836
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195868
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/include/vcl/weld/ItemView.hxx b/include/vcl/weld/ItemView.hxx
index 534138dac574..4d661282ae62 100644
--- a/include/vcl/weld/ItemView.hxx
+++ b/include/vcl/weld/ItemView.hxx
@@ -20,10 +20,7 @@ class VCL_DLLPUBLIC ItemView : virtual public Widget
     OUString m_sSavedValue;
 
 protected:
-    virtual void do_select(int pos) = 0;
     virtual void do_select(const TreeIter& rIter) = 0;
-
-    virtual void do_unselect(int pos) = 0;
     virtual void do_unselect(const TreeIter& rIter) = 0;
 
     virtual void do_select_all() = 0;
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx 
b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index 6c84206f1c71..2f2ea25d0f6b 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -725,9 +725,6 @@ public:
     virtual void set_sensitive(int pos, bool bSensitive, int col = -1) 
override;
     virtual void set_sensitive(const weld::TreeIter& rIter, bool bSensitive, 
int col = -1) override;
 
-    using SalInstanceTreeView::do_select;
-    /// pos is used differently here, it defines how many steps of iterator we 
need to perform to take entry
-    virtual void do_select(int pos) override;
     virtual void do_select(const weld::TreeIter& rIter) override;
 
     virtual weld::TreeView* get_drag_source() const override;
@@ -786,9 +783,7 @@ public:
     virtual void insert_separator(int pos, const OUString* pId) override;
 
     virtual void do_clear() override;
-    virtual void do_select(int pos) override;
     virtual void do_select(const weld::TreeIter& rIter) override;
-    virtual void do_unselect(int pos) override;
     virtual void do_unselect(const weld::TreeIter& rIter) override;
 
     // OnDemandRenderingHandler
diff --git a/vcl/inc/qt5/QtInstanceIconView.hxx 
b/vcl/inc/qt5/QtInstanceIconView.hxx
index f14fdf20c47b..aab0ff9fbd25 100644
--- a/vcl/inc/qt5/QtInstanceIconView.hxx
+++ b/vcl/inc/qt5/QtInstanceIconView.hxx
@@ -46,10 +46,7 @@ public:
 
     virtual OUString get_id(int nPos) const override;
 
-    virtual void do_select(int nPos) override;
     virtual void do_select(const weld::TreeIter& rIter) override;
-
-    virtual void do_unselect(int nPos) override;
     virtual void do_unselect(const weld::TreeIter& rIter) override;
 
     virtual void set_image(int nPos, VirtualDevice& rDevice) override;
diff --git a/vcl/inc/qt5/QtInstanceTreeView.hxx 
b/vcl/inc/qt5/QtInstanceTreeView.hxx
index cbc995b1ca8e..ec489b1ba480 100644
--- a/vcl/inc/qt5/QtInstanceTreeView.hxx
+++ b/vcl/inc/qt5/QtInstanceTreeView.hxx
@@ -56,8 +56,6 @@ public:
     virtual void set_clicks_to_toggle(int nToggleBehavior) override;
 
     virtual int get_selected_index() const override;
-    virtual void do_select(int nPos) override;
-    virtual void do_unselect(int nPos) override;
     virtual void do_remove(int nPos) override;
     virtual OUString get_text(int nRow, int nCol = -1) const override;
     virtual void set_text(int nRow, const OUString& rText, int nCol = -1) 
override;
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 5bebf85307ff..d9a9ab4092e0 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -1496,10 +1496,7 @@ protected:
     SalInstanceItemView(SvTreeListBox* pTreeListBox, SalInstanceBuilder* 
pBuilder,
                         bool bTakeOwnership);
 
-    virtual void do_select(int pos) override;
     virtual void do_select(const weld::TreeIter& rIter) override;
-
-    virtual void do_unselect(int pos) override;
     virtual void do_unselect(const weld::TreeIter& rIter) override;
 
     virtual void do_select_all() override;
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index ae9d458bf797..aa3bd95861f7 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -1728,31 +1728,6 @@ void JSTreeView::set_sensitive(const weld::TreeIter& 
rIter, bool bSensitive, int
     sendUpdate();
 }
 
-void JSTreeView::do_select(int pos)
-{
-    assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
-    if (pos == -1 || (pos == 0 && n_children() == 0))
-        m_xTreeView->SelectAll(false);
-    else
-    {
-        SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0);
-
-        while (pEntry && pos--)
-            pEntry = m_xTreeView->Next(pEntry);
-
-        if (pEntry)
-        {
-            m_xTreeView->Select(pEntry, true);
-            m_xTreeView->MakeVisible(pEntry);
-        }
-    }
-
-    std::unique_ptr<jsdialog::ActionDataMap> pMap = 
std::make_unique<jsdialog::ActionDataMap>();
-    (*pMap)[ACTION_TYPE ""_ostr] = "select";
-    (*pMap)["position"_ostr] = OUString::number(pos);
-    sendAction(std::move(pMap));
-}
-
 void JSTreeView::do_select(const weld::TreeIter& rIter)
 {
     SalInstanceTreeView::do_select(rIter);
@@ -1940,16 +1915,6 @@ void JSIconView::do_clear()
     sendUpdate();
 }
 
-void JSIconView::do_select(int pos)
-{
-    SalInstanceIconView::do_select(pos);
-
-    std::unique_ptr<jsdialog::ActionDataMap> pMap = 
std::make_unique<jsdialog::ActionDataMap>();
-    (*pMap)[ACTION_TYPE ""_ostr] = "select";
-    (*pMap)["position"_ostr] = OUString::number(pos);
-    sendAction(std::move(pMap));
-}
-
 void JSIconView::do_select(const weld::TreeIter& rIter)
 {
     SalInstanceIconView::do_select(rIter);
@@ -1961,12 +1926,6 @@ void JSIconView::do_select(const weld::TreeIter& rIter)
     sendAction(std::move(pMap));
 }
 
-void JSIconView::do_unselect(int pos)
-{
-    SalInstanceIconView::do_unselect(pos);
-    sendUpdate();
-}
-
 void JSIconView::do_unselect(const weld::TreeIter& rIter)
 {
     SalInstanceIconView::do_unselect(rIter);
diff --git a/vcl/qt5/QtInstanceIconView.cxx b/vcl/qt5/QtInstanceIconView.cxx
index 4d1753d33296..fc203f0f0c23 100644
--- a/vcl/qt5/QtInstanceIconView.cxx
+++ b/vcl/qt5/QtInstanceIconView.cxx
@@ -133,8 +133,6 @@ OUString QtInstanceIconView::get_selected_text() const
 
 OUString QtInstanceIconView::get_id(int nPos) const { return 
get_id(treeIter(nPos)); }
 
-void QtInstanceIconView::do_select(int nPos) { do_select(treeIter(nPos)); }
-
 void QtInstanceIconView::do_select(const weld::TreeIter& rIter)
 {
     SolarMutexGuard g;
@@ -142,8 +140,6 @@ void QtInstanceIconView::do_select(const weld::TreeIter& 
rIter)
         [&] { m_pSelectionModel->select(modelIndex(rIter), 
QItemSelectionModel::Select); });
 }
 
-void QtInstanceIconView::do_unselect(int nPos) { do_unselect(treeIter(nPos)); }
-
 void QtInstanceIconView::do_unselect(const weld::TreeIter& rIter)
 {
     SolarMutexGuard g;
diff --git a/vcl/qt5/QtInstanceTreeView.cxx b/vcl/qt5/QtInstanceTreeView.cxx
index 8feaeee2d7e7..18d6874f18dc 100644
--- a/vcl/qt5/QtInstanceTreeView.cxx
+++ b/vcl/qt5/QtInstanceTreeView.cxx
@@ -162,10 +162,6 @@ int QtInstanceTreeView::get_selected_index() const
     return nIndex;
 }
 
-void QtInstanceTreeView::do_select(int nPos) { do_select(treeIter(nPos)); }
-
-void QtInstanceTreeView::do_unselect(int nPos) { do_unselect(treeIter(nPos)); }
-
 void QtInstanceTreeView::do_remove(int nPos) { do_remove(treeIter(nPos)); }
 
 OUString QtInstanceTreeView::get_text(int nRow, int nCol) const
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index c2109b37469a..f4700b05f106 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3572,23 +3572,6 @@ int SalInstanceItemView::n_children() const
     return m_pTreeListBox->GetModel()->GetChildList(nullptr).size();
 }
 
-void SalInstanceItemView::do_select(int pos)
-{
-    if (pos == -1 || (pos == 0 && n_children() == 0))
-    {
-        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)
 {
     assert(m_pTreeListBox->IsUpdateMode()
@@ -3600,21 +3583,6 @@ void SalInstanceItemView::do_select(const 
weld::TreeIter& rIter)
     m_pTreeListBox->MakeVisible(rVclIter.iter);
 }
 
-void SalInstanceItemView::do_unselect(int pos)
-{
-    assert(m_pTreeListBox->IsUpdateMode()
-           && "don't select when frozen, select after thaw. Note selection 
doesn't survive a "
-              "freeze");
-    if (pos == -1)
-    {
-        do_select_all();
-        return;
-    }
-
-    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry(nullptr, pos);
-    m_pTreeListBox->Select(pEntry, false);
-}
-
 void SalInstanceItemView::do_unselect(const weld::TreeIter& rIter)
 {
     assert(m_pTreeListBox->IsUpdateMode()
diff --git a/vcl/source/weld/ItemView.cxx b/vcl/source/weld/ItemView.cxx
index bc64a59a2716..9c260b94078a 100644
--- a/vcl/source/weld/ItemView.cxx
+++ b/vcl/source/weld/ItemView.cxx
@@ -13,9 +13,14 @@ namespace weld
 {
 void ItemView::select(int pos)
 {
-    disable_notify_events();
-    do_select(pos);
-    enable_notify_events();
+    if (pos == -1 || (pos == 0 && n_children() == 0))
+    {
+        unselect_all();
+        return;
+    }
+
+    if (std::unique_ptr<weld::TreeIter> pIter = get_iterator(pos))
+        return select(*pIter);
 }
 
 void ItemView::select(const TreeIter& rIter)
@@ -27,9 +32,14 @@ void ItemView::select(const TreeIter& rIter)
 
 void ItemView::unselect(int pos)
 {
-    disable_notify_events();
-    do_unselect(pos);
-    enable_notify_events();
+    if (pos == -1)
+    {
+        select_all();
+        return;
+    }
+
+    if (std::unique_ptr<weld::TreeIter> pIter = get_iterator(pos))
+        return unselect(*pIter);
 }
 
 void ItemView::unselect(const TreeIter& rIter)
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 853cd80350be..4e27b4d40311 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -15227,23 +15227,6 @@ public:
         return gtk_tree_model_iter_n_children(m_pTreeModel, 
const_cast<GtkTreeIter*>(&rGtkIter.iter));
     }
 
-    virtual void do_select(int pos) override
-    {
-        if (pos == -1 || (pos == 0 && n_children() == 0))
-        {
-            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();
-    }
-
     virtual void do_set_cursor(int pos) override
     {
         disable_notify_events();
@@ -15278,22 +15261,6 @@ public:
         return 
gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(m_pTreeView), 
&iter);
     }
 
-    virtual void do_unselect(int pos) override
-    {
-        if (pos == -1 || (pos == 0 && n_children() == 0))
-        {
-            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();
-    }
-
     virtual std::vector<int> get_selected_rows() const override
     {
         std::vector<int> aRows;
@@ -17184,23 +17151,6 @@ public:
         return nRet;
     }
 
-    virtual void do_select(int pos) override
-    {
-        if (pos == -1 || (pos == 0 && n_children() == 0))
-        {
-            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();
-    }
-
     virtual void do_select(const weld::TreeIter& rIter) override
     {
         disable_notify_events();
@@ -17214,22 +17164,6 @@ public:
         enable_notify_events();
     }
 
-    virtual void do_unselect(int pos) override
-    {
-        if (pos == -1 || (pos == 0 && n_children() == 0))
-        {
-            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();
-    }
-
     virtual void do_unselect(const weld::TreeIter& rIter) override
     {
         disable_notify_events();

Reply via email to