include/vcl/weld.hxx          |  109 ++++++++++++++++++++++++++++++++++++------
 vcl/inc/salvtables.hxx        |   11 +---
 vcl/source/app/salvtables.cxx |   69 +++-----------------------
 3 files changed, 108 insertions(+), 81 deletions(-)

New commits:
commit f35a453340beec925f2deed97e6273be77af8654
Author:     Michael Weghorn <[email protected]>
AuthorDate: Fri Oct 17 21:49:10 2025 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Mon Oct 20 17:05:40 2025 +0200

    tdf#130857 weld: Move logic for (not) calling signal hdls to base classes
    
    Following previous commit
    
        Change-Id: I93ec71e29804fd601e314e24c96d0f18a7cbb98c
        Author: Michael Weghorn <[email protected]>
        Date:   Fri Oct 17 20:42:30 2025 +0200
    
            tdf#130857 weld: Move signal block counter logic to weld::Widget
    
    , now also move the logic to only conditionally call
    the signal handlers from SalInstanceWidget (and subclasses)
    to weld::Widget (and subclasses), so this can be reused
    for other implementations in the future as well.
    
    Don't add it this logic to all signal_* methods, but
    only those for which the SalInstance* implementations
    were doing this previously, to not change the existing
    behavior.
    
    The only known case where the behavior would slightly
    differ now is SalInstanceCheckButton::ToggleHdl, which
    previously was
    
        IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void)
        {
            if (notify_events_disabled())
                return;
            m_xCheckButton->EnableTriState(false);
            signal_toggled();
        }
    
    and now would still call
    
        m_xCheckButton->EnableTriState(false);
    
    when event notification is disabled.
    However, that should presumably be fine, and making
    it dependent on whether or not signal notification
    is enabled seems a little odd anyway.
    
    The gtk3/gtk4 VCL plugin implement their own logic,
    which remains unchanged for now.
    
    Change-Id: I13bb1d4a2b52b2d4494a85895f2e33b98b2c45c6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192598
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index b636f7dfe4b1..883ff09341dd 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -691,7 +691,12 @@ class VCL_DLLPUBLIC Assistant : virtual public Dialog
     Link<const OUString&, bool> m_aJumpPageHdl;
 
 protected:
-    bool signal_jump_page(const OUString& rIdent) { return 
m_aJumpPageHdl.Call(rIdent); }
+    bool signal_jump_page(const OUString& rIdent)
+    {
+        if (notify_events_disabled())
+            return true;
+        return m_aJumpPageHdl.Call(rIdent);
+    }
 
 public:
     virtual int get_current_page() const = 0;
@@ -999,8 +1004,20 @@ protected:
     std::function<int(const weld::TreeIter&, const weld::TreeIter&)> 
m_aCustomSort;
 
 protected:
-    void signal_selection_changed() { m_aSelectionChangedHdl.Call(*this); }
-    bool signal_row_activated() { return m_aRowActivatedHdl.Call(*this); }
+    void signal_selection_changed()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aSelectionChangedHdl.Call(*this);
+    }
+
+    bool signal_row_activated()
+    {
+        if (notify_events_disabled())
+            return true;
+        return m_aRowActivatedHdl.Call(*this);
+    }
+
     void signal_column_clicked(int nColumn) { 
m_aColumnClickedHdl.Call(nColumn); }
     bool signal_expanding(const TreeIter& rIter)
     {
@@ -1010,8 +1027,19 @@ protected:
     {
         return !m_aCollapsingHdl.IsSet() || m_aCollapsingHdl.Call(rIter);
     }
-    void signal_visible_range_changed() { 
m_aVisibleRangeChangedHdl.Call(*this); }
-    void signal_model_changed() { m_aModelChangedHdl.Call(*this); }
+    void signal_visible_range_changed()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aVisibleRangeChangedHdl.Call(*this);
+    }
+
+    void signal_model_changed()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aModelChangedHdl.Call(*this);
+    }
 
     void signal_toggled(const iter_col& rIterCol) { 
m_aRadioToggleHdl.Call(rIterCol); }
 
@@ -1025,7 +1053,13 @@ protected:
     void signal_popup_menu(const CommandEvent& rCommand) { 
m_aPopupMenuHdl.Call(rCommand); }
 
     Link<const TreeIter&, OUString> m_aQueryTooltipHdl;
-    OUString signal_query_tooltip(const TreeIter& rIter) { return 
m_aQueryTooltipHdl.Call(rIter); }
+
+    OUString signal_query_tooltip(const TreeIter& rIter)
+    {
+        if (notify_events_disabled())
+            return {};
+        return m_aQueryTooltipHdl.Call(rIter);
+    }
 
     Link<render_args, void> m_aRenderHdl;
     void signal_custom_render(vcl::RenderContext& rDevice, const 
tools::Rectangle& rRect,
@@ -1454,10 +1488,24 @@ protected:
     Link<const TreeIter&, OUString> m_aQueryTooltipHdl;
     Link<const encoded_image_query&, bool> m_aGetPropertyTreeElemHdl;
 
-    void signal_selection_changed() { m_aSelectionChangeHdl.Call(*this); }
-    bool signal_item_activated() { return m_aItemActivatedHdl.Call(*this); }
+    void signal_selection_changed()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aSelectionChangeHdl.Call(*this);
+    }
+
+    bool signal_item_activated()
+    {
+        if (notify_events_disabled())
+            return true;
+        return m_aItemActivatedHdl.Call(*this);
+    }
+
     OUString signal_query_tooltip(const TreeIter& rIter) const
     {
+        if (notify_events_disabled())
+            return {};
         return m_aQueryTooltipHdl.Call(rIter);
     }
 
@@ -1600,7 +1648,12 @@ protected:
     Link<Toggleable&, void> m_aToggleHdl;
     TriState m_eSavedValue = TRISTATE_FALSE;
 
-    void signal_toggled() { m_aToggleHdl.Call(*this); }
+    void signal_toggled()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aToggleHdl.Call(*this);
+    }
 
 public:
     virtual void set_active(bool active) = 0;
@@ -1788,7 +1841,13 @@ protected:
     friend class ::LOKTrigger;
 
     void signal_changed() { m_aChangeHdl.Call(*this); }
-    void signal_cursor_position() { m_aCursorPositionHdl.Call(*this); }
+
+    void signal_cursor_position()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aCursorPositionHdl.Call(*this);
+    }
 
 public:
     virtual void set_text(const OUString& rText) = 0;
@@ -2042,8 +2101,19 @@ class VCL_DLLPUBLIC Calendar : virtual public Widget
     Link<Calendar&, void> m_aActivatedHdl;
 
 protected:
-    void signal_selected() { m_aSelectedHdl.Call(*this); }
-    void signal_activated() { m_aActivatedHdl.Call(*this); }
+    void signal_selected()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aSelectedHdl.Call(*this);
+    }
+
+    void signal_activated()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aActivatedHdl.Call(*this);
+    }
 
 public:
     void connect_selected(const Link<Calendar&, void>& rLink) { m_aSelectedHdl 
= rLink; }
@@ -2418,7 +2488,14 @@ protected:
     Link<TextView&, void> m_aCursorPositionHdl;
 
     void signal_changed() { m_aChangeHdl.Call(*this); }
-    void signal_cursor_position() { m_aCursorPositionHdl.Call(*this); }
+
+    void signal_cursor_position()
+    {
+        if (notify_events_disabled())
+            return;
+        m_aCursorPositionHdl.Call(*this);
+    }
+
     void signal_vadjustment_value_changed() { m_aVValueChangeHdl.Call(*this); }
 
 public:
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index f791f09918eb..4d6a2f9f1f2d 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -2225,8 +2225,6 @@ SalInstanceAssistant::~SalInstanceAssistant()
 
 IMPL_LINK_NOARG(SalInstanceAssistant, OnRoadmapItemSelected, LinkParamNone*, 
void)
 {
-    if (notify_events_disabled())
-        return;
     auto nCurItemId = m_xWizard->GetCurrentRoadmapItemID();
     int nPageIndex(find_id(nCurItemId));
     if (!signal_jump_page(get_page_ident(nPageIndex)) && nCurItemId != 
m_xWizard->GetCurLevel())
@@ -3069,12 +3067,7 @@ IMPL_LINK_NOARG(SalInstanceMenuButton, MenuSelectHdl, 
::MenuButton*, void)
     signal_selected(m_xMenuButton->GetCurItemIdent());
 }
 
-IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void)
-{
-    if (notify_events_disabled())
-        return;
-    signal_toggled();
-}
+IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void) { 
signal_toggled(); }
 
 IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void)
 {
@@ -3132,17 +3125,10 @@ SalInstanceRadioButton::~SalInstanceRadioButton()
     m_xRadioButton->SetToggleHdl(Link<::RadioButton&, void>());
 }
 
-IMPL_LINK_NOARG(SalInstanceRadioButton, ToggleHdl, ::RadioButton&, void)
-{
-    if (notify_events_disabled())
-        return;
-    signal_toggled();
-}
+IMPL_LINK_NOARG(SalInstanceRadioButton, ToggleHdl, ::RadioButton&, void) { 
signal_toggled(); }
 
 IMPL_LINK(SalInstanceToggleButton, ToggleListener, VclWindowEvent&, rEvent, 
void)
 {
-    if (notify_events_disabled())
-        return;
     if (rEvent.GetId() == VclEventId::PushbuttonToggle)
         signal_toggled();
 }
@@ -3177,8 +3163,6 @@ SalInstanceCheckButton::~SalInstanceCheckButton()
 
 IMPL_LINK_NOARG(SalInstanceCheckButton, ToggleHdl, CheckBox&, void)
 {
-    if (notify_events_disabled())
-        return;
     m_xCheckButton->EnableTriState(false);
     signal_toggled();
 }
@@ -3268,19 +3252,9 @@ public:
 };
 }
 
-IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
-{
-    if (notify_events_disabled())
-        return;
-    signal_selected();
-}
+IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void) { 
signal_selected(); }
 
-IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void)
-{
-    if (notify_events_disabled())
-        return;
-    signal_activated();
-}
+IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void) { 
signal_activated(); }
 
 SalInstanceImage::SalInstanceImage(FixedImage* pImage, SalInstanceBuilder* 
pBuilder,
                                    bool bTakeOwnership)
@@ -3512,8 +3486,6 @@ IMPL_LINK_NOARG(SalInstanceEntry, ChangeHdl, Edit&, void) 
{ signal_changed(); }
 
 IMPL_LINK(SalInstanceEntry, CursorListener, VclWindowEvent&, rEvent, void)
 {
-    if (notify_events_disabled())
-        return;
     if (rEvent.GetId() == VclEventId::EditSelectionChanged
         || rEvent.GetId() == VclEventId::EditCaretChanged)
         signal_cursor_position();
@@ -5120,7 +5092,7 @@ SalInstanceTreeView::~SalInstanceTreeView()
 
 IMPL_LINK(SalInstanceTreeView, TooltipHdl, SvTreeListEntry*, pEntry, OUString)
 {
-    if (pEntry && !notify_events_disabled())
+    if (pEntry)
         return signal_query_tooltip(SalInstanceTreeIter(pEntry));
 
     return {};
@@ -5194,15 +5166,11 @@ IMPL_LINK(SalInstanceTreeView, CompareHdl, const 
SvSortData&, rSortData, sal_Int
 
 IMPL_LINK_NOARG(SalInstanceTreeView, VisibleRangeChangedHdl, SvTreeListBox*, 
void)
 {
-    if (notify_events_disabled())
-        return;
     signal_visible_range_changed();
 }
 
 IMPL_LINK_NOARG(SalInstanceTreeView, ModelChangedHdl, SvTreeListBox*, void)
 {
-    if (notify_events_disabled())
-        return;
     signal_model_changed();
 }
 
@@ -5250,15 +5218,11 @@ IMPL_LINK(SalInstanceTreeView, ToggleHdl, 
SvLBoxButtonData*, pData, void)
 
 IMPL_LINK_NOARG(SalInstanceTreeView, SelectHdl, SvTreeListBox*, void)
 {
-    if (notify_events_disabled())
-        return;
     signal_selection_changed();
 }
 
 IMPL_LINK_NOARG(SalInstanceTreeView, DeSelectHdl, SvTreeListBox*, void)
 {
-    if (notify_events_disabled())
-        return;
     if (m_xTreeView->GetSelectionMode() == SelectionMode::Single
         && !m_xTreeView->GetHoverSelection())
         return;
@@ -5267,8 +5231,6 @@ IMPL_LINK_NOARG(SalInstanceTreeView, DeSelectHdl, 
SvTreeListBox*, void)
 
 IMPL_LINK_NOARG(SalInstanceTreeView, DoubleClickHdl, SvTreeListBox*, bool)
 {
-    if (notify_events_disabled())
-        return false;
     return !signal_row_activated();
 }
 
@@ -5448,7 +5410,7 @@ void SalInstanceIconView::insert_separator(int pos, const 
OUString* /* pId */)
 
 IMPL_LINK(SalInstanceIconView, TooltipHdl, SvTreeListEntry*, pEntry, OUString)
 {
-    if (pEntry && !notify_events_disabled())
+    if (pEntry)
         return signal_query_tooltip(SalInstanceTreeIter(pEntry));
 
     return {};
@@ -5726,15 +5688,11 @@ SalInstanceIconView::~SalInstanceIconView()
 
 IMPL_LINK_NOARG(SalInstanceIconView, SelectHdl, SvTreeListBox*, void)
 {
-    if (notify_events_disabled())
-        return;
     signal_selection_changed();
 }
 
 IMPL_LINK_NOARG(SalInstanceIconView, DeSelectHdl, SvTreeListBox*, void)
 {
-    if (notify_events_disabled())
-        return;
     if (m_xIconView->GetSelectionMode() == SelectionMode::Single)
         return;
     signal_selection_changed();
@@ -5742,8 +5700,6 @@ IMPL_LINK_NOARG(SalInstanceIconView, DeSelectHdl, 
SvTreeListBox*, void)
 
 IMPL_LINK_NOARG(SalInstanceIconView, DoubleClickHdl, SvTreeListBox*, bool)
 {
-    if (notify_events_disabled())
-        return false;
     return !signal_item_activated();
 }
 
@@ -6138,8 +6094,6 @@ IMPL_LINK_NOARG(SalInstanceTextView, ChangeHdl, Edit&, 
void) { signal_changed();
 
 IMPL_LINK(SalInstanceTextView, CursorListener, VclWindowEvent&, rEvent, void)
 {
-    if (notify_events_disabled())
-        return;
     if (rEvent.GetId() == VclEventId::EditSelectionChanged
         || rEvent.GetId() == VclEventId::EditCaretChanged)
         signal_cursor_position();
commit a049564b4952b6500001717e2c47bb7bda35a63e
Author:     Michael Weghorn <[email protected]>
AuthorDate: Fri Oct 17 20:42:30 2025 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Mon Oct 20 17:05:31 2025 +0200

    tdf#130857 weld: Move signal block counter logic to weld::Widget
    
    Move the existing member and methods for managing
    the counter for disabling signal emission from
    SalInstanceWidget to the weld::Widget base class.
    
    This is currently used to avoid signalling about
    certain weld::Widget changes when they were made
    programmatically and not manually by the user.
    
    For example, when setting the selection for a TextView,
    signals get disabled like this:
    
        void SalInstanceTextView::select_region(int nStartPos, int nEndPos)
        {
            disable_notify_events();
            tools::Long nStart = nStartPos < 0 ? SELECTION_MAX : nStartPos;
            tools::Long nEnd = nEndPos < 0 ? SELECTION_MAX : nEndPos;
            m_xTextView->SetSelection(Selection(nStart, nEnd));
            enable_notify_events();
        }
    
    The corresponding event handler then doesn't call
    weld::TextView::signal_cursor_position which would otherwise
    notify about the cursor change.
    
        IMPL_LINK(SalInstanceTextView, CursorListener, VclWindowEvent&, rEvent, 
void)
        {
            if (notify_events_disabled())
                return;
            if (rEvent.GetId() == VclEventId::EditSelectionChanged
                || rEvent.GetId() == VclEventId::EditCaretChanged)
                signal_cursor_position();
        }
    
    While the methods were public previously, make them
    protected now.
    For SalInstanceTreeView, add public wrappers, so
    SalInstanceEntryTreeView::KeyPressListener can
    continue to call this directly for its tree view.
    
    This commit only moves those methods from SalInstanceWidget
    to the weld::Widget base class. More logic will be moved
    for reuse in other implementations than the vcl one
    in upcoming commits.
    (Currently, GtkInstanceWidget implements its own logic
    and QtInstanceWidget doesn't implement the logic to
    block signals.)
    
    Change-Id: I93ec71e29804fd601e314e24c96d0f18a7cbb98c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192597
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 4a5bc6a32484..b636f7dfe4b1 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -85,6 +85,8 @@ class VCL_DLLPUBLIC Widget
 {
     friend class ::LOKTrigger;
 
+    int m_nBlockNotify = 0;
+
 protected:
     Link<Widget&, void> m_aFocusInHdl;
     Link<Widget&, void> m_aFocusOutHdl;
@@ -97,6 +99,10 @@ protected:
     Link<const MouseEvent&, bool> m_aMouseMotionHdl;
     Link<const MouseEvent&, bool> m_aMouseReleaseHdl;
 
+    void disable_notify_events() { ++m_nBlockNotify; }
+    bool notify_events_disabled() const { return m_nBlockNotify != 0; }
+    void enable_notify_events() { --m_nBlockNotify; }
+
     void signal_focus_in() { m_aFocusInHdl.Call(*this); }
     void signal_focus_out() { m_aFocusOutHdl.Call(*this); }
     bool signal_mnemonic_activate() { return 
m_aMnemonicActivateHdl.Call(*this); }
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index c667cc17b93a..2df36dcc2082 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -202,7 +202,6 @@ private:
     bool m_bEventListener;
     bool m_bKeyEventListener;
     bool m_bMouseEventListener;
-    int m_nBlockNotify;
     int m_nFreezeCount;
 
 protected:
@@ -358,12 +357,6 @@ public:
 
     vcl::Window* getWidget() const;
 
-    void disable_notify_events();
-
-    bool notify_events_disabled() const;
-
-    void enable_notify_events();
-
     virtual void queue_resize() override;
 
     virtual void help_hierarchy_foreach(const std::function<bool(const 
OUString&)>& func) override;
@@ -1861,6 +1854,10 @@ public:
     virtual bool changed_by_hover() const override;
 
     virtual ~SalInstanceTreeView() override;
+
+    // public version of protected weld::Widget methods
+    void disableNotifyEvents() { disable_notify_events(); }
+    void enableNotifyEvents() { enable_notify_events(); }
 };
 
 class SalInstanceExpander : public SalInstanceWidget, public virtual 
weld::Expander
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 9ce9f2f64e8a..f791f09918eb 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -365,7 +365,6 @@ SalInstanceWidget::SalInstanceWidget(vcl::Window* pWidget, 
SalInstanceBuilder* p
     , m_bEventListener(false)
     , m_bKeyEventListener(false)
     , m_bMouseEventListener(false)
-    , m_nBlockNotify(0)
     , m_nFreezeCount(0)
 {
 }
@@ -653,12 +652,6 @@ SalInstanceWidget::~SalInstanceWidget()
 
 vcl::Window* SalInstanceWidget::getWidget() const { return m_xWidget; }
 
-void SalInstanceWidget::disable_notify_events() { ++m_nBlockNotify; }
-
-bool SalInstanceWidget::notify_events_disabled() const { return m_nBlockNotify 
!= 0; }
-
-void SalInstanceWidget::enable_notify_events() { --m_nBlockNotify; }
-
 OUString SalInstanceWidget::strip_mnemonic(const OUString& rLabel) const
 {
     return rLabel.replaceFirst("~", "");
@@ -6882,7 +6875,7 @@ IMPL_LINK(SalInstanceEntryTreeView, KeyPressListener, 
VclWindowEvent&, rEvent, v
     if (!bNavigation)
         return;
 
-    m_pTreeView->disable_notify_events();
+    m_pTreeView->disableNotifyEvents();
     auto& rListBox = m_pTreeView->getTreeView();
     if (!rListBox.FirstSelected())
     {
@@ -6893,7 +6886,7 @@ IMPL_LINK(SalInstanceEntryTreeView, KeyPressListener, 
VclWindowEvent&, rEvent, v
         rListBox.KeyInput(rKeyEvent);
     m_xEntry->set_text(m_xTreeView->get_selected_text());
     m_xEntry->select_region(0, -1);
-    m_pTreeView->enable_notify_events();
+    m_pTreeView->enableNotifyEvents();
     m_bTreeChange = true;
     m_pEntry->fire_signal_changed();
     m_bTreeChange = false;

Reply via email to