From 678eb8ab76bda38829be4de8371ced6f43f781ff Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 14 Jul 2022 16:50:22 -0400 Subject: [PATCH 1/2] maplistmodel: Fix items-changed emission We were modifying the removed value before passing it to the items-changed signal, so we always ended up with removed == 0 in our signal emission, instead of passing the original value on, as we should. Pointed out in !4870 --- gtk/gtkmaplistmodel.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gtk/gtkmaplistmodel.c b/gtk/gtkmaplistmodel.c index 5001367b9f..e1cb0b1553 100644 --- a/gtk/gtkmaplistmodel.c +++ b/gtk/gtkmaplistmodel.c @@ -220,6 +220,7 @@ gtk_map_list_model_items_changed_cb (GListModel *model, { MapNode *node; guint start, end; + guint count; if (self->items == NULL) { @@ -232,21 +233,22 @@ gtk_map_list_model_items_changed_cb (GListModel *model, node = gtk_map_list_model_get_nth (self->items, position, &start); g_assert (start <= position); - while (removed > 0) + count = removed; + while (count > 0) { end = start + node->n_items; - if (start == position && end <= position + removed) + if (start == position && end <= position + count) { MapNode *next = gtk_rb_tree_node_get_next (node); - removed -= node->n_items; + count -= node->n_items; gtk_rb_tree_remove (self->items, node); node = next; } else { - if (end >= position + removed) + if (end >= position + count) { - node->n_items -= removed; + node->n_items -= count; removed = 0; gtk_rb_tree_node_mark_dirty (node); } @@ -255,7 +257,7 @@ gtk_map_list_model_items_changed_cb (GListModel *model, guint overlap = node->n_items - (position - start); node->n_items -= overlap; gtk_rb_tree_node_mark_dirty (node); - removed -= overlap; + count -= overlap; start = position; node = gtk_rb_tree_node_get_next (node); } From fa1daf50a7f7fc6d6253b7f9124aaf4775b2f1a6 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 14 Jul 2022 16:52:30 -0400 Subject: [PATCH 2/2] Add more maplistmodel tests Add some tests for adding and removing items. --- testsuite/gtk/maplistmodel.c | 57 ++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/testsuite/gtk/maplistmodel.c b/testsuite/gtk/maplistmodel.c index 2ee0c4cc64..29fd207cf8 100644 --- a/testsuite/gtk/maplistmodel.c +++ b/testsuite/gtk/maplistmodel.c @@ -57,7 +57,6 @@ new_store (guint start, guint end, guint step); -#if 0 static void splice (GListStore *store, guint pos, @@ -65,9 +64,11 @@ splice (GListStore *store, guint *numbers, guint added) { - GObject *objects[added]; + GObject **objects; guint i; + objects = g_newa (GObject*, added); + for (i = 0; i < added; i++) { /* 0 cannot be differentiated from NULL, so don't use it */ @@ -81,7 +82,6 @@ splice (GListStore *store, for (i = 0; i < added; i++) g_object_unref (objects[i]); } -#endif static void add (GListStore *store, @@ -295,6 +295,54 @@ test_set_map_func (void) g_object_unref (map); } +static void +test_add_items (void) +{ + GtkMapListModel *map; + GListStore *store; + + store = new_store (1, 5, 1); + map = new_model (store); + assert_model (map, "2 4 6 8 10"); + assert_changes (map, ""); + + add (store, 6); + assert_model (map, "2 4 6 8 10 12"); + assert_changes (map, "+5*"); +} + +static void +test_remove_items (void) +{ + GtkMapListModel *map; + GListStore *store; + + store = new_store (1, 5, 1); + map = new_model (store); + assert_model (map, "2 4 6 8 10"); + assert_changes (map, ""); + + g_list_store_remove (store, 2); + assert_model (map, "2 4 8 10"); + assert_changes (map, "-2*"); +} + +static void +test_splice (void) +{ + GtkMapListModel *map; + GListStore *store; + + store = new_store (1, 5, 1); + map = new_model (store); + assert_model (map, "2 4 6 8 10"); + assert_changes (map, ""); + + splice (store, 2, 2, (guint[]){ 4, 3 }, 2); + assert_model (map, "2 4 8 6 10"); + assert_changes (map, "2-2+2"); +} + int main (int argc, char *argv[]) { @@ -308,6 +356,9 @@ main (int argc, char *argv[]) g_test_add_func ("/maplistmodel/create", test_create); g_test_add_func ("/maplistmodel/set-model", test_set_model); g_test_add_func ("/maplistmodel/set-map-func", test_set_map_func); + g_test_add_func ("/maplistmodel/add_items", test_add_items); + g_test_add_func ("/maplistmodel/remove_items", test_remove_items); + g_test_add_func ("/maplistmodel/splice", test_splice); return g_test_run (); }