[gtk/wip/otte/listmodels: 2/17] sortlistmodel: Add ::item-type and ::n-items




commit e4f15b76b111b896276abd9dfe44b20fd5242eeb
Author: Benjamin Otte <otte redhat com>
Date:   Sat Jun 11 04:48:45 2022 +0200

    sortlistmodel: Add ::item-type and ::n-items
    
    With tests!

 gtk/gtksortlistmodel.c                   | 40 ++++++++++++++++++++++++++++++++
 testsuite/gtk/sortlistmodel-exhaustive.c | 30 +++++++++++++++++++++++-
 testsuite/gtk/sortlistmodel.c            | 29 +++++++++++++++--------
 3 files changed, 88 insertions(+), 11 deletions(-)
---
diff --git a/gtk/gtksortlistmodel.c b/gtk/gtksortlistmodel.c
index 46155cb60d..59d8385683 100644
--- a/gtk/gtksortlistmodel.c
+++ b/gtk/gtksortlistmodel.c
@@ -79,7 +79,9 @@
 enum {
   PROP_0,
   PROP_INCREMENTAL,
+  PROP_ITEM_TYPE,
   PROP_MODEL,
+  PROP_N_ITEMS,
   PROP_PENDING,
   PROP_SORTER,
   NUM_PROPERTIES
@@ -580,6 +582,8 @@ gtk_sort_list_model_items_changed_cb (GListModel       *model,
     {
       self->n_items = self->n_items - removed + added;
       g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
+      if (removed != added)
+        g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
       return;
     }
 
@@ -620,6 +624,8 @@ gtk_sort_list_model_items_changed_cb (GListModel       *model,
 
   n_items = self->n_items - start - end;
   g_list_model_items_changed (G_LIST_MODEL (self), start, n_items - added + removed, n_items);
+  if (removed != added)
+    g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
 }
 
 static void
@@ -664,10 +670,18 @@ gtk_sort_list_model_get_property (GObject     *object,
       g_value_set_boolean (value, self->incremental);
       break;
 
+    case PROP_ITEM_TYPE:
+      g_value_set_gtype (value, gtk_sort_list_model_get_item_type (G_LIST_MODEL (self)));
+      break;
+
     case PROP_MODEL:
       g_value_set_object (value, self->model);
       break;
 
+    case PROP_N_ITEMS:
+      g_value_set_uint (value, gtk_sort_list_model_get_n_items (G_LIST_MODEL (self)));
+      break;
+
     case PROP_PENDING:
       g_value_set_uint (value, gtk_sort_list_model_get_pending (self));
       break;
@@ -788,6 +802,18 @@ gtk_sort_list_model_class_init (GtkSortListModelClass *class)
                             FALSE,
                             GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
 
+  /**
+   * GtkSortListModel:item-type:
+   *
+   * The type of items. See [func@Gio.ListModel.get_item_type].
+   *
+   * Since: 4.8
+   **/
+  properties[PROP_ITEM_TYPE] =
+    g_param_spec_gtype ("item-type", NULL, NULL,
+                        G_TYPE_OBJECT,
+                        G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
   /**
    * GtkSortListModel:model: (attributes org.gtk.Property.get=gtk_sort_list_model_get_model 
org.gtk.Property.set=gtk_sort_list_model_set_model)
    *
@@ -798,6 +824,18 @@ gtk_sort_list_model_class_init (GtkSortListModelClass *class)
                            G_TYPE_LIST_MODEL,
                            GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
 
+  /**
+   * GtkSortListModel:n-items:
+   *
+   * The number of items. See [func@Gio.ListModel.get_n_items].
+   *
+   * Since: 4.8
+   **/
+  properties[PROP_N_ITEMS] =
+    g_param_spec_uint ("n-items", NULL, NULL,
+                       0, G_MAXUINT, 0,
+                       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
   /**
    * GtkSortListModel:pending: (attributes org.gtk.Property.get=gtk_sort_list_model_get_pending)
    *
@@ -898,6 +936,8 @@ gtk_sort_list_model_set_model (GtkSortListModel *self,
   
   if (removed > 0 || self->n_items > 0)
     g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, self->n_items);
+  if (removed != self->n_items)
+    g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
 
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
 }
diff --git a/testsuite/gtk/sortlistmodel-exhaustive.c b/testsuite/gtk/sortlistmodel-exhaustive.c
index 76aa8bfa2f..0ca2c68f5e 100644
--- a/testsuite/gtk/sortlistmodel-exhaustive.c
+++ b/testsuite/gtk/sortlistmodel-exhaustive.c
@@ -84,9 +84,12 @@ assert_items_changed_correctly (GListModel *model,
 {
   guint i, n_items;
 
+  //sanity check that we got all notifies
+  g_assert_cmpuint (g_list_model_get_n_items (compare), ==, GPOINTER_TO_UINT (g_object_get_data (G_OBJECT 
(compare), "last-notified-n-items")));
+
   //g_print ("%s => %u -%u +%u => %s\n", model_to_string (compare), position, removed, added, 
model_to_string (model));
 
-  g_assert_cmpint (g_list_model_get_n_items (model), ==, g_list_model_get_n_items (compare) - removed + 
added);
+  g_assert_cmpuint (g_list_model_get_n_items (model), ==, g_list_model_get_n_items (compare) - removed + 
added);
   n_items = g_list_model_get_n_items (model);
 
   if (position != 0 || removed != n_items)
@@ -139,6 +142,21 @@ assert_items_changed_correctly (GListModel *model,
     }
 }
 
+static void
+assert_n_items_notified_properly (GListModel *model,
+                                  GParamSpec *pspec,
+                                  GListModel *compare)
+{
+  g_assert_cmpuint (g_list_model_get_n_items (model), !=, GPOINTER_TO_UINT (g_object_get_data (G_OBJECT 
(compare), "last-notified-n-items")));
+
+  /* These should hve been updated in items-changed, which should have been emitted first */
+  g_assert_cmpuint (g_list_model_get_n_items (model), ==, g_list_model_get_n_items (compare));
+
+  g_object_set_data (G_OBJECT (compare),
+                     "last-notified-n-items",
+                     GUINT_TO_POINTER (g_list_model_get_n_items (model)));
+}
+
 static GtkSortListModel *
 sort_list_model_new (GListModel *source,
                      GtkSorter  *sorter)
@@ -162,6 +180,16 @@ sort_list_model_new (GListModel *source,
                          (GClosureNotify) g_object_unref,
                          0);
 
+  g_object_set_data (G_OBJECT (check),
+                     "last-notified-n-items",
+                     GUINT_TO_POINTER (g_list_model_get_n_items (G_LIST_MODEL (check))));
+  g_signal_connect_data (model,
+                         "notify::n-items",
+                         G_CALLBACK (assert_n_items_notified_properly), 
+                         g_object_ref (check),
+                         (GClosureNotify) g_object_unref,
+                         0);
+
   return model;
 }
 
diff --git a/testsuite/gtk/sortlistmodel.c b/testsuite/gtk/sortlistmodel.c
index 515d7a2e10..fa8915df8f 100644
--- a/testsuite/gtk/sortlistmodel.c
+++ b/testsuite/gtk/sortlistmodel.c
@@ -176,6 +176,14 @@ items_changed (GListModel *model,
     }
 }
 
+static void
+notify_n_items (GObject    *object,
+                GParamSpec *pspec,
+                GString    *changes)
+{
+  g_string_append_c (changes, '*');
+}
+
 static void
 free_changes (gpointer data)
 {
@@ -228,6 +236,7 @@ new_model (gpointer model)
   changes = g_string_new ("");
   g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes);
   g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes);
+  g_signal_connect (result, "notify::n-items", G_CALLBACK (notify_n_items), changes);
 
   return result;
 }
@@ -275,11 +284,11 @@ test_set_model (void)
   store = new_store ((guint[]) { 4, 8, 2, 6, 10, 0 });
   gtk_sort_list_model_set_model (sort, G_LIST_MODEL (store));
   assert_model (sort, "4 8 2 6 10");
-  assert_changes (sort, "0+5");
+  assert_changes (sort, "0+5*");
 
   gtk_sort_list_model_set_model (sort, NULL);
   assert_model (sort, "");
-  assert_changes (sort, "0-5");
+  assert_changes (sort, "0-5*");
 
   g_object_unref (sort);
 
@@ -290,11 +299,11 @@ test_set_model (void)
 
   gtk_sort_list_model_set_model (sort, NULL);
   assert_model (sort, "");
-  assert_changes (sort, "0-5");
+  assert_changes (sort, "0-5*");
 
   gtk_sort_list_model_set_model (sort, G_LIST_MODEL (store));
   assert_model (sort, "2 4 6 8 10");
-  assert_changes (sort, "0+5");
+  assert_changes (sort, "0+5*");
 
   g_object_unref (store);
   g_object_unref (sort);
@@ -345,7 +354,7 @@ test_add_items (void)
   assert_changes (sort, "");
   splice (store, 4, 0, (guint[]) { 1,  2 }, 2);
   assert_model (sort, "1 2 49 50 51 99 100");
-  assert_changes (sort, "0+2");
+  assert_changes (sort, "0+2*");
   g_object_unref (store);
   g_object_unref (sort);
 
@@ -356,7 +365,7 @@ test_add_items (void)
   assert_changes (sort, "");
   splice (store, 2, 0, (guint[]) { 49, 50, 51 }, 3);
   assert_model (sort, "1 2 49 50 51 99 100");
-  assert_changes (sort, "2+3");
+  assert_changes (sort, "2+3*");
   g_object_unref (store);
   g_object_unref (sort);
 
@@ -367,7 +376,7 @@ test_add_items (void)
   assert_changes (sort, "");
   splice (store, 1, 0, (guint[]) { 99, 100 }, 2);
   assert_model (sort, "1 2 49 50 51 99 100");
-  assert_changes (sort, "5+2");
+  assert_changes (sort, "5+2*");
   g_object_unref (store);
   g_object_unref (sort);
 }
@@ -385,7 +394,7 @@ test_remove_items (void)
   assert_changes (sort, "");
   splice (store, 4, 2, NULL, 0);
   assert_model (sort, "49 50 51 99 100");
-  assert_changes (sort, "0-2");
+  assert_changes (sort, "0-2*");
   g_object_unref (store);
   g_object_unref (sort);
 
@@ -396,7 +405,7 @@ test_remove_items (void)
   assert_changes (sort, "");
   splice (store, 2, 3, NULL, 0);
   assert_model (sort, "1 2 99 100");
-  assert_changes (sort, "2-3");
+  assert_changes (sort, "2-3*");
   g_object_unref (store);
   g_object_unref (sort);
 
@@ -407,7 +416,7 @@ test_remove_items (void)
   assert_changes (sort, "");
   splice (store, 1, 2, NULL, 0);
   assert_model (sort, "1 2 49 50 51");
-  assert_changes (sort, "5-2");
+  assert_changes (sort, "5-2*");
   g_object_unref (store);
   g_object_unref (sort);
 }


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