[libdazzle/gbsneto/fix-model-filter] list-model-filter: Emit items-changed when removing all items



commit fb6ff5fa5eda9e5cb10c00df24bcef46e9159634
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Sep 11 12:27:13 2018 -0300

    list-model-filter: Emit items-changed when removing all items
    
    DzlListModelFilter has a shortcut for when the child model is removing
    all its children. In those cases, however, it wouldn't emit items-changed,
    making any code that depends on the signal not work on those cases.
    
    Fix that by emitting items-changed on the shortcut code as well.

 src/util/dzl-list-model-filter.c |  6 +++++
 tests/test-model-filter.c        | 56 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)
---
diff --git a/src/util/dzl-list-model-filter.c b/src/util/dzl-list-model-filter.c
index c64e358..44eab9d 100644
--- a/src/util/dzl-list-model-filter.c
+++ b/src/util/dzl-list-model-filter.c
@@ -159,10 +159,16 @@ dzl_list_model_filter_child_model_items_changed (DzlListModelFilter *self,
       /* Small shortcut when all items are removed */
       if (n_removed == (guint)g_sequence_get_length (priv->child_seq))
         {
+          guint n_filter_removed = g_sequence_get_length (priv->filter_seq);
+
           g_sequence_remove_range (g_sequence_get_begin_iter (priv->child_seq),
                                    g_sequence_get_end_iter (priv->child_seq));
           g_assert (g_sequence_is_empty (priv->child_seq));
           g_assert (g_sequence_is_empty (priv->filter_seq));
+
+          if (unblocked)
+            g_list_model_items_changed (G_LIST_MODEL (self), 0, n_filter_removed, 0);
+
           goto add_new_items;
         }
 
diff --git a/tests/test-model-filter.c b/tests/test-model-filter.c
index 6840e72..77b7a9e 100644
--- a/tests/test-model-filter.c
+++ b/tests/test-model-filter.c
@@ -194,6 +194,61 @@ test_items_changed (void)
   g_clear_object (&filter);
 }
 
+
+static guint items_to_remove = 0;
+static gboolean items_changed_emitted = FALSE;
+
+static void
+filter_items_removed_cb (DzlListModelFilter *filter,
+                         guint               position,
+                         guint               n_removed,
+                         guint               n_added,
+                         GListModel         *model)
+{
+  items_changed_emitted = TRUE;
+
+  g_assert_cmpint (n_removed, ==, items_to_remove);
+}
+
+static void
+test_remove_all (void)
+{
+  DzlListModelFilter *filter;
+  GListStore *model;
+  guint i;
+
+  model = g_list_store_new (TEST_TYPE_ITEM);
+  g_assert (model);
+
+  filter = dzl_list_model_filter_new (G_LIST_MODEL (model));
+  g_assert (filter);
+
+  /* The filter model is not filtered, so it must mirror whatever
+   * the child model does. In this case, test if the position of
+   * items-changed match.
+   */
+  for (i = 0; i < 100; i++)
+    {
+      g_autoptr (TestItem) val = test_item_new (i);
+
+      g_list_store_append (model, val);
+
+      items_to_remove++;
+    }
+
+  g_assert_cmpint (100, ==, g_list_model_get_n_items (G_LIST_MODEL (model)));
+  g_assert_cmpint (100, ==, g_list_model_get_n_items (G_LIST_MODEL (filter)));
+
+  g_signal_connect_after (filter, "items-changed", G_CALLBACK (filter_items_removed_cb), model);
+
+  g_list_store_remove_all (model);
+
+  g_assert_true (items_changed_emitted);
+
+  g_clear_object (&model);
+  g_clear_object (&filter);
+}
+
 gint
 main (gint argc,
       gchar *argv[])
@@ -201,5 +256,6 @@ main (gint argc,
   g_test_init (&argc, &argv, NULL);
   g_test_add_func ("/Dazzle/ListModelFilter/basic", test_basic);
   g_test_add_func ("/Dazzle/ListModelFilter/items-changed", test_items_changed);
+  g_test_add_func ("/Dazzle/ListModelFilter/remove-all", test_remove_all);
   return g_test_run ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]