include/vcl/weld.hxx          |   12 ++++
 vcl/inc/salvtables.hxx        |    4 +
 vcl/source/app/salvtables.cxx |   39 ++++++++++++---
 vcl/unx/gtk3/gtk3gtkinst.cxx  |  105 ++++++++++++++++++++++++++----------------
 4 files changed, 113 insertions(+), 47 deletions(-)

New commits:
commit 5753386c2353ad4866e7c5dd9e8751ccaa58e93c
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Sat Apr 24 19:15:47 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Thu Apr 29 10:56:41 2021 +0200

    allow push/pop multiple levels of freeze/thaw
    
    so can freely protect a block with freeze/thaw regardless of current
    freeze/thaw state
    
    Change-Id: I1bd60bfc02fe784e36ae371a737f4fdfb15a0888
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114615
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index c055ee0e87b3..9821005fb9e6 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -284,7 +284,19 @@ public:
     virtual bool get_direction() const = 0;
     virtual void set_direction(bool bRTL) = 0;
 
+    /* Increases the freeze count on widget.
+
+       If the freeze count is non-zero, emission of the widget's notifications
+       is stopped. The notifications are queued until the freeze count is
+       decreased to zero. Duplicate notifications may be squashed together.
+    */
     virtual void freeze() = 0;
+
+    /* Reverts the effect of a previous call to freeze.
+
+       The freeze count is decreased on the widget and when it reaches zero,
+       queued notifications are emitted.
+    */
     virtual void thaw() = 0;
 
     /* push/pop busy mouse cursor state
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index f71ce7a055b2..c274b4bd234c 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -185,6 +185,7 @@ private:
     bool m_bKeyEventListener;
     bool m_bMouseEventListener;
     int m_nBlockNotify;
+    int m_nFreezeCount;
 
 protected:
     void ensure_event_listener();
@@ -198,6 +199,9 @@ protected:
     // so use this variant, we will need to filter them later
     void ensure_mouse_listener();
 
+    bool IsFirstFreeze() const { return m_nFreezeCount == 0; }
+    bool IsLastThaw() const { return m_nFreezeCount == 1; }
+
     virtual void HandleEventListener(VclWindowEvent& rEvent);
     virtual bool HandleKeyEventListener(VclWindowEvent& rEvent);
     virtual void HandleMouseEventListener(VclSimpleEvent& rEvent);
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 585fbebda541..f482d4ee7145 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -249,6 +249,7 @@ SalInstanceWidget::SalInstanceWidget(vcl::Window* pWidget, 
SalInstanceBuilder* p
     , m_bKeyEventListener(false)
     , m_bMouseEventListener(false)
     , m_nBlockNotify(0)
+    , m_nFreezeCount(0)
 {
 }
 
@@ -484,9 +485,19 @@ bool SalInstanceWidget::get_direction() const { return 
m_xWidget->IsRTLEnabled()
 
 void SalInstanceWidget::set_direction(bool bRTL) { m_xWidget->EnableRTL(bRTL); 
}
 
-void SalInstanceWidget::freeze() { m_xWidget->SetUpdateMode(false); }
+void SalInstanceWidget::freeze()
+{
+    if (m_nFreezeCount == 0)
+        m_xWidget->SetUpdateMode(false);
+    ++m_nFreezeCount;
+}
 
-void SalInstanceWidget::thaw() { m_xWidget->SetUpdateMode(true); }
+void SalInstanceWidget::thaw()
+{
+    --m_nFreezeCount;
+    if (m_nFreezeCount == 0)
+        m_xWidget->SetUpdateMode(true);
+}
 
 void SalInstanceWidget::set_busy_cursor(bool bBusy)
 {
@@ -3704,15 +3715,23 @@ void SalInstanceTreeView::columns_autosize()
 
 void SalInstanceTreeView::freeze()
 {
+    bool bIsFirstFreeze = IsFirstFreeze();
     SalInstanceWidget::freeze();
-    m_xTreeView->SetUpdateMode(false);
-    m_xTreeView->GetModel()->EnableInvalidate(false);
+    if (bIsFirstFreeze)
+    {
+        m_xTreeView->SetUpdateMode(false);
+        m_xTreeView->GetModel()->EnableInvalidate(false);
+    }
 }
 
 void SalInstanceTreeView::thaw()
 {
-    m_xTreeView->GetModel()->EnableInvalidate(true);
-    m_xTreeView->SetUpdateMode(true);
+    bool bIsLastThaw = IsLastThaw();
+    if (bIsLastThaw)
+    {
+        m_xTreeView->GetModel()->EnableInvalidate(true);
+        m_xTreeView->SetUpdateMode(true);
+    }
     SalInstanceWidget::thaw();
 }
 
@@ -5144,13 +5163,17 @@ SalInstanceIconView::SalInstanceIconView(::IconView* 
pIconView, SalInstanceBuild
 
 void SalInstanceIconView::freeze()
 {
+    bool bIsFirstFreeze = IsFirstFreeze();
     SalInstanceWidget::freeze();
-    m_xIconView->SetUpdateMode(false);
+    if (bIsFirstFreeze)
+        m_xIconView->SetUpdateMode(false);
 }
 
 void SalInstanceIconView::thaw()
 {
-    m_xIconView->SetUpdateMode(true);
+    bool bIsLastThaw = IsLastThaw();
+    if (bIsLastThaw)
+        m_xIconView->SetUpdateMode(true);
     SalInstanceWidget::thaw();
 }
 
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 43189617bf63..af252ea05bfa 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1984,6 +1984,9 @@ protected:
 
     DECL_LINK(async_drag_cancel, void*, void);
 
+    bool IsFirstFreeze() const { return m_nFreezeCount == 0; }
+    bool IsLastThaw() const { return m_nFreezeCount == 1; }
+
     static gboolean signalFocusIn(GtkWidget*, GdkEvent*, gpointer widget)
     {
         GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget);
@@ -2110,6 +2113,7 @@ private:
     bool m_bTakeOwnership;
     bool m_bDraggedOver;
     int m_nWaitCount;
+    int m_nFreezeCount;
     sal_uInt16 m_nLastMouseButton;
     sal_uInt16 m_nLastMouseClicks;
     int m_nPressedButton;
@@ -2482,6 +2486,7 @@ public:
         , m_bTakeOwnership(bTakeOwnership)
         , m_bDraggedOver(false)
         , m_nWaitCount(0)
+        , m_nFreezeCount(0)
         , m_nLastMouseButton(0)
         , m_nLastMouseClicks(0)
         , m_nPressedButton(-1)
@@ -3011,12 +3016,14 @@ public:
 
     virtual void freeze() override
     {
+        ++m_nFreezeCount;
         gtk_widget_freeze_child_notify(m_pWidget);
         g_object_freeze_notify(G_OBJECT(m_pWidget));
     }
 
     virtual void thaw() override
     {
+        --m_nFreezeCount;
         g_object_thaw_notify(G_OBJECT(m_pWidget));
         gtk_widget_thaw_child_notify(m_pWidget);
     }
@@ -12092,20 +12099,24 @@ public:
     virtual void freeze() override
     {
         disable_notify_events();
+        bool bIsFirstFreeze = IsFirstFreeze();
         GtkInstanceContainer::freeze();
-        g_object_ref(m_pTreeModel);
-        gtk_tree_view_set_model(m_pTreeView, nullptr);
-        g_object_freeze_notify(G_OBJECT(m_pTreeModel));
-        if (m_xSorter)
+        if (bIsFirstFreeze)
         {
-            int nSortColumn;
-            GtkSortType eSortType;
-            GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel);
-            gtk_tree_sortable_get_sort_column_id(pSortable, &nSortColumn, 
&eSortType);
-            gtk_tree_sortable_set_sort_column_id(pSortable, 
GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, eSortType);
-
-            m_aSavedSortColumns.push_back(nSortColumn);
-            m_aSavedSortTypes.push_back(eSortType);
+            g_object_ref(m_pTreeModel);
+            gtk_tree_view_set_model(m_pTreeView, nullptr);
+            g_object_freeze_notify(G_OBJECT(m_pTreeModel));
+            if (m_xSorter)
+            {
+                int nSortColumn;
+                GtkSortType eSortType;
+                GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel);
+                gtk_tree_sortable_get_sort_column_id(pSortable, &nSortColumn, 
&eSortType);
+                gtk_tree_sortable_set_sort_column_id(pSortable, 
GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, eSortType);
+
+                m_aSavedSortColumns.push_back(nSortColumn);
+                m_aSavedSortTypes.push_back(eSortType);
+            }
         }
         enable_notify_events();
     }
@@ -12113,16 +12124,19 @@ public:
     virtual void thaw() override
     {
         disable_notify_events();
-        if (m_xSorter)
+        if (IsLastThaw())
         {
-            GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel);
-            gtk_tree_sortable_set_sort_column_id(pSortable, 
m_aSavedSortColumns.back(), m_aSavedSortTypes.back());
-            m_aSavedSortTypes.pop_back();
-            m_aSavedSortColumns.pop_back();
+            if (m_xSorter)
+            {
+                GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel);
+                gtk_tree_sortable_set_sort_column_id(pSortable, 
m_aSavedSortColumns.back(), m_aSavedSortTypes.back());
+                m_aSavedSortTypes.pop_back();
+                m_aSavedSortColumns.pop_back();
+            }
+            g_object_thaw_notify(G_OBJECT(m_pTreeModel));
+            gtk_tree_view_set_model(m_pTreeView, GTK_TREE_MODEL(m_pTreeModel));
+            g_object_unref(m_pTreeModel);
         }
-        g_object_thaw_notify(G_OBJECT(m_pTreeModel));
-        gtk_tree_view_set_model(m_pTreeView, GTK_TREE_MODEL(m_pTreeModel));
-        g_object_unref(m_pTreeModel);
         GtkInstanceContainer::thaw();
         enable_notify_events();
     }
@@ -12742,19 +12756,26 @@ public:
     virtual void freeze() override
     {
         disable_notify_events();
+        bool bIsFirstFreeze = IsFirstFreeze();
         GtkInstanceContainer::freeze();
-        g_object_ref(m_pTreeStore);
-        gtk_icon_view_set_model(m_pIconView, nullptr);
-        g_object_freeze_notify(G_OBJECT(m_pTreeStore));
+        if (bIsFirstFreeze)
+        {
+            g_object_ref(m_pTreeStore);
+            gtk_icon_view_set_model(m_pIconView, nullptr);
+            g_object_freeze_notify(G_OBJECT(m_pTreeStore));
+        }
         enable_notify_events();
     }
 
     virtual void thaw() override
     {
         disable_notify_events();
-        g_object_thaw_notify(G_OBJECT(m_pTreeStore));
-        gtk_icon_view_set_model(m_pIconView, GTK_TREE_MODEL(m_pTreeStore));
-        g_object_unref(m_pTreeStore);
+        if (IsLastThaw())
+        {
+            g_object_thaw_notify(G_OBJECT(m_pTreeStore));
+            gtk_icon_view_set_model(m_pIconView, GTK_TREE_MODEL(m_pTreeStore));
+            g_object_unref(m_pTreeStore);
+        }
         GtkInstanceContainer::thaw();
         enable_notify_events();
     }
@@ -15920,14 +15941,18 @@ public:
     virtual void freeze() override
     {
         disable_notify_events();
+        bool bIsFirstFreeze = IsFirstFreeze();
         GtkInstanceContainer::freeze();
-        g_object_ref(m_pTreeModel);
-        gtk_tree_view_set_model(m_pTreeView, nullptr);
-        g_object_freeze_notify(G_OBJECT(m_pTreeModel));
-        if (m_xSorter)
+        if (bIsFirstFreeze)
         {
-            GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel);
-            gtk_tree_sortable_set_sort_column_id(pSortable, 
GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
+            g_object_ref(m_pTreeModel);
+            gtk_tree_view_set_model(m_pTreeView, nullptr);
+            g_object_freeze_notify(G_OBJECT(m_pTreeModel));
+            if (m_xSorter)
+            {
+                GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel);
+                gtk_tree_sortable_set_sort_column_id(pSortable, 
GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
+            }
         }
         enable_notify_events();
     }
@@ -15935,15 +15960,17 @@ public:
     virtual void thaw() override
     {
         disable_notify_events();
-        if (m_xSorter)
+        if (IsLastThaw())
         {
-            GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel);
-            gtk_tree_sortable_set_sort_column_id(pSortable, m_nTextCol, 
GTK_SORT_ASCENDING);
+            if (m_xSorter)
+            {
+                GtkTreeSortable* pSortable = GTK_TREE_SORTABLE(m_pTreeModel);
+                gtk_tree_sortable_set_sort_column_id(pSortable, m_nTextCol, 
GTK_SORT_ASCENDING);
+            }
+            g_object_thaw_notify(G_OBJECT(m_pTreeModel));
+            gtk_tree_view_set_model(m_pTreeView, m_pTreeModel);
+            g_object_unref(m_pTreeModel);
         }
-        g_object_thaw_notify(G_OBJECT(m_pTreeModel));
-        gtk_tree_view_set_model(m_pTreeView, m_pTreeModel);
-        g_object_unref(m_pTreeModel);
-
         GtkInstanceContainer::thaw();
         enable_notify_events();
     }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to