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();
