1 /* Extensive GtkTreeModelFilter tests.
2 * Copyright (C) 2009,2011 Kristian Rietveld <kris@gtk.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "treemodel.h"
23 #include "gtktreemodelrefcount.h"
26 * - Proper coverage checking to see if the unit tests cover
28 * - Check if the iterator stamp is incremented at the correct times.
36 #define LEVEL_LENGTH 5
39 create_tree_store_set_values (GtkTreeStore *store,
46 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
47 path_string = gtk_tree_path_to_string (path);
49 gtk_tree_store_set (store, iter,
54 gtk_tree_path_free (path);
59 create_tree_store_recurse (int depth,
66 for (i = 0; i < LEVEL_LENGTH; i++)
70 gtk_tree_store_insert (store, &iter, parent, i);
71 create_tree_store_set_values (store, &iter, visible);
74 create_tree_store_recurse (depth - 1, store, &iter, visible);
79 create_tree_store (int depth,
84 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
86 create_tree_store_recurse (depth, store, NULL, visible);
100 ROW_HAS_CHILD_TOGGLED,
107 signal_name_to_string (SignalName signal)
112 return "row-inserted";
115 return "row-deleted";
118 return "row-changed";
120 case ROW_HAS_CHILD_TOGGLED:
121 return "row-has-child-toggled";
124 return "rows-reordered";
139 /* For rows-reordered */
147 signal_new (SignalName signal, GtkTreePath *path)
151 s = g_new0 (Signal, 1);
153 s->path = gtk_tree_path_copy (path);
160 signal_new_with_order (SignalName signal, GtkTreePath *path,
161 int *new_order, int len)
163 Signal *s = signal_new (signal, path);
165 s->new_order = new_order;
172 signal_free (Signal *s)
175 gtk_tree_path_free (s->path);
184 GtkTreeModel *client;
185 gulong signal_ids[LAST_SIGNAL];
191 signal_monitor_generic_handler (SignalMonitor *m,
200 if (g_queue_is_empty (m->queue))
204 path_str = gtk_tree_path_to_string (path);
205 g_error ("Signal queue empty, got signal %s path %s\n",
206 signal_name_to_string (signal), path_str);
209 g_assert_not_reached ();
212 if (m->client != model)
214 g_error ("Model mismatch; expected %p, got %p\n",
216 g_assert_not_reached ();
219 s = g_queue_peek_tail (m->queue);
222 /* For debugging: output signals that are coming in. Leaks memory. */
223 g_print ("signal=%s path=%s\n", signal_name_to_string (signal),
224 gtk_tree_path_to_string (path));
227 if (s->signal != signal ||
228 (gtk_tree_path_get_depth (s->path) == 0 &&
229 gtk_tree_path_get_depth (path) != 0) ||
230 (gtk_tree_path_get_depth (s->path) != 0 &&
231 gtk_tree_path_compare (s->path, path) != 0))
233 gchar *path_str, *s_path_str;
235 s_path_str = gtk_tree_path_to_string (s->path);
236 path_str = gtk_tree_path_to_string (path);
238 g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n",
239 signal_name_to_string (s->signal), s_path_str,
240 signal_name_to_string (signal), path_str);
245 g_assert_not_reached ();
248 if (signal == ROWS_REORDERED && s->new_order != NULL)
252 g_assert (new_order != NULL);
254 len = gtk_tree_model_iter_n_children (model, iter);
255 g_assert (s->len == len);
257 for (i = 0; i < len; i++)
258 g_assert (s->new_order[i] == new_order[i]);
261 s = g_queue_pop_tail (m->queue);
267 signal_monitor_row_inserted (GtkTreeModel *model,
272 signal_monitor_generic_handler (data, ROW_INSERTED,
273 model, iter, path, NULL);
277 signal_monitor_row_deleted (GtkTreeModel *model,
281 signal_monitor_generic_handler (data, ROW_DELETED,
282 model, NULL, path, NULL);
286 signal_monitor_row_changed (GtkTreeModel *model,
291 signal_monitor_generic_handler (data, ROW_CHANGED,
292 model, iter, path, NULL);
296 signal_monitor_row_has_child_toggled (GtkTreeModel *model,
301 signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
302 model, iter, path, NULL);
306 signal_monitor_rows_reordered (GtkTreeModel *model,
312 signal_monitor_generic_handler (data, ROWS_REORDERED,
313 model, iter, path, new_order);
316 static SignalMonitor *
317 signal_monitor_new (GtkTreeModel *client)
321 m = g_new0 (SignalMonitor, 1);
322 m->client = g_object_ref (client);
323 m->queue = g_queue_new ();
325 m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
327 G_CALLBACK (signal_monitor_row_inserted),
329 m->signal_ids[ROW_DELETED] = g_signal_connect (client,
331 G_CALLBACK (signal_monitor_row_deleted),
333 m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
335 G_CALLBACK (signal_monitor_row_changed),
337 m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
338 "row-has-child-toggled",
339 G_CALLBACK (signal_monitor_row_has_child_toggled),
341 m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
343 G_CALLBACK (signal_monitor_rows_reordered),
350 signal_monitor_free (SignalMonitor *m)
354 for (i = 0; i < LAST_SIGNAL; i++)
355 g_signal_handler_disconnect (m->client, m->signal_ids[i]);
357 g_object_unref (m->client);
360 g_queue_free (m->queue);
366 signal_monitor_assert_is_empty (SignalMonitor *m)
368 g_assert (g_queue_is_empty (m->queue));
372 signal_monitor_append_signal_path (SignalMonitor *m,
378 s = signal_new (signal, path);
379 g_queue_push_head (m->queue, s);
383 signal_monitor_append_signal_reordered (SignalMonitor *m,
391 s = signal_new_with_order (signal, path, new_order, len);
392 g_queue_push_head (m->queue, s);
396 signal_monitor_append_signal (SignalMonitor *m,
398 const gchar *path_string)
403 path = gtk_tree_path_new_from_string (path_string);
405 s = signal_new (signal, path);
406 g_queue_push_head (m->queue, s);
408 gtk_tree_path_free (path);
417 GtkWidget *tree_view;
420 GtkTreeModelFilter *filter;
422 SignalMonitor *monitor;
424 guint block_signals : 1;
429 filter_test_store_signal (FilterTest *fixture)
431 if (fixture->block_signals)
432 g_signal_stop_emission_by_name (fixture->store, "row-changed");
437 filter_test_setup_generic (FilterTest *fixture,
438 gconstpointer test_data,
443 const GtkTreePath *vroot = test_data;
444 GtkTreeModel *filter;
446 fixture->store = create_tree_store (depth, !empty);
448 g_signal_connect_swapped (fixture->store, "row-changed",
449 G_CALLBACK (filter_test_store_signal), fixture);
451 /* Please forgive me for casting const away. */
452 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
453 (GtkTreePath *)vroot);
454 fixture->filter = GTK_TREE_MODEL_FILTER (filter);
457 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
459 /* We need a tree view that's listening to get ref counting from that
462 fixture->tree_view = gtk_tree_view_new_with_model (filter);
464 fixture->monitor = signal_monitor_new (filter);
468 filter_test_setup_expand_root (FilterTest *fixture)
473 path = gtk_tree_path_new_from_indices (0, -1);
475 for (i = 0; i < LEVEL_LENGTH; i++)
477 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view),
479 gtk_tree_path_next (path);
481 gtk_tree_path_free (path);
485 filter_test_setup (FilterTest *fixture,
486 gconstpointer test_data)
488 filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
492 filter_test_setup_empty (FilterTest *fixture,
493 gconstpointer test_data)
495 filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
499 filter_test_setup_unfiltered (FilterTest *fixture,
500 gconstpointer test_data)
502 filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
506 filter_test_setup_unfiltered_root_expanded (FilterTest *fixture,
507 gconstpointer test_data)
509 filter_test_setup_unfiltered (fixture, test_data);
510 filter_test_setup_expand_root (fixture);
514 filter_test_setup_empty_unfiltered (FilterTest *fixture,
515 gconstpointer test_data)
517 filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
521 filter_test_setup_empty_unfiltered_root_expanded (FilterTest *fixture,
522 gconstpointer test_data)
524 filter_test_setup_empty_unfiltered (fixture, test_data);
525 filter_test_setup_expand_root (fixture);
529 strip_virtual_root (GtkTreePath *path,
530 GtkTreePath *root_path)
532 GtkTreePath *real_path;
537 int depth = gtk_tree_path_get_depth (path);
538 int root_depth = gtk_tree_path_get_depth (root_path);
540 real_path = gtk_tree_path_new ();
542 for (j = 0; j < depth - root_depth; j++)
543 gtk_tree_path_append_index (real_path,
544 gtk_tree_path_get_indices (path)[root_depth + j]);
547 real_path = gtk_tree_path_copy (path);
553 count_visible (FilterTest *fixture,
554 GtkTreePath *store_path)
560 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
563 for (i = 0; i < LEVEL_LENGTH; i++)
567 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
579 filter_test_append_refilter_signals_recurse (FilterTest *fixture,
580 GtkTreePath *store_path,
581 GtkTreePath *filter_path,
583 GtkTreePath *root_path)
586 int rows_deleted = 0;
589 gtk_tree_path_down (store_path);
590 gtk_tree_path_down (filter_path);
592 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
595 for (i = 0; i < LEVEL_LENGTH; i++)
598 GtkTreePath *real_path;
600 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
605 (!gtk_tree_path_is_descendant (store_path, root_path)
606 || !gtk_tree_path_compare (store_path, root_path)))
608 if (!gtk_tree_path_compare (store_path, root_path))
611 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
614 GtkTreePath *store_copy;
615 GtkTreePath *filter_copy;
617 store_copy = gtk_tree_path_copy (store_path);
618 filter_copy = gtk_tree_path_copy (filter_path);
619 filter_test_append_refilter_signals_recurse (fixture,
624 gtk_tree_path_free (store_copy);
625 gtk_tree_path_free (filter_copy);
629 gtk_tree_path_next (store_path);
630 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
633 gtk_tree_path_next (filter_path);
638 real_path = strip_virtual_root (filter_path, root_path);
642 /* This row will be inserted */
643 signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
646 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
649 signal_monitor_append_signal_path (fixture->monitor,
650 ROW_HAS_CHILD_TOGGLED,
655 GtkTreePath *store_copy;
656 GtkTreePath *filter_copy;
658 store_copy = gtk_tree_path_copy (store_path);
659 filter_copy = gtk_tree_path_copy (filter_path);
660 filter_test_append_refilter_signals_recurse (fixture,
665 gtk_tree_path_free (store_copy);
666 gtk_tree_path_free (filter_copy);
670 GtkTreePath *tmp_path;
672 /* If all child rows are invisible, then the last row to
673 * become invisible will emit row-has-child-toggled on the
677 tmp_path = gtk_tree_path_copy (store_path);
678 gtk_tree_path_append_index (tmp_path, 0);
680 if (count_visible (fixture, tmp_path) == 0)
681 signal_monitor_append_signal_path (fixture->monitor,
682 ROW_HAS_CHILD_TOGGLED,
685 gtk_tree_path_free (tmp_path);
689 gtk_tree_path_next (filter_path);
693 /* This row will be deleted */
695 signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
699 gtk_tree_path_free (real_path);
701 gtk_tree_path_next (store_path);
702 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
705 if (rows_deleted == LEVEL_LENGTH
706 && gtk_tree_path_get_depth (filter_path) > 1)
708 GtkTreePath *real_path;
710 gtk_tree_path_up (store_path);
711 gtk_tree_path_up (filter_path);
713 /* A row-has-child-toggled will be emitted on the parent */
716 && gtk_tree_path_is_descendant (store_path, root_path)
717 && gtk_tree_path_compare (store_path, root_path)))
719 real_path = strip_virtual_root (filter_path, root_path);
720 signal_monitor_append_signal_path (fixture->monitor,
721 ROW_HAS_CHILD_TOGGLED,
724 gtk_tree_path_free (real_path);
730 filter_test_append_refilter_signals (FilterTest *fixture,
733 /* A special function that walks the tree store like the
734 * model validation functions below.
737 GtkTreePath *filter_path;
739 path = gtk_tree_path_new ();
740 filter_path = gtk_tree_path_new ();
741 filter_test_append_refilter_signals_recurse (fixture,
746 gtk_tree_path_free (path);
747 gtk_tree_path_free (filter_path);
751 filter_test_append_refilter_signals_with_vroot (FilterTest *fixture,
753 GtkTreePath *root_path)
755 /* A special function that walks the tree store like the
756 * model validation functions below.
759 GtkTreePath *filter_path;
761 path = gtk_tree_path_new ();
762 filter_path = gtk_tree_path_new ();
763 filter_test_append_refilter_signals_recurse (fixture,
768 gtk_tree_path_free (path);
769 gtk_tree_path_free (filter_path);
773 filter_test_enable_filter (FilterTest *fixture)
775 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
776 gtk_tree_model_filter_refilter (fixture->filter);
780 filter_test_block_signals (FilterTest *fixture)
782 fixture->block_signals = TRUE;
786 filter_test_unblock_signals (FilterTest *fixture)
788 fixture->block_signals = FALSE;
792 filter_test_teardown (FilterTest *fixture,
793 gconstpointer test_data)
795 signal_monitor_free (fixture->monitor);
797 gtk_widget_destroy (fixture->tree_view);
799 g_object_unref (fixture->filter);
800 g_object_unref (fixture->store);
804 * Model structure validation
808 check_filter_model_recurse (FilterTest *fixture,
809 GtkTreePath *store_parent_path,
810 GtkTreePath *filter_parent_path)
813 GtkTreeIter store_iter;
814 GtkTreeIter filter_iter;
815 gboolean store_has_next, filter_has_next;
817 gtk_tree_path_down (store_parent_path);
818 gtk_tree_path_down (filter_parent_path);
820 store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
821 &store_iter, store_parent_path);
822 filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
823 &filter_iter, filter_parent_path);
825 for (i = 0; i < LEVEL_LENGTH; i++)
829 g_return_if_fail (store_has_next == TRUE);
831 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
839 gchar *filter_str, *store_str;
841 g_return_if_fail (filter_has_next == TRUE);
844 tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
846 g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
848 /* Verify model content */
849 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
853 gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
858 g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
863 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
866 g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
868 check_filter_model_recurse (fixture,
869 gtk_tree_path_copy (store_parent_path),
873 /* Only when we do not recurse we need to free tmp */
874 gtk_tree_path_free (tmp);
876 gtk_tree_path_next (filter_parent_path);
877 filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
880 gtk_tree_path_next (store_parent_path);
881 store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
884 /* Both models should have no more content! */
885 g_return_if_fail (store_has_next == FALSE);
886 g_return_if_fail (filter_has_next == FALSE);
888 gtk_tree_path_free (store_parent_path);
889 gtk_tree_path_free (filter_parent_path);
893 check_filter_model (FilterTest *fixture)
897 if (fixture->monitor)
898 signal_monitor_assert_is_empty (fixture->monitor);
900 path = gtk_tree_path_new ();
902 check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
906 check_filter_model_with_root (FilterTest *fixture,
909 if (fixture->monitor)
910 signal_monitor_assert_is_empty (fixture->monitor);
912 check_filter_model_recurse (fixture,
913 gtk_tree_path_copy (path),
914 gtk_tree_path_new ());
920 check_level_length (GtkTreeModelFilter *filter,
922 const int expected_length)
928 model_length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
929 g_assert_cmpint (model_length, ==, expected_length);
934 gboolean retrieved_iter = FALSE;
937 retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
939 g_return_if_fail (retrieved_iter);
940 model_length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
941 g_assert_cmpint (model_length, ==, expected_length);
946 set_path_visibility (FilterTest *fixture,
950 GtkTreeIter store_iter;
952 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
954 gtk_tree_store_set (fixture->store, &store_iter,
961 insert_path_with_visibility (FilterTest *fixture,
962 const gchar *path_string,
967 GtkTreeIter parent, iter;
969 path = gtk_tree_path_new_from_string (path_string);
970 position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
971 gtk_tree_path_up (path);
973 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
975 gtk_tree_store_insert (fixture->store, &iter, &parent, position);
976 create_tree_store_set_values (fixture->store, &iter, visible);
978 gtk_tree_path_free (path);
987 verify_test_suite (FilterTest *fixture,
988 gconstpointer user_data)
990 check_filter_model (fixture);
994 verify_test_suite_vroot (FilterTest *fixture,
995 gconstpointer user_data)
997 check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
1002 filled_hide_root_level (FilterTest *fixture,
1003 gconstpointer user_data)
1005 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
1006 set_path_visibility (fixture, "2", FALSE);
1007 check_filter_model (fixture);
1008 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1010 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1011 set_path_visibility (fixture, "0", FALSE);
1012 check_filter_model (fixture);
1013 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1015 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
1016 set_path_visibility (fixture, "4", FALSE);
1017 check_filter_model (fixture);
1018 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
1021 /* Hide remaining */
1022 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1023 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1025 set_path_visibility (fixture, "1", FALSE);
1026 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
1028 set_path_visibility (fixture, "3", FALSE);
1029 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
1031 check_filter_model (fixture);
1034 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1035 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1036 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1037 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1039 set_path_visibility (fixture, "1", TRUE);
1040 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
1042 set_path_visibility (fixture, "3", TRUE);
1043 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
1045 check_filter_model (fixture);
1049 filled_hide_child_levels (FilterTest *fixture,
1050 gconstpointer user_data)
1052 set_path_visibility (fixture, "0:2", FALSE);
1053 check_filter_model (fixture);
1054 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1055 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1057 set_path_visibility (fixture, "0:4", FALSE);
1058 check_filter_model (fixture);
1059 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1060 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1062 set_path_visibility (fixture, "0:4:3", FALSE);
1063 check_filter_model (fixture);
1064 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1065 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1067 set_path_visibility (fixture, "0:4:0", FALSE);
1068 set_path_visibility (fixture, "0:4:1", FALSE);
1069 set_path_visibility (fixture, "0:4:2", FALSE);
1070 set_path_visibility (fixture, "0:4:4", FALSE);
1071 check_filter_model (fixture);
1072 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1073 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1075 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1076 set_path_visibility (fixture, "0:4", TRUE);
1077 check_filter_model (fixture);
1078 check_level_length (fixture->filter, "0:3", 0);
1080 set_path_visibility (fixture, "0:2", TRUE);
1081 check_filter_model (fixture);
1082 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1083 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1084 check_level_length (fixture->filter, "0:4", 0);
1086 /* Once 0:4:0 got inserted, 0:4 became a parent. Because 0:4 is
1087 * not visible, not signals are emitted.
1089 set_path_visibility (fixture, "0:4:2", TRUE);
1090 set_path_visibility (fixture, "0:4:4", TRUE);
1091 signal_monitor_assert_is_empty (fixture->monitor);
1092 check_level_length (fixture->filter, "0:4", 2);
1096 filled_hide_child_levels_root_expanded (FilterTest *fixture,
1097 gconstpointer user_data)
1101 path = gtk_tree_path_new_from_indices (0, -1);
1102 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
1103 gtk_tree_path_free (path);
1105 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1106 set_path_visibility (fixture, "0:2", FALSE);
1107 check_filter_model (fixture);
1108 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1109 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1111 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1112 set_path_visibility (fixture, "0:4", FALSE);
1113 check_filter_model (fixture);
1114 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1115 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1117 set_path_visibility (fixture, "0:4:3", FALSE);
1118 check_filter_model (fixture);
1119 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1120 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1122 set_path_visibility (fixture, "0:4:0", FALSE);
1123 set_path_visibility (fixture, "0:4:1", FALSE);
1124 set_path_visibility (fixture, "0:4:2", FALSE);
1125 set_path_visibility (fixture, "0:4:4", FALSE);
1126 check_filter_model (fixture);
1127 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1128 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1130 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1131 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1132 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1133 set_path_visibility (fixture, "0:4", TRUE);
1134 check_filter_model (fixture);
1135 check_level_length (fixture->filter, "0:3", 0);
1137 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1138 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1139 set_path_visibility (fixture, "0:2", TRUE);
1140 check_filter_model (fixture);
1141 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1142 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1143 check_level_length (fixture->filter, "0:4", 0);
1145 /* has-child-toggled for 0:4 is required. */
1146 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1147 set_path_visibility (fixture, "0:4:2", TRUE);
1148 set_path_visibility (fixture, "0:4:4", TRUE);
1149 signal_monitor_assert_is_empty (fixture->monitor);
1150 check_level_length (fixture->filter, "0:4", 2);
1155 filled_vroot_hide_root_level (FilterTest *fixture,
1156 gconstpointer user_data)
1158 GtkTreePath *path = (GtkTreePath *)user_data;
1160 /* These changes do not affect the filter's root level */
1161 set_path_visibility (fixture, "0", FALSE);
1162 check_filter_model_with_root (fixture, path);
1163 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1164 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1166 set_path_visibility (fixture, "4", FALSE);
1167 check_filter_model_with_root (fixture, path);
1168 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1169 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1171 /* Even though we set the virtual root parent node to FALSE,
1172 * the virtual root contents remain.
1174 set_path_visibility (fixture, "2", FALSE);
1175 check_filter_model_with_root (fixture, path);
1176 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1177 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1180 set_path_visibility (fixture, "1", FALSE);
1181 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1182 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1184 set_path_visibility (fixture, "3", FALSE);
1185 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1186 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1188 check_filter_model_with_root (fixture, path);
1191 set_path_visibility (fixture, "2", TRUE);
1192 check_filter_model_with_root (fixture, path);
1193 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1194 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1196 set_path_visibility (fixture, "1", TRUE);
1197 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1198 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1200 set_path_visibility (fixture, "3", TRUE);
1201 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1202 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1204 check_filter_model_with_root (fixture, path);
1206 /* Now test changes in the virtual root level */
1207 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
1208 set_path_visibility (fixture, "2:2", FALSE);
1209 check_filter_model_with_root (fixture, path);
1210 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1212 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
1213 set_path_visibility (fixture, "2:4", FALSE);
1214 check_filter_model_with_root (fixture, path);
1215 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1217 set_path_visibility (fixture, "1:4", FALSE);
1218 check_filter_model_with_root (fixture, path);
1219 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1221 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
1222 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
1223 set_path_visibility (fixture, "2:4", TRUE);
1224 check_filter_model_with_root (fixture, path);
1225 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1227 set_path_visibility (fixture, "2", FALSE);
1228 check_filter_model_with_root (fixture, path);
1229 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1231 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1232 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1233 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1234 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1235 set_path_visibility (fixture, "2:0", FALSE);
1236 set_path_visibility (fixture, "2:1", FALSE);
1237 set_path_visibility (fixture, "2:2", FALSE);
1238 set_path_visibility (fixture, "2:3", FALSE);
1239 set_path_visibility (fixture, "2:4", FALSE);
1240 check_filter_model_with_root (fixture, path);
1241 check_level_length (fixture->filter, NULL, 0);
1243 set_path_visibility (fixture, "2", TRUE);
1244 check_filter_model_with_root (fixture, path);
1245 check_level_length (fixture->filter, NULL, 0);
1247 set_path_visibility (fixture, "1:4", FALSE);
1248 check_filter_model_with_root (fixture, path);
1249 check_level_length (fixture->filter, NULL, 0);
1251 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1252 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1253 set_path_visibility (fixture, "2:4", TRUE);
1254 check_filter_model_with_root (fixture, path);
1255 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
1257 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1258 set_path_visibility (fixture, "2:4", FALSE);
1259 check_filter_model_with_root (fixture, path);
1260 check_level_length (fixture->filter, NULL, 0);
1262 set_path_visibility (fixture, "2", FALSE);
1263 check_filter_model_with_root (fixture, path);
1264 check_level_length (fixture->filter, NULL, 0);
1266 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1267 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1268 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1269 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1270 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
1271 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1272 set_path_visibility (fixture, "2:0", TRUE);
1273 set_path_visibility (fixture, "2:1", TRUE);
1274 set_path_visibility (fixture, "2:2", TRUE);
1275 check_filter_model_with_root (fixture, path);
1276 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1278 set_path_visibility (fixture, "2", TRUE);
1279 check_filter_model_with_root (fixture, path);
1280 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1284 filled_vroot_hide_child_levels (FilterTest *fixture,
1285 gconstpointer user_data)
1287 GtkTreePath *path = (GtkTreePath *)user_data;
1289 set_path_visibility (fixture, "2:0:2", FALSE);
1290 check_filter_model_with_root (fixture, path);
1291 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1292 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1294 set_path_visibility (fixture, "2:0:4", FALSE);
1295 check_filter_model_with_root (fixture, path);
1296 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1297 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1299 set_path_visibility (fixture, "2:0:4:3", FALSE);
1300 check_filter_model_with_root (fixture, path);
1301 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1302 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1304 set_path_visibility (fixture, "2:0:4:0", FALSE);
1305 set_path_visibility (fixture, "2:0:4:1", FALSE);
1306 set_path_visibility (fixture, "2:0:4:2", FALSE);
1307 set_path_visibility (fixture, "2:0:4:4", FALSE);
1308 check_filter_model_with_root (fixture, path);
1309 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1310 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1312 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1313 set_path_visibility (fixture, "2:0:4", TRUE);
1314 check_filter_model_with_root (fixture, path);
1315 check_level_length (fixture->filter, "0:3", 0);
1317 set_path_visibility (fixture, "2:0:2", TRUE);
1318 check_filter_model_with_root (fixture, path);
1319 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1320 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1321 check_level_length (fixture->filter, "0:4", 0);
1323 /* Once 0:4:0 got inserted, 0:4 became a parent */
1324 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1325 set_path_visibility (fixture, "2:0:4:2", TRUE);
1326 set_path_visibility (fixture, "2:0:4:4", TRUE);
1327 check_level_length (fixture->filter, "0:4", 2);
1331 filled_vroot_hide_child_levels_root_expanded (FilterTest *fixture,
1332 gconstpointer user_data)
1334 GtkTreePath *path = (GtkTreePath *)user_data;
1335 GtkTreePath *tmp_path;
1337 tmp_path = gtk_tree_path_new_from_indices (0, -1);
1338 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), tmp_path, FALSE);
1339 gtk_tree_path_free (tmp_path);
1341 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1342 set_path_visibility (fixture, "2:0:2", FALSE);
1343 check_filter_model_with_root (fixture, path);
1344 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1345 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1347 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1348 set_path_visibility (fixture, "2:0:4", FALSE);
1349 check_filter_model_with_root (fixture, path);
1350 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1351 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1353 set_path_visibility (fixture, "2:0:4:3", FALSE);
1354 check_filter_model_with_root (fixture, path);
1355 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1356 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1358 set_path_visibility (fixture, "2:0:4:0", FALSE);
1359 set_path_visibility (fixture, "2:0:4:1", FALSE);
1360 set_path_visibility (fixture, "2:0:4:2", FALSE);
1361 set_path_visibility (fixture, "2:0:4:4", FALSE);
1362 check_filter_model_with_root (fixture, path);
1363 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1364 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1366 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1367 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1368 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1369 set_path_visibility (fixture, "2:0:4", TRUE);
1370 check_filter_model_with_root (fixture, path);
1371 check_level_length (fixture->filter, "0:3", 0);
1373 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1374 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1375 set_path_visibility (fixture, "2:0:2", TRUE);
1376 check_filter_model_with_root (fixture, path);
1377 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1378 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1379 check_level_length (fixture->filter, "0:4", 0);
1381 /* Once 0:4:0 got inserted, 0:4 became a parent */
1382 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1383 set_path_visibility (fixture, "2:0:4:2", TRUE);
1384 set_path_visibility (fixture, "2:0:4:4", TRUE);
1385 check_level_length (fixture->filter, "0:4", 2);
1389 empty_show_nodes (FilterTest *fixture,
1390 gconstpointer user_data)
1392 check_filter_model (fixture);
1393 check_level_length (fixture->filter, NULL, 0);
1395 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1396 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1397 set_path_visibility (fixture, "3", TRUE);
1398 check_filter_model (fixture);
1399 check_level_length (fixture->filter, NULL, 1);
1400 check_level_length (fixture->filter, "0", 0);
1402 set_path_visibility (fixture, "3:2:2", TRUE);
1403 check_filter_model (fixture);
1404 check_level_length (fixture->filter, NULL, 1);
1405 check_level_length (fixture->filter, "0", 0);
1407 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1408 set_path_visibility (fixture, "3:2", TRUE);
1409 check_filter_model (fixture);
1410 check_level_length (fixture->filter, NULL, 1);
1411 check_level_length (fixture->filter, "0", 1);
1412 check_level_length (fixture->filter, "0:0", 1);
1413 check_level_length (fixture->filter, "0:0:0", 0);
1415 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1416 set_path_visibility (fixture, "3", FALSE);
1417 check_filter_model (fixture);
1418 check_level_length (fixture->filter, NULL, 0);
1420 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1421 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1422 set_path_visibility (fixture, "3:2:1", TRUE);
1423 set_path_visibility (fixture, "3", TRUE);
1424 check_filter_model (fixture);
1425 check_level_length (fixture->filter, NULL, 1);
1426 check_level_length (fixture->filter, "0", 1);
1427 check_level_length (fixture->filter, "0:0", 2);
1428 check_level_length (fixture->filter, "0:0:0", 0);
1432 empty_show_multiple_nodes (FilterTest *fixture,
1433 gconstpointer user_data)
1436 GtkTreePath *changed_path;
1438 check_filter_model (fixture);
1439 check_level_length (fixture->filter, NULL, 0);
1441 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1442 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1443 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1444 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1446 /* We simulate a change in visible func condition with this. The
1447 * visibility state of multiple nodes changes at once, we emit row-changed
1448 * for these nodes (and others) after that.
1450 filter_test_block_signals (fixture);
1451 set_path_visibility (fixture, "3", TRUE);
1452 set_path_visibility (fixture, "4", TRUE);
1453 filter_test_unblock_signals (fixture);
1455 changed_path = gtk_tree_path_new ();
1456 gtk_tree_path_append_index (changed_path, 2);
1457 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1458 &iter, changed_path);
1459 /* Invisible node - so no signals expected */
1460 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1461 changed_path, &iter);
1463 gtk_tree_path_next (changed_path);
1464 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1465 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1466 changed_path, &iter);
1468 gtk_tree_path_next (changed_path);
1469 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1470 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1471 changed_path, &iter);
1473 gtk_tree_path_free (changed_path);
1475 check_filter_model (fixture);
1476 check_level_length (fixture->filter, NULL, 2);
1477 check_level_length (fixture->filter, "0", 0);
1479 set_path_visibility (fixture, "3:2:2", TRUE);
1480 check_filter_model (fixture);
1481 check_level_length (fixture->filter, NULL, 2);
1482 check_level_length (fixture->filter, "0", 0);
1484 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1485 set_path_visibility (fixture, "3:2", TRUE);
1486 check_filter_model (fixture);
1487 check_level_length (fixture->filter, NULL, 2);
1488 check_level_length (fixture->filter, "0", 1);
1489 check_level_length (fixture->filter, "0:0", 1);
1490 check_level_length (fixture->filter, "0:0:0", 0);
1492 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1493 set_path_visibility (fixture, "3", FALSE);
1494 check_filter_model (fixture);
1495 check_level_length (fixture->filter, NULL, 1);
1497 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1498 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1499 set_path_visibility (fixture, "3:2:1", TRUE);
1500 set_path_visibility (fixture, "3", TRUE);
1501 check_filter_model (fixture);
1502 check_level_length (fixture->filter, NULL, 2);
1503 check_level_length (fixture->filter, "0", 1);
1504 check_level_length (fixture->filter, "0:0", 2);
1505 check_level_length (fixture->filter, "0:0:0", 0);
1509 empty_vroot_show_nodes (FilterTest *fixture,
1510 gconstpointer user_data)
1512 GtkTreePath *path = (GtkTreePath *)user_data;
1514 check_filter_model_with_root (fixture, path);
1515 check_level_length (fixture->filter, NULL, 0);
1517 set_path_visibility (fixture, "2", TRUE);
1518 check_filter_model_with_root (fixture, path);
1519 check_level_length (fixture->filter, NULL, 0);
1521 set_path_visibility (fixture, "2:2:2", TRUE);
1522 check_filter_model_with_root (fixture, path);
1523 check_level_length (fixture->filter, NULL, 0);
1525 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1526 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1527 set_path_visibility (fixture, "2:2", TRUE);
1528 check_filter_model_with_root (fixture, path);
1529 check_level_length (fixture->filter, NULL, 1);
1530 check_level_length (fixture->filter, "0", 1);
1531 check_level_length (fixture->filter, "0:0", 0);
1533 set_path_visibility (fixture, "3", TRUE);
1534 check_filter_model_with_root (fixture, path);
1535 check_level_length (fixture->filter, NULL, 1);
1537 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1538 set_path_visibility (fixture, "2:2", FALSE);
1539 check_filter_model_with_root (fixture, path);
1540 check_level_length (fixture->filter, NULL, 0);
1542 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1543 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1544 set_path_visibility (fixture, "2:2:1", TRUE);
1545 set_path_visibility (fixture, "2:2", TRUE);
1546 check_filter_model_with_root (fixture, path);
1547 check_level_length (fixture->filter, NULL, 1);
1548 check_level_length (fixture->filter, "0", 2);
1549 check_level_length (fixture->filter, "0:1", 0);
1553 empty_vroot_show_multiple_nodes (FilterTest *fixture,
1554 gconstpointer user_data)
1557 GtkTreePath *changed_path;
1558 GtkTreePath *path = (GtkTreePath *)user_data;
1560 check_filter_model_with_root (fixture, path);
1561 check_level_length (fixture->filter, NULL, 0);
1563 /* We simulate a change in visible func condition with this. The
1564 * visibility state of multiple nodes changes at once, we emit row-changed
1565 * for these nodes (and others) after that.
1567 filter_test_block_signals (fixture);
1568 set_path_visibility (fixture, "2", TRUE);
1569 set_path_visibility (fixture, "3", TRUE);
1570 filter_test_unblock_signals (fixture);
1572 changed_path = gtk_tree_path_new ();
1573 gtk_tree_path_append_index (changed_path, 1);
1574 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1575 &iter, changed_path);
1576 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1577 changed_path, &iter);
1579 gtk_tree_path_next (changed_path);
1580 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1581 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1582 changed_path, &iter);
1584 gtk_tree_path_next (changed_path);
1585 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1586 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1587 changed_path, &iter);
1589 gtk_tree_path_next (changed_path);
1590 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1591 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1592 changed_path, &iter);
1594 gtk_tree_path_free (changed_path);
1596 check_filter_model_with_root (fixture, path);
1597 check_level_length (fixture->filter, NULL, 0);
1599 set_path_visibility (fixture, "2:2:2", TRUE);
1600 check_filter_model_with_root (fixture, path);
1601 check_level_length (fixture->filter, NULL, 0);
1603 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1604 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1605 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1606 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1608 /* Again, we simulate a call to refilter */
1609 filter_test_block_signals (fixture);
1610 set_path_visibility (fixture, "2:2", TRUE);
1611 set_path_visibility (fixture, "2:3", TRUE);
1612 filter_test_unblock_signals (fixture);
1614 changed_path = gtk_tree_path_new ();
1615 gtk_tree_path_append_index (changed_path, 2);
1616 gtk_tree_path_append_index (changed_path, 1);
1617 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1618 &iter, changed_path);
1619 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1620 changed_path, &iter);
1622 gtk_tree_path_next (changed_path);
1623 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1624 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1625 changed_path, &iter);
1627 gtk_tree_path_next (changed_path);
1628 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1629 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1630 changed_path, &iter);
1632 gtk_tree_path_next (changed_path);
1633 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1634 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1635 changed_path, &iter);
1637 gtk_tree_path_free (changed_path);
1639 check_filter_model_with_root (fixture, path);
1640 check_level_length (fixture->filter, NULL, 2);
1641 check_level_length (fixture->filter, "0", 1);
1642 check_level_length (fixture->filter, "0:0", 0);
1644 set_path_visibility (fixture, "3", TRUE);
1645 check_filter_model_with_root (fixture, path);
1646 check_level_length (fixture->filter, NULL, 2);
1648 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1649 set_path_visibility (fixture, "2:2", FALSE);
1650 check_filter_model_with_root (fixture, path);
1651 check_level_length (fixture->filter, NULL, 1);
1653 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1654 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1655 set_path_visibility (fixture, "2:2:1", TRUE);
1656 set_path_visibility (fixture, "2:2", TRUE);
1657 check_filter_model_with_root (fixture, path);
1658 check_level_length (fixture->filter, NULL, 2);
1659 check_level_length (fixture->filter, "0", 2);
1660 check_level_length (fixture->filter, "0:1", 0);
1665 unfiltered_hide_single (FilterTest *fixture,
1666 gconstpointer user_data)
1669 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1670 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1671 set_path_visibility (fixture, "2", FALSE);
1673 signal_monitor_assert_is_empty (fixture->monitor);
1674 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1676 /* The view only shows the root level, so we only expect signals
1677 * for the root level.
1679 filter_test_append_refilter_signals (fixture, 1);
1680 filter_test_enable_filter (fixture);
1682 check_filter_model (fixture);
1683 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1687 unfiltered_hide_single_root_expanded (FilterTest *fixture,
1688 gconstpointer user_data)
1691 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1692 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1693 set_path_visibility (fixture, "2", FALSE);
1695 signal_monitor_assert_is_empty (fixture->monitor);
1696 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1698 filter_test_append_refilter_signals (fixture, 2);
1699 filter_test_enable_filter (fixture);
1701 check_filter_model (fixture);
1702 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1706 unfiltered_hide_single_child (FilterTest *fixture,
1707 gconstpointer user_data)
1710 /* This row is not shown, so its signal is not propagated */
1711 set_path_visibility (fixture, "2:2", FALSE);
1713 signal_monitor_assert_is_empty (fixture->monitor);
1714 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1715 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1717 /* The view only shows the root level, so we only expect signals
1718 * for the root level.
1720 filter_test_append_refilter_signals (fixture, 0);
1721 filter_test_enable_filter (fixture);
1723 check_filter_model (fixture);
1724 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1725 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1729 unfiltered_hide_single_child_root_expanded (FilterTest *fixture,
1730 gconstpointer user_data)
1733 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1734 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1735 set_path_visibility (fixture, "2:2", FALSE);
1737 signal_monitor_assert_is_empty (fixture->monitor);
1738 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1739 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1741 filter_test_append_refilter_signals (fixture, 2);
1742 filter_test_enable_filter (fixture);
1744 check_filter_model (fixture);
1745 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1746 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1750 unfiltered_hide_single_multi_level (FilterTest *fixture,
1751 gconstpointer user_data)
1754 /* This row is not shown, so its signal is not propagated */
1755 set_path_visibility (fixture, "2:2:2", FALSE);
1757 /* This row is not shown, so its signal is not propagated */
1758 set_path_visibility (fixture, "2:2", FALSE);
1760 signal_monitor_assert_is_empty (fixture->monitor);
1761 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1762 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1763 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1765 /* The view only shows the root level, so we only expect signals
1766 * for the root level.
1768 filter_test_append_refilter_signals (fixture, 1);
1769 filter_test_enable_filter (fixture);
1771 check_filter_model (fixture);
1772 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1773 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1775 set_path_visibility (fixture, "2:2", TRUE);
1777 check_filter_model (fixture);
1778 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1779 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1780 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1784 unfiltered_hide_single_multi_level_root_expanded (FilterTest *fixture,
1785 gconstpointer user_data)
1788 /* This row is not shown, so its signal is not propagated */
1789 set_path_visibility (fixture, "2:2:2", FALSE);
1791 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1792 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1793 set_path_visibility (fixture, "2:2", FALSE);
1795 signal_monitor_assert_is_empty (fixture->monitor);
1796 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1797 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1798 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1800 filter_test_append_refilter_signals (fixture, 2);
1801 filter_test_enable_filter (fixture);
1803 check_filter_model (fixture);
1804 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1805 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1807 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1808 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1809 set_path_visibility (fixture, "2:2", TRUE);
1811 check_filter_model (fixture);
1812 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1813 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1814 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1820 unfiltered_vroot_hide_single (FilterTest *fixture,
1821 gconstpointer user_data)
1824 GtkTreePath *path = (GtkTreePath *)user_data;
1826 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1827 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1828 set_path_visibility (fixture, "2:2", FALSE);
1830 signal_monitor_assert_is_empty (fixture->monitor);
1831 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1833 /* The view only shows the root level, so we only expect signals
1834 * for the root level. (Though for the depth argument, we have to
1835 * take the virtual root into account).
1837 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1838 filter_test_enable_filter (fixture);
1840 check_filter_model_with_root (fixture, path);
1841 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1845 unfiltered_vroot_hide_single_child (FilterTest *fixture,
1846 gconstpointer user_data)
1849 GtkTreePath *path = (GtkTreePath *)user_data;
1851 /* Not visible, so no signal will be received. */
1852 set_path_visibility (fixture, "2:2:2", FALSE);
1854 signal_monitor_assert_is_empty (fixture->monitor);
1855 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1856 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1858 /* The view only shows the root level, so we only expect signals
1859 * for the root level. (Though for the depth argument, we have to
1860 * take the virtual root into account).
1862 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1863 filter_test_enable_filter (fixture);
1865 check_filter_model_with_root (fixture, path);
1866 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1867 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1871 unfiltered_vroot_hide_single_child_root_expanded (FilterTest *fixture,
1872 gconstpointer user_data)
1875 GtkTreePath *path = (GtkTreePath *)user_data;
1877 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1878 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1879 set_path_visibility (fixture, "2:2:2", FALSE);
1881 signal_monitor_assert_is_empty (fixture->monitor);
1882 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1883 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1885 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1886 filter_test_enable_filter (fixture);
1888 check_filter_model_with_root (fixture, path);
1889 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1890 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1894 unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
1895 gconstpointer user_data)
1898 GtkTreePath *path = (GtkTreePath *)user_data;
1900 /* This row is not shown, so its signal is not propagated */
1901 set_path_visibility (fixture, "2:2:2:2", FALSE);
1903 /* Not shown, so no signal */
1904 set_path_visibility (fixture, "2:2:2", FALSE);
1906 signal_monitor_assert_is_empty (fixture->monitor);
1907 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1908 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1909 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1911 /* We only expect signals for the root level. The depth is 2
1912 * because we have to take the virtual root into account.
1914 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1915 filter_test_enable_filter (fixture);
1917 check_filter_model_with_root (fixture, path);
1918 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1919 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1921 /* Not shown, so no signal */
1922 set_path_visibility (fixture, "2:2:2", TRUE);
1924 check_filter_model_with_root (fixture, path);
1925 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1926 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1927 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1931 unfiltered_vroot_hide_single_multi_level_root_expanded (FilterTest *fixture,
1932 gconstpointer user_data)
1935 GtkTreePath *path = (GtkTreePath *)user_data;
1937 /* This row is not shown, so its signal is not propagated */
1938 set_path_visibility (fixture, "2:2:2:2", FALSE);
1940 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1941 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1942 set_path_visibility (fixture, "2:2:2", FALSE);
1944 signal_monitor_assert_is_empty (fixture->monitor);
1945 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1946 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1947 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1949 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1950 filter_test_enable_filter (fixture);
1952 check_filter_model_with_root (fixture, path);
1953 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1954 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1956 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1957 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1958 set_path_visibility (fixture, "2:2:2", TRUE);
1960 check_filter_model_with_root (fixture, path);
1961 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1962 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1963 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1967 unfiltered_show_single (FilterTest *fixture,
1968 gconstpointer user_data)
1971 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1972 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1973 set_path_visibility (fixture, "2", TRUE);
1975 signal_monitor_assert_is_empty (fixture->monitor);
1976 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1978 /* We only expect signals for the root level */
1979 filter_test_append_refilter_signals (fixture, 1);
1980 filter_test_enable_filter (fixture);
1982 check_filter_model (fixture);
1983 check_level_length (fixture->filter, NULL, 1);
1987 unfiltered_show_single_child (FilterTest *fixture,
1988 gconstpointer user_data)
1991 set_path_visibility (fixture, "2:2", TRUE);
1993 signal_monitor_assert_is_empty (fixture->monitor);
1994 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1995 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1997 /* We only expect signals for the root level */
1998 filter_test_append_refilter_signals (fixture, 1);
1999 filter_test_enable_filter (fixture);
2001 check_filter_model (fixture);
2002 check_level_length (fixture->filter, NULL, 0);
2004 /* From here we are filtered, "2" in the real model is "0" in the filter
2007 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
2008 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
2009 set_path_visibility (fixture, "2", TRUE);
2010 signal_monitor_assert_is_empty (fixture->monitor);
2011 check_level_length (fixture->filter, NULL, 1);
2012 check_level_length (fixture->filter, "0", 1);
2016 unfiltered_show_single_child_root_expanded (FilterTest *fixture,
2017 gconstpointer user_data)
2020 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
2021 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
2022 set_path_visibility (fixture, "2:2", TRUE);
2024 signal_monitor_assert_is_empty (fixture->monitor);
2025 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
2026 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
2028 filter_test_append_refilter_signals (fixture, 2);
2029 filter_test_enable_filter (fixture);
2031 check_filter_model (fixture);
2032 check_level_length (fixture->filter, NULL, 0);
2034 /* From here we are filtered, "2" in the real model is "0" in the filter
2037 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
2038 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
2039 set_path_visibility (fixture, "2", TRUE);
2040 signal_monitor_assert_is_empty (fixture->monitor);
2041 check_level_length (fixture->filter, NULL, 1);
2042 check_level_length (fixture->filter, "0", 1);
2046 unfiltered_show_single_multi_level (FilterTest *fixture,
2047 gconstpointer user_data)
2050 /* The view is not showing these rows (collapsed state), so it is not
2051 * referenced. The signal should not go through.
2053 set_path_visibility (fixture, "2:2:2", TRUE);
2054 set_path_visibility (fixture, "2:2", TRUE);
2056 signal_monitor_assert_is_empty (fixture->monitor);
2057 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
2058 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
2059 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
2061 /* We only expect signals for the first level */
2062 filter_test_append_refilter_signals (fixture, 1);
2063 filter_test_enable_filter (fixture);
2065 check_filter_model (fixture);
2066 check_level_length (fixture->filter, NULL, 0);
2068 /* From here we are filtered, "2" in the real model is "0" in the filter
2071 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
2072 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
2073 set_path_visibility (fixture, "2", TRUE);
2074 check_filter_model (fixture);
2075 check_level_length (fixture->filter, NULL, 1);
2076 check_level_length (fixture->filter, "0", 1);
2077 check_level_length (fixture->filter, "0:0", 1);
2081 unfiltered_show_single_multi_level_root_expanded (FilterTest *fixture,
2082 gconstpointer user_data)
2085 /* The view is not showing this row (collapsed state), so it is not
2086 * referenced. The signal should not go through.
2088 set_path_visibility (fixture, "2:2:2", TRUE);
2090 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
2091 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
2092 set_path_visibility (fixture, "2:2", TRUE);
2094 signal_monitor_assert_is_empty (fixture->monitor);
2095 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
2096 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
2097 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
2099 filter_test_append_refilter_signals (fixture, 2);
2100 filter_test_enable_filter (fixture);
2102 check_filter_model (fixture);
2103 check_level_length (fixture->filter, NULL, 0);
2105 /* From here we are filtered, "2" in the real model is "0" in the filter
2108 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
2109 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
2110 set_path_visibility (fixture, "2", TRUE);
2111 check_filter_model (fixture);
2112 check_level_length (fixture->filter, NULL, 1);
2113 check_level_length (fixture->filter, "0", 1);
2114 check_level_length (fixture->filter, "0:0", 1);
2118 unfiltered_vroot_show_single (FilterTest *fixture,
2119 gconstpointer user_data)
2122 GtkTreePath *path = (GtkTreePath *)user_data;
2124 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
2125 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
2126 set_path_visibility (fixture, "2:2", TRUE);
2128 signal_monitor_assert_is_empty (fixture->monitor);
2129 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
2131 /* The view only shows the root level, so the filter model only has
2132 * the first two levels cached.
2134 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
2135 filter_test_enable_filter (fixture);
2137 check_filter_model_with_root (fixture, path);
2138 check_level_length (fixture->filter, NULL, 1);
2142 unfiltered_vroot_show_single_child (FilterTest *fixture,
2143 gconstpointer user_data)
2146 GtkTreePath *path = (GtkTreePath *)user_data;
2148 set_path_visibility (fixture, "2:2:2", TRUE);
2150 signal_monitor_assert_is_empty (fixture->monitor);
2151 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
2152 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
2154 /* The view only shows the root level, so the filter model only has
2155 * the first two levels cached.
2157 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
2158 filter_test_enable_filter (fixture);
2160 check_filter_model_with_root (fixture, path);
2161 check_level_length (fixture->filter, NULL, 0);
2163 /* From here we are filtered, "2" in the real model is "0" in the filter
2166 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
2167 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
2168 set_path_visibility (fixture, "2:2", TRUE);
2169 signal_monitor_assert_is_empty (fixture->monitor);
2170 check_level_length (fixture->filter, NULL, 1);
2171 check_level_length (fixture->filter, "0", 1);
2175 unfiltered_vroot_show_single_child_root_expanded (FilterTest *fixture,
2176 gconstpointer user_data)
2179 GtkTreePath *path = (GtkTreePath *)user_data;
2181 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
2182 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
2183 set_path_visibility (fixture, "2:2:2", TRUE);
2185 signal_monitor_assert_is_empty (fixture->monitor);
2186 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
2187 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
2189 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
2190 filter_test_enable_filter (fixture);
2192 check_filter_model_with_root (fixture, path);
2193 check_level_length (fixture->filter, NULL, 0);
2195 /* From here we are filtered, "2" in the real model is "0" in the filter
2198 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
2199 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
2200 set_path_visibility (fixture, "2:2", TRUE);
2201 signal_monitor_assert_is_empty (fixture->monitor);
2202 check_level_length (fixture->filter, NULL, 1);
2203 check_level_length (fixture->filter, "0", 1);
2208 unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
2209 gconstpointer user_data)
2212 GtkTreePath *path = (GtkTreePath *)user_data;
2214 /* The view is not showing this row (collapsed state), so it is not
2215 * referenced. The signal should not go through.
2217 set_path_visibility (fixture, "2:2:2:2", TRUE);
2219 set_path_visibility (fixture, "2:2:2", TRUE);
2221 signal_monitor_assert_is_empty (fixture->monitor);
2222 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
2223 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
2224 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
2226 /* We only expect signals for the root level */
2227 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
2228 filter_test_enable_filter (fixture);
2230 check_filter_model_with_root (fixture, path);
2231 check_level_length (fixture->filter, NULL, 0);
2233 /* From here we are filtered, "2" in the real model is "0" in the filter
2236 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
2237 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
2238 set_path_visibility (fixture, "2:2", TRUE);
2239 check_filter_model_with_root (fixture, path);
2240 check_level_length (fixture->filter, NULL, 1);
2241 check_level_length (fixture->filter, "0", 1);
2242 check_level_length (fixture->filter, "0:0", 1);
2246 unfiltered_vroot_show_single_multi_level_root_expanded (FilterTest *fixture,
2247 gconstpointer user_data)
2250 GtkTreePath *path = (GtkTreePath *)user_data;
2252 /* The view is not showing this row (collapsed state), so it is not
2253 * referenced. The signal should not go through.
2255 set_path_visibility (fixture, "2:2:2:2", TRUE);
2257 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
2258 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
2259 set_path_visibility (fixture, "2:2:2", TRUE);
2261 signal_monitor_assert_is_empty (fixture->monitor);
2262 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
2263 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
2264 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
2266 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
2267 filter_test_enable_filter (fixture);
2269 check_filter_model_with_root (fixture, path);
2270 check_level_length (fixture->filter, NULL, 0);
2272 /* From here we are filtered, "2" in the real model is "0" in the filter
2275 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
2276 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
2277 set_path_visibility (fixture, "2:2", TRUE);
2278 check_filter_model_with_root (fixture, path);
2279 check_level_length (fixture->filter, NULL, 1);
2280 check_level_length (fixture->filter, "0", 1);
2281 check_level_length (fixture->filter, "0:0", 1);
2285 unfiltered_rows_reordered_root_level (FilterTest *fixture,
2286 gconstpointer user_data)
2288 int order0[] = { 1, 2, 3, 4, 0 };
2289 int order1[] = { 0, 2, 1, 3, 4 };
2290 int order2[] = { 4, 0, 1, 2, 3 };
2291 GtkTreeIter iter0, iter1, iter2, iter3, iter4;
2294 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2296 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2298 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2300 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2302 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2305 path = gtk_tree_path_new ();
2306 signal_monitor_append_signal_reordered (fixture->monitor,
2309 gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
2310 signal_monitor_assert_is_empty (fixture->monitor);
2312 signal_monitor_append_signal_reordered (fixture->monitor,
2315 gtk_tree_store_move_after (fixture->store, &iter2, &iter3);
2316 signal_monitor_assert_is_empty (fixture->monitor);
2318 signal_monitor_append_signal_reordered (fixture->monitor,
2321 gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
2322 signal_monitor_assert_is_empty (fixture->monitor);
2324 gtk_tree_path_free (path);
2328 unfiltered_rows_reordered_child_level (FilterTest *fixture,
2329 gconstpointer user_data)
2331 int order0[] = { 1, 2, 3, 4, 0 };
2332 int order1[] = { 0, 2, 1, 3, 4 };
2333 int order2[] = { 4, 0, 1, 2, 3 };
2334 GtkTreeIter iter0, iter1, iter2, iter3, iter4;
2338 path = gtk_tree_path_new_from_indices (0, -1);
2339 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
2341 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2343 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2345 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2347 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2349 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2352 signal_monitor_append_signal_reordered (fixture->monitor,
2355 gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
2356 signal_monitor_assert_is_empty (fixture->monitor);
2358 signal_monitor_append_signal_reordered (fixture->monitor,
2361 gtk_tree_store_move_after (fixture->store, &iter2, &iter3);
2362 signal_monitor_assert_is_empty (fixture->monitor);
2364 signal_monitor_append_signal_reordered (fixture->monitor,
2367 gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
2368 signal_monitor_assert_is_empty (fixture->monitor);
2370 gtk_tree_path_free (path);
2374 filtered_rows_reordered_root_level_first_hidden (FilterTest *fixture,
2375 gconstpointer user_data)
2377 int order0[] = { 1, 2, 3, 0 };
2378 int order1[] = { 0, 2, 1, 3 };
2379 int order2[] = { 3, 0, 1, 2 };
2380 GtkTreeIter iter1, iter2, iter3, iter4;
2383 /* Hide middle path */
2384 signal_monitor_append_signal (fixture->monitor,
2386 set_path_visibility (fixture, "0", FALSE);
2387 signal_monitor_assert_is_empty (fixture->monitor);
2389 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2391 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2393 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2395 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2398 path = gtk_tree_path_new ();
2399 signal_monitor_append_signal_reordered (fixture->monitor,
2402 gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
2403 signal_monitor_assert_is_empty (fixture->monitor);
2405 signal_monitor_append_signal_reordered (fixture->monitor,
2408 gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
2409 signal_monitor_assert_is_empty (fixture->monitor);
2411 signal_monitor_append_signal_reordered (fixture->monitor,
2414 gtk_tree_store_move_before (fixture->store, &iter1, &iter2);
2415 signal_monitor_assert_is_empty (fixture->monitor);
2417 gtk_tree_path_free (path);
2421 filtered_rows_reordered_root_level_middle_hidden (FilterTest *fixture,
2422 gconstpointer user_data)
2424 int order0[] = { 1, 2, 3, 0 };
2425 int order1[] = { 0, 2, 1, 3 };
2426 int order2[] = { 3, 0, 1, 2 };
2427 GtkTreeIter iter0, iter1, iter3, iter4;
2430 /* Hide middle path */
2431 signal_monitor_append_signal (fixture->monitor,
2433 set_path_visibility (fixture, "2", FALSE);
2434 signal_monitor_assert_is_empty (fixture->monitor);
2436 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2438 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2440 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2442 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2445 path = gtk_tree_path_new ();
2446 signal_monitor_append_signal_reordered (fixture->monitor,
2449 gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
2450 signal_monitor_assert_is_empty (fixture->monitor);
2452 signal_monitor_append_signal_reordered (fixture->monitor,
2455 gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
2456 signal_monitor_assert_is_empty (fixture->monitor);
2458 signal_monitor_append_signal_reordered (fixture->monitor,
2461 gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
2462 signal_monitor_assert_is_empty (fixture->monitor);
2464 gtk_tree_path_free (path);
2468 filtered_rows_reordered_child_level_first_hidden (FilterTest *fixture,
2469 gconstpointer user_data)
2471 int order0[] = { 1, 2, 3, 0 };
2472 int order1[] = { 0, 2, 1, 3 };
2473 int order2[] = { 3, 0, 1, 2 };
2474 GtkTreeIter iter1, iter2, iter3, iter4;
2478 path = gtk_tree_path_new_from_indices (0, -1);
2479 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, TRUE);
2481 /* Hide middle path */
2482 signal_monitor_append_signal (fixture->monitor,
2483 ROW_DELETED, "0:0");
2484 set_path_visibility (fixture, "0:0", FALSE);
2485 signal_monitor_assert_is_empty (fixture->monitor);
2487 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2489 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2491 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2493 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2496 signal_monitor_append_signal_reordered (fixture->monitor,
2499 gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
2500 signal_monitor_assert_is_empty (fixture->monitor);
2502 signal_monitor_append_signal_reordered (fixture->monitor,
2505 gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
2506 signal_monitor_assert_is_empty (fixture->monitor);
2508 signal_monitor_append_signal_reordered (fixture->monitor,
2511 gtk_tree_store_move_before (fixture->store, &iter1, &iter2);
2512 signal_monitor_assert_is_empty (fixture->monitor);
2514 gtk_tree_path_free (path);
2518 filtered_rows_reordered_child_level_middle_hidden (FilterTest *fixture,
2519 gconstpointer user_data)
2521 int order0[] = { 1, 2, 3, 0 };
2522 int order1[] = { 0, 2, 1, 3 };
2523 int order2[] = { 3, 0, 1, 2 };
2524 GtkTreeIter iter0, iter1, iter3, iter4;
2528 path = gtk_tree_path_new_from_indices (0, -1);
2529 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
2531 /* Hide middle path */
2532 signal_monitor_append_signal (fixture->monitor,
2533 ROW_DELETED, "0:2");
2534 set_path_visibility (fixture, "0:2", FALSE);
2535 signal_monitor_assert_is_empty (fixture->monitor);
2537 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2539 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2541 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2543 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2546 signal_monitor_append_signal_reordered (fixture->monitor,
2549 gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
2550 signal_monitor_assert_is_empty (fixture->monitor);
2552 signal_monitor_append_signal_reordered (fixture->monitor,
2555 gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
2556 signal_monitor_assert_is_empty (fixture->monitor);
2558 signal_monitor_append_signal_reordered (fixture->monitor,
2561 gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
2562 signal_monitor_assert_is_empty (fixture->monitor);
2564 gtk_tree_path_free (path);
2568 filtered_rows_reordered_child_level_4_hidden (FilterTest *fixture,
2569 gconstpointer user_data)
2571 int order0[] = { 0 };
2572 GtkTreeIter iter1, iter4;
2576 path = gtk_tree_path_new_from_indices (0, -1);
2577 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
2579 /* Hide last 4 paths */
2580 signal_monitor_append_signal (fixture->monitor,
2581 ROW_DELETED, "0:4");
2582 signal_monitor_append_signal (fixture->monitor,
2583 ROW_DELETED, "0:3");
2584 signal_monitor_append_signal (fixture->monitor,
2585 ROW_DELETED, "0:2");
2586 signal_monitor_append_signal (fixture->monitor,
2587 ROW_DELETED, "0:0");
2588 set_path_visibility (fixture, "0:4", FALSE);
2589 set_path_visibility (fixture, "0:3", FALSE);
2590 set_path_visibility (fixture, "0:2", FALSE);
2591 set_path_visibility (fixture, "0:0", FALSE);
2592 signal_monitor_assert_is_empty (fixture->monitor);
2594 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2596 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2599 signal_monitor_append_signal_reordered (fixture->monitor,
2602 gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
2603 signal_monitor_assert_is_empty (fixture->monitor);
2605 gtk_tree_path_free (path);
2609 filtered_rows_reordered_child_level_all_hidden (FilterTest *fixture,
2610 gconstpointer user_data)
2612 GtkTreeIter iter1, iter4;
2616 path = gtk_tree_path_new_from_indices (0, -1);
2617 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
2618 gtk_tree_path_free (path);
2620 /* Hide last 4 paths */
2621 signal_monitor_append_signal (fixture->monitor,
2622 ROW_DELETED, "0:4");
2623 signal_monitor_append_signal (fixture->monitor,
2624 ROW_DELETED, "0:3");
2625 signal_monitor_append_signal (fixture->monitor,
2626 ROW_DELETED, "0:2");
2627 signal_monitor_append_signal (fixture->monitor,
2628 ROW_DELETED, "0:1");
2629 signal_monitor_append_signal (fixture->monitor,
2630 ROW_DELETED, "0:0");
2631 signal_monitor_append_signal (fixture->monitor,
2632 ROW_HAS_CHILD_TOGGLED, "0");
2633 set_path_visibility (fixture, "0:4", FALSE);
2634 set_path_visibility (fixture, "0:3", FALSE);
2635 set_path_visibility (fixture, "0:2", FALSE);
2636 set_path_visibility (fixture, "0:1", FALSE);
2637 set_path_visibility (fixture, "0:0", FALSE);
2638 signal_monitor_assert_is_empty (fixture->monitor);
2640 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2642 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2645 gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
2646 signal_monitor_assert_is_empty (fixture->monitor);
2650 insert_before (void)
2652 GtkTreeStore *store;
2653 GtkTreeModel *filter;
2654 GtkWidget *tree_view;
2655 SignalMonitor *monitor;
2657 GtkTreeIter last_iter;
2660 /* This tests two aspects of the row-inserted handling:
2661 * 1) If the newly inserted node was already handled by building
2662 * the root level, don't handle it a second time.
2663 * 2) Offsets of existing nodes must be updated when a new
2667 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2668 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2669 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
2672 tree_view = gtk_tree_view_new_with_model (filter);
2673 monitor = signal_monitor_new (filter);
2675 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 0);
2678 path = gtk_tree_path_new_from_indices (0, -1);
2679 signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
2680 gtk_tree_path_free (path);
2682 gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
2683 0, "Foo", 1, TRUE, -1);
2685 signal_monitor_assert_is_empty (monitor);
2686 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
2689 path = gtk_tree_path_new_from_indices (1, -1);
2690 signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
2691 gtk_tree_path_free (path);
2693 gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
2694 0, "Foo", 1, TRUE, -1);
2697 signal_monitor_assert_is_empty (monitor);
2698 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
2700 /* Insert on 1 again -- invisible */
2701 gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
2702 0, "Foo", 1, FALSE, -1);
2704 signal_monitor_assert_is_empty (monitor);
2705 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
2707 /* Insert on 1 again -- visible */
2708 path = gtk_tree_path_new_from_indices (1, -1);
2709 signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
2710 gtk_tree_path_free (path);
2712 gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
2713 0, "Foo", 1, TRUE, -1);
2715 signal_monitor_assert_is_empty (monitor);
2716 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 3);
2718 /* Modify the iter that should be at the last position and check the
2721 path = gtk_tree_path_new_from_indices (2, -1);
2722 signal_monitor_append_signal_path (monitor, ROW_CHANGED, path);
2723 gtk_tree_path_free (path);
2725 gtk_tree_store_set (store, &last_iter, 0, "Foo changed", -1);
2727 signal_monitor_assert_is_empty (monitor);
2728 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 3);
2734 GtkTreeStore *store;
2735 GtkTreeModel *filter;
2736 GtkWidget *tree_view;
2737 SignalMonitor *monitor;
2738 GtkTreeIter parent, iter;
2741 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2743 gtk_tree_store_insert_with_values (store, &parent, NULL, 0,
2744 0, "Parent", 1, TRUE, -1);
2747 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2748 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
2751 tree_view = gtk_tree_view_new_with_model (filter);
2752 monitor = signal_monitor_new (filter);
2754 /* Insert child -- invisible */
2755 path = gtk_tree_path_new_from_indices (0, -1);
2756 signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
2757 /* The signal is received twice, once a pass through from GtkTreeStore
2758 * and one generated by GtkTreeModelFilter. Not accurate, but cannot
2761 signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
2762 gtk_tree_path_free (path);
2764 gtk_tree_store_insert_with_values (store, &iter, &parent, 1,
2765 0, "Child", 1, FALSE, -1);
2767 signal_monitor_assert_is_empty (monitor);
2768 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
2771 path = gtk_tree_path_new_from_indices (0, 0, -1);
2772 gtk_tree_path_up (path); /* 0 */
2773 signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
2774 gtk_tree_path_free (path);
2776 gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
2777 0, "Child", 1, TRUE, -1);
2779 signal_monitor_assert_is_empty (monitor);
2780 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
2782 /* Insert child -- invisible */
2783 gtk_tree_store_insert_with_values (store, &iter, &parent, 1,
2784 0, "Child", 1, FALSE, -1);
2786 signal_monitor_assert_is_empty (monitor);
2787 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
2795 GtkTreeIter iter, iter1, iter2, iter3;
2797 GtkTreeModel *filter;
2798 GtkWidget *view G_GNUC_UNUSED;
2800 list = gtk_list_store_new (1, G_TYPE_INT);
2801 gtk_list_store_insert_with_values (list, &iter1, 0, 0, 1, -1);
2802 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
2803 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
2804 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
2805 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
2806 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
2807 gtk_list_store_insert_with_values (list, &iter2, 6, 0, 7, -1);
2808 gtk_list_store_insert_with_values (list, &iter3, 7, 0, 8, -1);
2810 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
2811 view = gtk_tree_view_new_with_model (filter);
2813 gtk_list_store_remove (list, &iter1);
2814 gtk_list_store_remove (list, &iter3);
2815 gtk_list_store_remove (list, &iter2);
2817 gtk_widget_destroy (view);
2818 g_object_unref (filter);
2819 g_object_unref (list);
2823 remove_node_vroot (void)
2825 GtkTreeIter parent, root;
2826 GtkTreeIter iter, iter1, iter2, iter3;
2828 GtkTreeModel *filter;
2830 GtkWidget *view G_GNUC_UNUSED;
2832 tree = gtk_tree_store_new (1, G_TYPE_INT);
2833 gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
2834 gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
2836 gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
2837 gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
2838 gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
2839 gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
2840 gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
2841 gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
2842 gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
2843 gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
2845 path = gtk_tree_path_new_from_indices (0, 0, -1);
2846 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
2847 gtk_tree_path_free (path);
2849 view = gtk_tree_view_new_with_model (filter);
2851 gtk_tree_store_remove (tree, &iter1);
2852 gtk_tree_store_remove (tree, &iter3);
2853 gtk_tree_store_remove (tree, &iter2);
2855 gtk_widget_destroy (view);
2856 g_object_unref (filter);
2857 g_object_unref (tree);
2861 remove_vroot_ancestor (void)
2863 GtkTreeIter parent, root;
2864 GtkTreeIter iter, iter1, iter2, iter3;
2866 GtkTreeModel *filter;
2868 GtkWidget *view G_GNUC_UNUSED;
2870 tree = gtk_tree_store_new (1, G_TYPE_INT);
2871 gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
2872 gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
2874 gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
2875 gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
2876 gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
2877 gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
2878 gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
2879 gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
2880 gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
2881 gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
2883 path = gtk_tree_path_new_from_indices (0, 0, -1);
2884 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
2885 gtk_tree_path_free (path);
2887 view = gtk_tree_view_new_with_model (filter);
2889 gtk_tree_store_remove (tree, &parent);
2891 gtk_widget_destroy (view);
2892 g_object_unref (filter);
2893 g_object_unref (tree);
2897 ref_count_single_level (void)
2899 GtkTreeIter iter[5];
2900 GtkTreeModel *model;
2901 GtkTreeModelRefCount *ref_model;
2902 GtkTreeModel *filter_model;
2903 GtkWidget *tree_view;
2905 model = gtk_tree_model_ref_count_new ();
2906 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
2908 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[0], NULL);
2909 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[1], NULL);
2910 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[2], NULL);
2911 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[3], NULL);
2912 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[4], NULL);
2914 assert_root_level_unreferenced (ref_model);
2916 filter_model = gtk_tree_model_filter_new (model, NULL);
2917 tree_view = gtk_tree_view_new_with_model (filter_model);
2919 assert_node_ref_count (ref_model, &iter[0], 2);
2920 assert_node_ref_count (ref_model, &iter[1], 1);
2921 assert_node_ref_count (ref_model, &iter[2], 1);
2922 assert_node_ref_count (ref_model, &iter[3], 1);
2923 assert_node_ref_count (ref_model, &iter[4], 1);
2925 gtk_widget_destroy (tree_view);
2927 assert_node_ref_count (ref_model, &iter[0], 1);
2928 assert_node_ref_count (ref_model, &iter[1], 0);
2929 assert_node_ref_count (ref_model, &iter[2], 0);
2930 assert_node_ref_count (ref_model, &iter[3], 0);
2931 assert_node_ref_count (ref_model, &iter[4], 0);
2933 g_object_unref (filter_model);
2935 assert_node_ref_count (ref_model, &iter[0], 0);
2937 g_object_unref (ref_model);
2941 ref_count_two_levels (void)
2943 GtkTreeIter parent1, parent2, iter, iter_first;
2944 GtkTreeModel *model;
2945 GtkTreeModelRefCount *ref_model;
2946 GtkTreeModel *filter_model;
2947 GtkWidget *tree_view;
2949 model = gtk_tree_model_ref_count_new ();
2950 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
2952 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
2953 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
2954 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_first, &parent2);
2955 gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
2956 gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
2958 assert_entire_model_unreferenced (ref_model);
2960 filter_model = gtk_tree_model_filter_new (model, NULL);
2961 tree_view = gtk_tree_view_new_with_model (filter_model);
2963 /* This is quite confusing:
2964 * - node 0 has a ref count of 2 because it is referenced as the
2965 * first node in a level and by the tree view.
2966 * - node 1 has a ref count of 2 because it is referenced by its
2967 * child level and by the tree view.
2969 assert_root_level_referenced (ref_model, 2);
2970 assert_node_ref_count (ref_model, &iter_first, 1);
2971 assert_node_ref_count (ref_model, &iter, 0);
2973 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2975 assert_node_ref_count (ref_model, &parent1, 2);
2976 assert_node_ref_count (ref_model, &parent2, 2);
2977 assert_node_ref_count (ref_model, &iter_first, 2);
2978 assert_node_ref_count (ref_model, &iter, 1);
2980 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
2982 /* The child level is not destroyed because its parent is visible */
2983 assert_node_ref_count (ref_model, &parent1, 2);
2984 assert_node_ref_count (ref_model, &parent2, 2);
2985 assert_node_ref_count (ref_model, &iter_first, 1);
2986 assert_node_ref_count (ref_model, &iter, 0);
2988 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2990 assert_node_ref_count (ref_model, &parent1, 2);
2991 assert_node_ref_count (ref_model, &parent2, 2);
2992 assert_node_ref_count (ref_model, &iter_first, 1);
2993 assert_node_ref_count (ref_model, &iter, 0);
2995 gtk_widget_destroy (tree_view);
2997 assert_root_level_referenced (ref_model, 1);
2998 assert_node_ref_count (ref_model, &iter_first, 1);
2999 assert_node_ref_count (ref_model, &iter, 0);
3001 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3003 /* The first two levels should not be cleared, these are used to
3004 * monitor whether or not the parent must become (in)visible.
3006 assert_root_level_referenced (ref_model, 1);
3007 assert_node_ref_count (ref_model, &iter_first, 1);
3008 assert_node_ref_count (ref_model, &iter, 0);
3010 g_object_unref (filter_model);
3011 g_object_unref (ref_model);
3015 ref_count_three_levels (void)
3017 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
3018 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
3019 GtkTreeModel *model;
3020 GtkTreeModelRefCount *ref_model;
3021 GtkTreeModel *filter_model;
3023 GtkWidget *tree_view;
3025 model = gtk_tree_model_ref_count_new ();
3026 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3033 * + iter_parent2_first
3037 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3038 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3039 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
3040 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
3041 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
3042 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
3043 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
3045 assert_entire_model_unreferenced (ref_model);
3047 filter_model = gtk_tree_model_filter_new (model, NULL);
3048 tree_view = gtk_tree_view_new_with_model (filter_model);
3050 /* This is quite confusing:
3051 * - node 0 has a ref count of 2 because it is referenced as the
3052 * first node in a level and by the tree view.
3053 * - node 1 has a ref count of 2 because it is referenced by its
3054 * child level and by the tree view.
3056 assert_root_level_referenced (ref_model, 2);
3057 assert_node_ref_count (ref_model, &parent1, 1);
3058 assert_node_ref_count (ref_model, &parent2, 0);
3059 assert_level_unreferenced (ref_model, &parent1);
3060 assert_level_unreferenced (ref_model, &parent2);
3062 path = gtk_tree_path_new_from_indices (1, -1);
3063 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
3065 assert_node_ref_count (ref_model, &grandparent1, 2);
3066 assert_node_ref_count (ref_model, &grandparent2, 2);
3067 assert_node_ref_count (ref_model, &parent1, 3);
3068 assert_node_ref_count (ref_model, &parent2, 2);
3069 assert_node_ref_count (ref_model, &iter_parent1, 1);
3070 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3071 assert_node_ref_count (ref_model, &iter_parent2, 0);
3073 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
3075 assert_node_ref_count (ref_model, &grandparent1, 2);
3076 assert_node_ref_count (ref_model, &grandparent2, 2);
3077 assert_node_ref_count (ref_model, &parent1, 3);
3078 assert_node_ref_count (ref_model, &parent2, 2);
3079 assert_node_ref_count (ref_model, &iter_parent1, 2);
3080 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
3081 assert_node_ref_count (ref_model, &iter_parent2, 1);
3083 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
3085 assert_node_ref_count (ref_model, &grandparent1, 2);
3086 assert_node_ref_count (ref_model, &grandparent2, 2);
3087 assert_node_ref_count (ref_model, &parent1, 2);
3088 assert_node_ref_count (ref_model, &parent2, 1);
3089 assert_node_ref_count (ref_model, &iter_parent1, 1);
3090 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3091 assert_node_ref_count (ref_model, &iter_parent2, 0);
3093 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3095 assert_node_ref_count (ref_model, &grandparent1, 2);
3096 assert_node_ref_count (ref_model, &grandparent2, 2);
3097 assert_node_ref_count (ref_model, &parent1, 2);
3098 assert_node_ref_count (ref_model, &parent2, 1);
3099 assert_node_ref_count (ref_model, &iter_parent1, 1);
3100 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3101 assert_node_ref_count (ref_model, &iter_parent2, 0);
3103 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
3105 assert_node_ref_count (ref_model, &grandparent1, 2);
3106 assert_node_ref_count (ref_model, &grandparent2, 2);
3107 assert_node_ref_count (ref_model, &parent1, 3);
3108 assert_node_ref_count (ref_model, &parent2, 2);
3109 assert_node_ref_count (ref_model, &iter_parent1, 1);
3110 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3111 assert_node_ref_count (ref_model, &iter_parent2, 0);
3113 gtk_tree_path_append_index (path, 1);
3114 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
3116 assert_node_ref_count (ref_model, &grandparent1, 2);
3117 assert_node_ref_count (ref_model, &grandparent2, 2);
3118 assert_node_ref_count (ref_model, &parent1, 3);
3119 assert_node_ref_count (ref_model, &parent2, 2);
3120 assert_node_ref_count (ref_model, &iter_parent1, 1);
3121 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
3122 assert_node_ref_count (ref_model, &iter_parent2, 1);
3124 gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
3126 assert_node_ref_count (ref_model, &grandparent1, 2);
3127 assert_node_ref_count (ref_model, &grandparent2, 2);
3128 assert_node_ref_count (ref_model, &parent1, 3);
3129 assert_node_ref_count (ref_model, &parent2, 2);
3130 assert_node_ref_count (ref_model, &iter_parent1, 1);
3131 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3132 assert_node_ref_count (ref_model, &iter_parent2, 0);
3134 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3136 assert_node_ref_count (ref_model, &grandparent1, 2);
3137 assert_node_ref_count (ref_model, &grandparent2, 2);
3138 assert_node_ref_count (ref_model, &parent1, 3);
3139 assert_node_ref_count (ref_model, &parent2, 2);
3140 assert_node_ref_count (ref_model, &iter_parent1, 1);
3141 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3142 assert_node_ref_count (ref_model, &iter_parent2, 0);
3144 gtk_tree_path_up (path);
3145 gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
3146 gtk_tree_path_free (path);
3148 assert_node_ref_count (ref_model, &grandparent1, 2);
3149 assert_node_ref_count (ref_model, &grandparent2, 2);
3150 assert_node_ref_count (ref_model, &parent1, 2);
3151 assert_node_ref_count (ref_model, &parent2, 1);
3152 assert_node_ref_count (ref_model, &iter_parent1, 1);
3153 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3154 assert_node_ref_count (ref_model, &iter_parent2, 0);
3156 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3158 assert_node_ref_count (ref_model, &grandparent1, 2);
3159 assert_node_ref_count (ref_model, &grandparent2, 2);
3160 assert_node_ref_count (ref_model, &parent1, 2);
3161 assert_node_ref_count (ref_model, &parent2, 1);
3162 assert_node_ref_count (ref_model, &iter_parent1, 1);
3163 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3164 assert_node_ref_count (ref_model, &iter_parent2, 0);
3166 gtk_widget_destroy (tree_view);
3168 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3170 /* The first two levels should not be cleared, these are used to
3171 * monitor whether or not the parent must become (in)visible.
3173 assert_node_ref_count (ref_model, &grandparent1, 1);
3174 assert_node_ref_count (ref_model, &grandparent2, 1);
3175 assert_node_ref_count (ref_model, &parent1, 1);
3176 assert_node_ref_count (ref_model, &parent2, 0);
3177 assert_node_ref_count (ref_model, &iter_parent1, 0);
3178 assert_node_ref_count (ref_model, &iter_parent2_first, 0);
3179 assert_node_ref_count (ref_model, &iter_parent2, 0);
3181 g_object_unref (filter_model);
3182 g_object_unref (ref_model);
3186 ref_count_delete_row (void)
3188 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
3189 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
3190 GtkTreeModel *model;
3191 GtkTreeModelRefCount *ref_model;
3192 GtkTreeModel *filter_model;
3194 GtkWidget *tree_view;
3196 model = gtk_tree_model_ref_count_new ();
3197 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3204 * + iter_parent2_first
3208 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3209 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3210 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
3211 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
3212 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
3213 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
3214 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
3216 assert_entire_model_unreferenced (ref_model);
3218 filter_model = gtk_tree_model_filter_new (model, NULL);
3219 tree_view = gtk_tree_view_new_with_model (filter_model);
3221 assert_root_level_referenced (ref_model, 2);
3222 assert_node_ref_count (ref_model, &parent1, 1);
3223 assert_node_ref_count (ref_model, &parent2, 0);
3224 assert_level_unreferenced (ref_model, &parent1);
3225 assert_level_unreferenced (ref_model, &parent2);
3227 path = gtk_tree_path_new_from_indices (1, -1);
3228 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
3230 assert_node_ref_count (ref_model, &grandparent1, 2);
3231 assert_node_ref_count (ref_model, &grandparent2, 2);
3232 assert_node_ref_count (ref_model, &parent1, 3);
3233 assert_node_ref_count (ref_model, &parent2, 2);
3234 assert_node_ref_count (ref_model, &iter_parent1, 2);
3235 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
3236 assert_node_ref_count (ref_model, &iter_parent2, 1);
3238 gtk_tree_store_remove (GTK_TREE_STORE (model), &iter_parent2);
3240 assert_node_ref_count (ref_model, &grandparent1, 2);
3241 assert_node_ref_count (ref_model, &grandparent2, 2);
3242 assert_node_ref_count (ref_model, &parent1, 3);
3243 assert_node_ref_count (ref_model, &parent2, 2);
3244 assert_node_ref_count (ref_model, &iter_parent1, 2);
3245 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
3247 gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
3249 assert_node_ref_count (ref_model, &grandparent1, 2);
3250 assert_node_ref_count (ref_model, &grandparent2, 2);
3251 assert_node_ref_count (ref_model, &parent2, 3);
3252 assert_level_referenced (ref_model, 2, &parent2);
3254 gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
3256 assert_node_ref_count (ref_model, &grandparent1, 2);
3258 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3260 assert_node_ref_count (ref_model, &grandparent1, 2);
3262 gtk_widget_destroy (tree_view);
3263 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3265 assert_node_ref_count (ref_model, &grandparent1, 1);
3267 g_object_unref (filter_model);
3269 assert_node_ref_count (ref_model, &grandparent1, 0);
3271 g_object_unref (ref_model);
3275 ref_count_cleanup (void)
3277 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
3278 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
3279 GtkTreeModel *model;
3280 GtkTreeModelRefCount *ref_model;
3281 GtkTreeModel *filter_model;
3282 GtkWidget *tree_view;
3284 model = gtk_tree_model_ref_count_new ();
3285 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3292 * + iter_parent2_first
3296 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3297 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3298 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
3299 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
3300 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
3301 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
3302 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
3304 filter_model = gtk_tree_model_filter_new (model, NULL);
3305 tree_view = gtk_tree_view_new_with_model (filter_model);
3307 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3309 assert_node_ref_count (ref_model, &grandparent1, 2);
3310 assert_node_ref_count (ref_model, &grandparent2, 2);
3311 assert_node_ref_count (ref_model, &parent1, 3);
3312 assert_node_ref_count (ref_model, &parent2, 2);
3313 assert_node_ref_count (ref_model, &iter_parent1, 2);
3314 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
3315 assert_node_ref_count (ref_model, &iter_parent2, 1);
3317 gtk_widget_destroy (tree_view);
3319 assert_node_ref_count (ref_model, &grandparent1, 1);
3320 assert_node_ref_count (ref_model, &grandparent2, 1);
3321 assert_node_ref_count (ref_model, &parent1, 2);
3322 assert_node_ref_count (ref_model, &parent2, 1);
3323 assert_node_ref_count (ref_model, &iter_parent1, 1);
3324 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3325 assert_node_ref_count (ref_model, &iter_parent2, 0);
3327 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3329 /* The first two levels should not be cleared, these are used to
3330 * monitor whether or not the parent must become (in)visible.
3332 assert_node_ref_count (ref_model, &grandparent1, 1);
3333 assert_node_ref_count (ref_model, &grandparent2, 1);
3334 assert_node_ref_count (ref_model, &parent1, 1);
3335 assert_node_ref_count (ref_model, &parent2, 0);
3336 assert_node_ref_count (ref_model, &iter_parent1, 0);
3337 assert_node_ref_count (ref_model, &iter_parent2_first, 0);
3338 assert_node_ref_count (ref_model, &iter_parent2, 0);
3340 g_object_unref (filter_model);
3341 g_object_unref (ref_model);
3345 ref_count_row_ref (void)
3347 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
3348 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
3349 GtkTreeModel *model;
3350 GtkTreeModelRefCount *ref_model;
3351 GtkTreeModel *filter_model;
3352 GtkWidget *tree_view;
3354 GtkTreeRowReference *row_ref;
3356 model = gtk_tree_model_ref_count_new ();
3357 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3368 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3369 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3370 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
3371 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
3372 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
3373 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
3374 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
3376 filter_model = gtk_tree_model_filter_new (model, NULL);
3377 tree_view = gtk_tree_view_new_with_model (filter_model);
3379 path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
3380 row_ref = gtk_tree_row_reference_new (filter_model, path);
3381 gtk_tree_path_free (path);
3383 assert_node_ref_count (ref_model, &grandparent1, 2);
3384 assert_node_ref_count (ref_model, &grandparent2, 3);
3385 assert_node_ref_count (ref_model, &parent1, 1);
3386 assert_node_ref_count (ref_model, &parent2, 2);
3387 assert_node_ref_count (ref_model, &iter_parent1, 0);
3388 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3389 assert_node_ref_count (ref_model, &iter_parent2, 1);
3391 gtk_tree_row_reference_free (row_ref);
3393 assert_node_ref_count (ref_model, &grandparent1, 2);
3394 assert_node_ref_count (ref_model, &grandparent2, 2);
3395 assert_node_ref_count (ref_model, &parent1, 1);
3396 assert_node_ref_count (ref_model, &parent2, 1);
3397 assert_node_ref_count (ref_model, &iter_parent1, 0);
3398 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3399 assert_node_ref_count (ref_model, &iter_parent2, 0);
3401 path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
3402 row_ref = gtk_tree_row_reference_new (filter_model, path);
3403 gtk_tree_path_free (path);
3405 assert_node_ref_count (ref_model, &grandparent1, 2);
3406 assert_node_ref_count (ref_model, &grandparent2, 3);
3407 assert_node_ref_count (ref_model, &parent1, 1);
3408 assert_node_ref_count (ref_model, &parent2, 2);
3409 assert_node_ref_count (ref_model, &iter_parent1, 0);
3410 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3411 assert_node_ref_count (ref_model, &iter_parent2, 1);
3413 gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
3415 assert_node_ref_count (ref_model, &grandparent1, 2);
3416 assert_node_ref_count (ref_model, &grandparent2, 2);
3417 assert_node_ref_count (ref_model, &parent1, 1);
3418 assert_node_ref_count (ref_model, &iter_parent1, 0);
3420 gtk_tree_row_reference_free (row_ref);
3422 assert_node_ref_count (ref_model, &grandparent1, 2);
3423 assert_node_ref_count (ref_model, &grandparent2, 2);
3424 assert_node_ref_count (ref_model, &parent1, 1);
3425 assert_node_ref_count (ref_model, &iter_parent1, 0);
3427 gtk_widget_destroy (tree_view);
3429 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3431 /* The first two levels should not be cleared, these are used to
3432 * monitor whether or not the parent must become (in)visible.
3434 assert_node_ref_count (ref_model, &grandparent1, 1);
3435 assert_node_ref_count (ref_model, &grandparent2, 1);
3436 assert_node_ref_count (ref_model, &parent1, 1);
3438 g_object_unref (filter_model);
3439 g_object_unref (ref_model);
3444 specific_path_dependent_filter_func (GtkTreeModel *model,
3450 path = gtk_tree_model_get_path (model, iter);
3451 if (gtk_tree_path_get_indices (path)[0] < 4)
3458 specific_path_dependent_filter (void)
3464 GtkTreeModel *filter;
3466 list = gtk_list_store_new (1, G_TYPE_INT);
3467 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
3468 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
3469 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
3470 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
3471 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
3472 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
3473 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
3474 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
3476 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
3477 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
3478 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3479 specific_path_dependent_filter_func,
3482 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
3483 GTK_SORT_DESCENDING);
3485 for (i = 0; i < 4; i++)
3487 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
3489 gtk_list_store_remove (list, &iter);
3491 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
3493 gtk_list_store_remove (list, &iter);
3496 g_object_unref (filter);
3497 g_object_unref (sort);
3498 g_object_unref (list);
3503 specific_append_after_collapse_visible_func (GtkTreeModel *model,
3508 gboolean hide_negative_numbers;
3510 gtk_tree_model_get (model, iter, 1, &number, -1);
3511 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
3513 return (number >= 0 || !hide_negative_numbers);
3517 specific_append_after_collapse (void)
3519 /* This test is based on one of the test cases I found in my
3520 * old test cases directory. I unfortunately do not have a record
3521 * from who this test case originated. -Kris.
3525 * - Show tree, expand, collapse.
3530 GtkTreeIter child_iter;
3531 GtkTreeIter child_iter2;
3532 GtkTreePath *append_path;
3533 GtkTreeStore *store;
3534 GtkTreeModel *filter;
3538 GtkWidget *tree_view;
3540 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
3542 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
3543 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
3544 GINT_TO_POINTER (FALSE));
3545 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3546 specific_append_after_collapse_visible_func,
3549 sort = gtk_tree_model_sort_new_with_model (filter);
3551 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3552 tree_view = gtk_tree_view_new_with_model (sort);
3553 gtk_container_add (GTK_CONTAINER (window), tree_view);
3554 gtk_widget_realize (tree_view);
3556 while (gtk_events_pending ())
3557 gtk_main_iteration ();
3559 gtk_tree_store_prepend (store, &iter, NULL);
3560 gtk_tree_store_set (store, &iter,
3561 0, "hallo", 1, 1, -1);
3563 gtk_tree_store_append (store, &child_iter, &iter);
3564 gtk_tree_store_set (store, &child_iter,
3565 0, "toemaar", 1, 1, -1);
3567 gtk_tree_store_append (store, &child_iter2, &child_iter);
3568 gtk_tree_store_set (store, &child_iter2,
3569 0, "very deep", 1, 1, -1);
3571 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
3573 gtk_tree_store_append (store, &child_iter, &iter);
3574 gtk_tree_store_set (store, &child_iter,
3575 0, "sja", 1, 1, -1);
3577 gtk_tree_store_append (store, &child_iter, &iter);
3578 gtk_tree_store_set (store, &child_iter,
3579 0, "some word", 1, -1, -1);
3581 /* Expand and collapse the tree */
3582 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3583 while (gtk_events_pending ())
3584 gtk_main_iteration ();
3586 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
3587 while (gtk_events_pending ())
3588 gtk_main_iteration ();
3590 /* Add another it */
3591 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
3592 GINT_TO_POINTER (TRUE));
3594 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
3596 gtk_tree_store_append (store, &child_iter, &iter);
3597 gtk_tree_store_set (store, &child_iter,
3598 0, "new new new !!", 1, 1, -1);
3600 gtk_tree_path_free (append_path);
3603 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3604 while (gtk_events_pending ())
3605 gtk_main_iteration ();
3610 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
3619 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
3625 /* Do reference the model */
3626 gtk_tree_model_get (model, iter, 0, &item, -1);
3633 specific_sort_filter_remove_node (void)
3635 /* This test is based on one of the test cases I found in my
3636 * old test cases directory. I unfortunately do not have a record
3637 * from who this test case originated. -Kris.
3640 * - Create tree store, sort, filter models. The sort model has
3641 * a default sort func that is enabled, filter model a visible func
3642 * that defaults to returning FALSE.
3643 * - Remove a node from the tree store.
3647 GtkTreeStore *store;
3648 GtkTreeModel *filter;
3652 GtkWidget *tree_view;
3654 store = gtk_tree_store_new (1, G_TYPE_STRING);
3655 gtk_tree_store_append (store, &iter, NULL);
3656 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
3658 gtk_tree_store_append (store, &iter, NULL);
3659 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
3661 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
3662 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
3663 specific_sort_filter_remove_node_compare_func, NULL, NULL);
3665 filter = gtk_tree_model_filter_new (sort, NULL);
3666 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3667 specific_sort_filter_remove_node_visible_func,
3671 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3672 tree_view = gtk_tree_view_new_with_model (filter);
3673 gtk_container_add (GTK_CONTAINER (window), tree_view);
3674 gtk_widget_realize (tree_view);
3676 while (gtk_events_pending ())
3677 gtk_main_iteration ();
3680 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
3681 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
3682 gtk_tree_store_remove (store, &iter);
3684 while (gtk_events_pending ())
3685 gtk_main_iteration ();
3690 specific_sort_filter_remove_root (void)
3692 /* This test is based on one of the test cases I found in my
3693 * old test cases directory. I unfortunately do not have a record
3694 * from who this test case originated. -Kris.
3697 GtkTreeModel *model, *sort, *filter;
3698 GtkTreeIter root, mid, leaf;
3701 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
3702 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
3703 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
3704 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
3706 path = gtk_tree_model_get_path (model, &mid);
3708 sort = gtk_tree_model_sort_new_with_model (model);
3709 filter = gtk_tree_model_filter_new (sort, path);
3711 gtk_tree_path_free (path);
3713 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
3715 g_object_unref (filter);
3716 g_object_unref (sort);
3717 g_object_unref (model);
3722 specific_root_mixed_visibility (void)
3725 GtkTreeModel *filter;
3726 /* A bit nasty, apologies */
3729 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3731 for (i = 0; i < LEVEL_LENGTH; i++)
3735 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
3737 create_tree_store_set_values (fixture.store, &iter, TRUE);
3739 create_tree_store_set_values (fixture.store, &iter, FALSE);
3742 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3743 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3744 fixture.monitor = NULL;
3746 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
3748 /* In order to trigger the potential bug, we should not access
3749 * the filter model here (so don't call the check functions).
3752 /* Change visibility of an odd row to TRUE */
3753 set_path_visibility (&fixture, "3", TRUE);
3754 check_filter_model (&fixture);
3755 check_level_length (fixture.filter, NULL, 4);
3761 specific_has_child_filter_filter_func (GtkTreeModel *model,
3765 return gtk_tree_model_iter_has_child (model, iter);
3769 specific_has_child_filter (void)
3771 GtkTreeModel *filter;
3772 GtkTreeIter iter, root;
3773 FilterTest fixture; /* This is not how it should be done */
3774 GtkWidget *tree_view;
3776 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3777 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3778 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3779 fixture.monitor = signal_monitor_new (filter);
3781 tree_view = gtk_tree_view_new_with_model (filter);
3783 /* We will filter on parent state using a filter function. We will
3784 * manually keep the boolean column in sync, so that we can use
3785 * check_filter_model() to check the consistency of the model.
3787 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3788 * to be able to check the structure here. We keep the calls to
3789 * check_filter_model() commented out until then.
3791 gtk_tree_model_filter_set_visible_func (fixture.filter,
3792 specific_has_child_filter_filter_func,
3795 /* The first node will be initially invisible: no signals */
3796 gtk_tree_store_append (fixture.store, &root, NULL);
3797 create_tree_store_set_values (fixture.store, &root, FALSE);
3799 /* check_filter_model (&fixture); */
3800 check_level_length (fixture.filter, NULL, 0);
3801 signal_monitor_assert_is_empty (fixture.monitor);
3803 /* Insert a child node. This will cause the parent to become visible
3804 * since there is a child now.
3806 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3807 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3808 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3810 gtk_tree_store_append (fixture.store, &iter, &root);
3811 create_tree_store_set_values (fixture.store, &iter, TRUE);
3813 /* Parent must now be visible. Do the level length check first,
3814 * to avoid modifying the child model triggering a row-changed to
3817 check_level_length (fixture.filter, NULL, 1);
3818 check_level_length (fixture.filter, "0", 0);
3819 signal_monitor_assert_is_empty (fixture.monitor);
3821 /* This should propagate row-changed */
3822 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3823 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3825 set_path_visibility (&fixture, "0", TRUE);
3826 /* check_filter_model (&fixture); */
3827 signal_monitor_assert_is_empty (fixture.monitor);
3829 /* New root node, no child, so no signal */
3830 gtk_tree_store_append (fixture.store, &root, NULL);
3831 check_level_length (fixture.filter, NULL, 1);
3832 signal_monitor_assert_is_empty (fixture.monitor);
3834 /* When the child comes in, this node will become visible */
3835 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
3836 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3837 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3838 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
3839 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3841 gtk_tree_store_append (fixture.store, &iter, &root);
3842 check_level_length (fixture.filter, NULL, 2);
3843 check_level_length (fixture.filter, "1", 0);
3845 create_tree_store_set_values (fixture.store, &root, TRUE);
3846 create_tree_store_set_values (fixture.store, &iter, TRUE);
3848 /* check_filter_model (&fixture); */
3849 signal_monitor_assert_is_empty (fixture.monitor);
3851 /* Add another child for 1 */
3852 gtk_tree_store_append (fixture.store, &iter, &root);
3853 create_tree_store_set_values (fixture.store, &iter, TRUE);
3854 check_level_length (fixture.filter, NULL, 2);
3855 check_level_length (fixture.filter, "0", 0);
3856 check_level_length (fixture.filter, "1", 0);
3857 signal_monitor_assert_is_empty (fixture.monitor);
3859 /* Now remove one of the remaining child rows */
3860 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
3862 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
3864 gtk_tree_store_remove (fixture.store, &iter);
3866 check_level_length (fixture.filter, NULL, 1);
3867 check_level_length (fixture.filter, "0", 0);
3869 set_path_visibility (&fixture, "0", FALSE);
3870 /* check_filter_model (&fixture); */
3871 signal_monitor_assert_is_empty (fixture.monitor);
3876 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
3883 path = gtk_tree_model_get_path (model, iter);
3884 depth = gtk_tree_path_get_depth (path);
3885 gtk_tree_path_free (path);
3890 return gtk_tree_model_iter_has_child (model, iter);
3894 specific_root_has_child_filter (void)
3896 GtkTreeModel *filter;
3897 GtkTreeIter iter, root;
3898 FilterTest fixture; /* This is not how it should be done ... */
3899 GtkWidget *tree_view;
3901 /* This is a variation on the above test case, specific has-child-filter,
3902 * herein the has-child check for visibility only applies to root level
3903 * nodes. In this test, children are always visible because we
3904 * only filter based on the "has child" criterion.
3907 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3908 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3909 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3910 fixture.monitor = signal_monitor_new (filter);
3912 tree_view = gtk_tree_view_new_with_model (filter);
3914 /* We will filter on parent state using a filter function. We will
3915 * manually keep the boolean column in sync, so that we can use
3916 * check_filter_model() to check the consistency of the model.
3918 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3919 * to be able to check the structure here. We keep the calls to
3920 * check_filter_model() commented out until then.
3922 gtk_tree_model_filter_set_visible_func (fixture.filter,
3923 specific_root_has_child_filter_filter_func,
3926 /* Add a first node, this will be invisible initially, so no signal
3927 * should be emitted.
3929 gtk_tree_store_append (fixture.store, &root, NULL);
3930 create_tree_store_set_values (fixture.store, &root, FALSE);
3932 signal_monitor_assert_is_empty (fixture.monitor);
3933 /* check_filter_model (&fixture); */
3934 check_level_length (fixture.filter, NULL, 0);
3936 /* Add a child node. This will cause the parent to become visible,
3937 * so we expect row-inserted signals for both.
3939 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3940 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3941 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3943 gtk_tree_store_append (fixture.store, &iter, &root);
3944 signal_monitor_assert_is_empty (fixture.monitor);
3946 check_level_length (fixture.filter, NULL, 1);
3947 check_level_length (fixture.filter, "0", 1);
3949 /* Modify the content of iter, no signals because the parent is not
3952 create_tree_store_set_values (fixture.store, &iter, TRUE);
3953 signal_monitor_assert_is_empty (fixture.monitor);
3955 /* Parent must now be visible. Do the level length check first,
3956 * to avoid modifying the child model triggering a row-changed to
3959 check_level_length (fixture.filter, NULL, 1);
3960 check_level_length (fixture.filter, "0", 1);
3963 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3964 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3966 set_path_visibility (&fixture, "0", TRUE);
3967 /* check_filter_model (&fixture); */
3969 signal_monitor_assert_is_empty (fixture.monitor);
3971 /* Insert another node in the root level. Initially invisible, so
3972 * not expecting any signal.
3974 gtk_tree_store_append (fixture.store, &root, NULL);
3975 check_level_length (fixture.filter, NULL, 1);
3977 signal_monitor_assert_is_empty (fixture.monitor);
3979 /* Adding a child node which also makes parent at path 1 visible. */
3980 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
3981 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3982 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3984 gtk_tree_store_append (fixture.store, &iter, &root);
3985 check_level_length (fixture.filter, NULL, 2);
3986 check_level_length (fixture.filter, "1", 1);
3988 signal_monitor_assert_is_empty (fixture.monitor);
3990 /* Check if row-changed is propagated */
3991 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
3992 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3994 create_tree_store_set_values (fixture.store, &root, TRUE);
3995 create_tree_store_set_values (fixture.store, &iter, TRUE);
3996 /* check_filter_model (&fixture); */
3997 signal_monitor_assert_is_empty (fixture.monitor);
3999 /* Insert another child under node 1 */
4000 gtk_tree_store_append (fixture.store, &iter, &root);
4001 create_tree_store_set_values (fixture.store, &iter, TRUE);
4002 check_level_length (fixture.filter, NULL, 2);
4003 check_level_length (fixture.filter, "0", 1);
4004 check_level_length (fixture.filter, "1", 2);
4005 signal_monitor_assert_is_empty (fixture.monitor);
4007 /* Set a child node to invisible. This should not yield any
4008 * change, because filtering is only done on whether the root
4009 * node has a child, which it still has.
4011 set_path_visibility (&fixture, "0:0", FALSE);
4012 signal_monitor_assert_is_empty (fixture.monitor);
4014 /* Now remove one of the remaining child rows */
4015 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4016 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4018 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4020 gtk_tree_store_remove (fixture.store, &iter);
4022 check_level_length (fixture.filter, NULL, 1);
4023 check_level_length (fixture.filter, "0", 2);
4024 signal_monitor_assert_is_empty (fixture.monitor);
4026 /* Set visibility of 0 to FALSE, no-op for filter model since
4027 * the child 0:0 is already gone
4029 set_path_visibility (&fixture, "0", FALSE);
4030 /* check_filter_model (&fixture); */
4031 signal_monitor_assert_is_empty (fixture.monitor);
4035 specific_has_child_filter_on_sort_model (void)
4037 GtkTreeModel *filter;
4038 GtkTreeModel *sort_model;
4039 GtkTreeIter iter, root;
4040 FilterTest fixture; /* This is not how it should be done */
4041 GtkWidget *tree_view;
4043 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4044 sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
4045 filter = gtk_tree_model_filter_new (sort_model, NULL);
4046 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4047 fixture.monitor = signal_monitor_new (filter);
4049 tree_view = gtk_tree_view_new_with_model (filter);
4051 /* We will filter on parent state using a filter function. We will
4052 * manually keep the boolean column in sync, so that we can use
4053 * check_filter_model() to check the consistency of the model.
4055 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
4056 * to be able to check the structure here. We keep the calls to
4057 * check_filter_model() commented out until then.
4059 gtk_tree_model_filter_set_visible_func (fixture.filter,
4060 specific_has_child_filter_filter_func,
4063 /* The first node will be initially invisible: no signals */
4064 gtk_tree_store_append (fixture.store, &root, NULL);
4065 create_tree_store_set_values (fixture.store, &root, FALSE);
4067 /* check_filter_model (&fixture); */
4068 check_level_length (fixture.filter, NULL, 0);
4069 signal_monitor_assert_is_empty (fixture.monitor);
4071 /* Insert a child node. This will cause the parent to become visible
4072 * since there is a child now.
4074 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4075 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4077 gtk_tree_store_append (fixture.store, &iter, &root);
4078 create_tree_store_set_values (fixture.store, &iter, TRUE);
4080 /* Parent must now be visible. Do the level length check first,
4081 * to avoid modifying the child model triggering a row-changed to
4084 check_level_length (fixture.filter, NULL, 1);
4085 check_level_length (fixture.filter, "0", 0);
4086 signal_monitor_assert_is_empty (fixture.monitor);
4088 /* This should propagate row-changed */
4089 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4090 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4092 set_path_visibility (&fixture, "0", TRUE);
4093 /* check_filter_model (&fixture); */
4094 signal_monitor_assert_is_empty (fixture.monitor);
4096 /* New root node, no child, so no signal */
4097 gtk_tree_store_append (fixture.store, &root, NULL);
4098 check_level_length (fixture.filter, NULL, 1);
4099 signal_monitor_assert_is_empty (fixture.monitor);
4101 /* When the child comes in, this node will become visible */
4102 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
4103 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4104 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
4105 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4107 gtk_tree_store_append (fixture.store, &iter, &root);
4108 check_level_length (fixture.filter, NULL, 2);
4109 check_level_length (fixture.filter, "1", 0);
4111 create_tree_store_set_values (fixture.store, &root, TRUE);
4112 create_tree_store_set_values (fixture.store, &iter, TRUE);
4114 /* check_filter_model (&fixture); */
4115 signal_monitor_assert_is_empty (fixture.monitor);
4117 /* Add another child for 1 */
4118 gtk_tree_store_append (fixture.store, &iter, &root);
4119 create_tree_store_set_values (fixture.store, &iter, TRUE);
4120 check_level_length (fixture.filter, NULL, 2);
4121 check_level_length (fixture.filter, "0", 0);
4122 check_level_length (fixture.filter, "1", 0);
4123 signal_monitor_assert_is_empty (fixture.monitor);
4125 /* Now remove one of the remaining child rows */
4126 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4128 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4130 gtk_tree_store_remove (fixture.store, &iter);
4132 check_level_length (fixture.filter, NULL, 1);
4133 check_level_length (fixture.filter, "0", 0);
4135 set_path_visibility (&fixture, "0", FALSE);
4136 /* check_filter_model (&fixture); */
4137 signal_monitor_assert_is_empty (fixture.monitor);
4141 specific_at_least_2_children_filter_filter_func (GtkTreeModel *model,
4145 return gtk_tree_model_iter_n_children (model, iter) >= 2;
4149 specific_at_least_2_children_filter (void)
4151 GtkTreeModel *filter;
4152 GtkTreeIter iter, root;
4153 FilterTest fixture; /* This is not how it should be done */
4154 GtkWidget *tree_view;
4156 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4157 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
4158 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4159 fixture.monitor = signal_monitor_new (filter);
4161 tree_view = gtk_tree_view_new_with_model (filter);
4163 gtk_tree_model_filter_set_visible_func (fixture.filter,
4164 specific_at_least_2_children_filter_filter_func,
4167 /* The first node will be initially invisible: no signals */
4168 gtk_tree_store_append (fixture.store, &root, NULL);
4169 create_tree_store_set_values (fixture.store, &root, FALSE);
4171 /* check_filter_model (&fixture); */
4172 check_level_length (fixture.filter, NULL, 0);
4173 signal_monitor_assert_is_empty (fixture.monitor);
4175 /* Insert a child node. Nothing should happen.
4177 gtk_tree_store_append (fixture.store, &iter, &root);
4178 create_tree_store_set_values (fixture.store, &iter, TRUE);
4180 check_level_length (fixture.filter, NULL, 0);
4181 signal_monitor_assert_is_empty (fixture.monitor);
4183 /* Insert a second child node. This will cause the parent to become
4186 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4187 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4189 gtk_tree_store_append (fixture.store, &iter, &root);
4190 create_tree_store_set_values (fixture.store, &iter, TRUE);
4192 /* Parent must now be visible. Do the level length check first,
4193 * to avoid modifying the child model triggering a row-changed to
4196 check_level_length (fixture.filter, NULL, 1);
4197 check_level_length (fixture.filter, "0", 0);
4198 signal_monitor_assert_is_empty (fixture.monitor);
4200 /* This should propagate row-changed */
4201 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4202 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4204 set_path_visibility (&fixture, "0", TRUE);
4205 /* check_filter_model (&fixture); */
4206 signal_monitor_assert_is_empty (fixture.monitor);
4208 /* New root node, no child, so no signal */
4209 gtk_tree_store_append (fixture.store, &root, NULL);
4210 check_level_length (fixture.filter, NULL, 1);
4211 signal_monitor_assert_is_empty (fixture.monitor);
4213 /* First child, no signal, no change */
4214 gtk_tree_store_append (fixture.store, &iter, &root);
4215 check_level_length (fixture.filter, NULL, 1);
4216 signal_monitor_assert_is_empty (fixture.monitor);
4218 /* When the second child comes in, this node will become visible */
4219 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
4220 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4221 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
4222 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4224 gtk_tree_store_append (fixture.store, &iter, &root);
4225 check_level_length (fixture.filter, NULL, 2);
4226 check_level_length (fixture.filter, "1", 0);
4228 create_tree_store_set_values (fixture.store, &root, TRUE);
4229 create_tree_store_set_values (fixture.store, &iter, TRUE);
4231 /* check_filter_model (&fixture); */
4232 signal_monitor_assert_is_empty (fixture.monitor);
4234 /* Add another child for 1 */
4235 gtk_tree_store_append (fixture.store, &iter, &root);
4236 create_tree_store_set_values (fixture.store, &iter, TRUE);
4237 check_level_length (fixture.filter, NULL, 2);
4238 check_level_length (fixture.filter, "0", 0);
4239 check_level_length (fixture.filter, "1", 0);
4240 signal_monitor_assert_is_empty (fixture.monitor);
4242 /* Now remove one of the remaining child rows */
4243 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4245 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4247 gtk_tree_store_remove (fixture.store, &iter);
4249 check_level_length (fixture.filter, NULL, 1);
4250 check_level_length (fixture.filter, "0", 0);
4252 set_path_visibility (&fixture, "0", FALSE);
4253 /* check_filter_model (&fixture); */
4254 signal_monitor_assert_is_empty (fixture.monitor);
4258 specific_at_least_2_children_filter_on_sort_model (void)
4260 GtkTreeModel *filter;
4261 GtkTreeModel *sort_model;
4262 GtkTreeIter iter, root;
4263 FilterTest fixture; /* This is not how it should be done */
4264 GtkWidget *tree_view;
4266 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4267 sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
4268 filter = gtk_tree_model_filter_new (sort_model, NULL);
4269 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4270 fixture.monitor = signal_monitor_new (filter);
4272 tree_view = gtk_tree_view_new_with_model (filter);
4274 gtk_tree_model_filter_set_visible_func (fixture.filter,
4275 specific_at_least_2_children_filter_filter_func,
4278 /* The first node will be initially invisible: no signals */
4279 gtk_tree_store_append (fixture.store, &root, NULL);
4280 create_tree_store_set_values (fixture.store, &root, FALSE);
4282 /* check_filter_model (&fixture); */
4283 check_level_length (fixture.filter, NULL, 0);
4284 signal_monitor_assert_is_empty (fixture.monitor);
4286 /* Insert a child node. Nothing should happen.
4288 gtk_tree_store_append (fixture.store, &iter, &root);
4289 create_tree_store_set_values (fixture.store, &iter, TRUE);
4291 check_level_length (fixture.filter, NULL, 0);
4292 signal_monitor_assert_is_empty (fixture.monitor);
4295 GtkTreePath *path = gtk_tree_path_new_from_indices (0, 0, -1);
4296 GtkTreeRowReference *ref;
4298 ref = gtk_tree_row_reference_new (sort_model, path);
4299 gtk_tree_path_free (path);
4302 /* Insert a second child node. This will cause the parent to become
4305 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4306 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4308 gtk_tree_store_append (fixture.store, &iter, &root);
4309 create_tree_store_set_values (fixture.store, &iter, TRUE);
4311 /* Parent must now be visible. Do the level length check first,
4312 * to avoid modifying the child model triggering a row-changed to
4315 check_level_length (fixture.filter, NULL, 1);
4316 check_level_length (fixture.filter, "0", 0);
4317 signal_monitor_assert_is_empty (fixture.monitor);
4319 /* This should propagate row-changed */
4320 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4321 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4323 set_path_visibility (&fixture, "0", TRUE);
4324 /* check_filter_model (&fixture); */
4325 signal_monitor_assert_is_empty (fixture.monitor);
4327 /* New root node, no child, so no signal */
4328 gtk_tree_store_append (fixture.store, &root, NULL);
4329 check_level_length (fixture.filter, NULL, 1);
4330 signal_monitor_assert_is_empty (fixture.monitor);
4335 specific_filter_add_child (void)
4337 /* This test is based on one of the test cases I found in my
4338 * old test cases directory. I unfortunately do not have a record
4339 * from who this test case originated. -Kris.
4343 GtkTreeIter iter_first;
4345 GtkTreeStore *store;
4346 GtkTreeModel *filter G_GNUC_UNUSED;
4348 store = gtk_tree_store_new (1, G_TYPE_STRING);
4350 gtk_tree_store_append (store, &iter_first, NULL);
4351 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
4353 gtk_tree_store_append (store, &iter, NULL);
4354 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4356 gtk_tree_store_append (store, &iter, NULL);
4357 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4359 gtk_tree_store_append (store, &iter, NULL);
4360 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4362 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4364 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4365 gtk_tree_store_append (store, &child, &iter_first);
4366 gtk_tree_store_set (store, &child, 0, "Hello", -1);
4370 specific_list_store_clear (void)
4374 GtkTreeModel *filter;
4375 GtkWidget *view G_GNUC_UNUSED;
4377 list = gtk_list_store_new (1, G_TYPE_INT);
4378 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
4379 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
4380 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
4381 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
4382 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
4383 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
4384 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
4385 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
4387 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
4388 view = gtk_tree_view_new_with_model (filter);
4390 gtk_list_store_clear (list);
4394 specific_sort_ref_leaf_and_remove_ancestor (void)
4396 GtkTreeIter iter, child, child2, child3;
4400 GtkTreeRowReference *rowref;
4401 GtkWidget *view G_GNUC_UNUSED;
4403 tree = gtk_tree_store_new (1, G_TYPE_INT);
4404 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4405 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4406 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4407 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4409 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4410 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4411 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4413 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
4414 view = gtk_tree_view_new_with_model (sort);
4415 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4417 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4418 rowref = gtk_tree_row_reference_new (sort, path);
4419 gtk_tree_path_free (path);
4421 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4422 rowref = gtk_tree_row_reference_new (sort, path);
4423 gtk_tree_path_free (path);
4425 path = gtk_tree_path_new_from_indices (3, 0, -1);
4426 rowref = gtk_tree_row_reference_new (sort, path);
4427 gtk_tree_path_free (path);
4429 path = gtk_tree_path_new_from_indices (3, -1);
4430 rowref = gtk_tree_row_reference_new (sort, path);
4431 gtk_tree_path_free (path);
4433 /* Deleting a parent */
4434 path = gtk_tree_path_new_from_indices (3, 0, -1);
4435 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4436 gtk_tree_store_remove (tree, &iter);
4437 gtk_tree_path_free (path);
4439 gtk_tree_row_reference_free (rowref);
4443 specific_ref_leaf_and_remove_ancestor (void)
4445 GtkTreeIter iter, child, child2, child3;
4447 GtkTreeModel *filter;
4449 GtkTreeRowReference *rowref;
4450 GtkWidget *view G_GNUC_UNUSED;
4452 tree = gtk_tree_store_new (1, G_TYPE_INT);
4453 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4454 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4455 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4456 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4458 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4459 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4460 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4462 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), NULL);
4463 view = gtk_tree_view_new_with_model (filter);
4464 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4466 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4467 rowref = gtk_tree_row_reference_new (filter, path);
4468 gtk_tree_path_free (path);
4470 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4471 rowref = gtk_tree_row_reference_new (filter, path);
4472 gtk_tree_path_free (path);
4474 path = gtk_tree_path_new_from_indices (3, 0, -1);
4475 rowref = gtk_tree_row_reference_new (filter, path);
4476 gtk_tree_path_free (path);
4478 path = gtk_tree_path_new_from_indices (3, -1);
4479 rowref = gtk_tree_row_reference_new (filter, path);
4480 gtk_tree_path_free (path);
4482 /* Deleting a parent */
4483 path = gtk_tree_path_new_from_indices (3, 0, -1);
4484 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4485 gtk_tree_store_remove (tree, &iter);
4486 gtk_tree_path_free (path);
4488 gtk_tree_row_reference_free (rowref);
4492 specific_virtual_ref_leaf_and_remove_ancestor (void)
4494 GtkTreeIter iter, child, child2, child3;
4496 GtkTreeModel *filter;
4498 GtkTreeRowReference *rowref;
4499 GtkWidget *view G_GNUC_UNUSED;
4501 tree = gtk_tree_store_new (1, G_TYPE_INT);
4502 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4503 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4504 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4505 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4507 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4508 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4509 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4511 /* Set a virtual root of 3:0 */
4512 path = gtk_tree_path_new_from_indices (3, 0, -1);
4513 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
4514 gtk_tree_path_free (path);
4516 view = gtk_tree_view_new_with_model (filter);
4517 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4519 path = gtk_tree_path_new_from_indices (0, 0, -1);
4520 rowref = gtk_tree_row_reference_new (filter, path);
4521 gtk_tree_path_free (path);
4523 path = gtk_tree_path_new_from_indices (0, 0, -1);
4524 rowref = gtk_tree_row_reference_new (filter, path);
4525 gtk_tree_path_free (path);
4527 path = gtk_tree_path_new_from_indices (0, -1);
4528 rowref = gtk_tree_row_reference_new (filter, path);
4529 gtk_tree_path_free (path);
4531 /* Deleting the virtual root */
4532 path = gtk_tree_path_new_from_indices (3, 0, -1);
4533 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4534 gtk_tree_store_remove (tree, &iter);
4535 gtk_tree_path_free (path);
4537 gtk_tree_row_reference_free (rowref);
4542 specific_bug_301558_sort_func (GtkTreeModel *model,
4549 gtk_tree_model_get (model, a, 0, &i, -1);
4550 gtk_tree_model_get (model, b, 0, &j, -1);
4556 specific_bug_301558 (void)
4558 /* Test case for GNOME Bugzilla bug 301558 provided by
4562 GtkTreeModel *filter;
4564 GtkTreeIter root, iter, iter2;
4565 GtkWidget *view G_GNUC_UNUSED;
4569 g_test_bug ("301558");
4571 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
4572 gtk_tree_store_append (tree, &iter, NULL);
4573 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
4574 gtk_tree_store_append (tree, &iter2, &iter);
4575 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
4577 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
4578 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
4579 specific_bug_301558_sort_func,
4582 filter = gtk_tree_model_filter_new (sort, NULL);
4583 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
4585 view = gtk_tree_view_new_with_model (filter);
4587 while (gtk_events_pending ())
4588 gtk_main_iteration ();
4592 for (i = 0; i < 10; i++)
4594 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
4595 g_assert_not_reached ();
4599 gtk_tree_store_append (tree, &iter, &root);
4600 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
4605 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
4606 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
4608 gtk_tree_store_remove (tree, &iter);
4617 specific_bug_311955_filter_func (GtkTreeModel *model,
4623 gtk_tree_model_get (model, iter, 0, &value, -1);
4625 return (value != 0);
4629 specific_bug_311955 (void)
4631 /* This is a test case for GNOME Bugzilla bug 311955. It was written
4634 GtkTreeIter iter, child, root;
4635 GtkTreeStore *store;
4637 GtkTreeModel *filter;
4639 GtkWidget *window G_GNUC_UNUSED;
4640 GtkWidget *tree_view;
4645 g_test_bug ("311955");
4647 store = gtk_tree_store_new (1, G_TYPE_INT);
4649 gtk_tree_store_append (store, &root, NULL);
4650 gtk_tree_store_set (store, &root, 0, 33, -1);
4652 gtk_tree_store_append (store, &iter, &root);
4653 gtk_tree_store_set (store, &iter, 0, 50, -1);
4655 gtk_tree_store_append (store, &iter, NULL);
4656 gtk_tree_store_set (store, &iter, 0, 22, -1);
4658 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
4659 filter = gtk_tree_model_filter_new (sort, NULL);
4661 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4662 specific_bug_311955_filter_func,
4665 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4666 tree_view = gtk_tree_view_new_with_model (filter);
4667 g_object_unref (store);
4669 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
4671 while (gtk_events_pending ())
4672 gtk_main_iteration ();
4674 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
4675 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
4678 for (i = 0; i < 4; i++)
4680 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
4682 gtk_tree_store_append (store, &iter, &root);
4685 gtk_tree_store_set (store, &iter, 0, i, -1);
4689 gtk_tree_store_append (store, &child, &iter);
4690 gtk_tree_store_set (store, &child, 0, 10, -1);
4694 while (gtk_events_pending ())
4695 gtk_main_iteration ();
4697 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4698 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 1);
4700 /* Remove bottommost child from the tree. */
4701 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
4702 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
4704 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
4706 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
4707 gtk_tree_store_remove (store, &child);
4710 g_assert_not_reached ();
4712 path = gtk_tree_path_new_from_indices (0, 2, -1);
4713 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
4714 gtk_tree_path_free (path);
4716 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4717 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
4721 specific_bug_311955_clean (void)
4723 /* Cleaned up version of the test case for GNOME Bugzilla bug 311955,
4724 * which is easier to understand.
4726 GtkTreeIter iter, child, grandchild;
4727 GtkTreeStore *store;
4729 GtkTreeModel *filter;
4731 GtkWidget *tree_view;
4734 store = gtk_tree_store_new (1, G_TYPE_INT);
4736 gtk_tree_store_append (store, &iter, NULL);
4737 gtk_tree_store_set (store, &iter, 0, 1, -1);
4739 gtk_tree_store_append (store, &child, &iter);
4740 gtk_tree_store_set (store, &child, 0, 1, -1);
4742 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
4743 filter = gtk_tree_model_filter_new (sort, NULL);
4745 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4746 specific_bug_311955_filter_func,
4749 tree_view = gtk_tree_view_new_with_model (filter);
4750 g_object_unref (store);
4752 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
4754 while (gtk_events_pending ())
4755 gtk_main_iteration ();
4757 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
4758 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
4760 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
4762 gtk_tree_store_append (store, &child, &iter);
4763 gtk_tree_store_set (store, &child, 0, 0, -1);
4765 gtk_tree_store_append (store, &child, &iter);
4766 gtk_tree_store_set (store, &child, 0, 1, -1);
4768 gtk_tree_store_append (store, &child, &iter);
4769 gtk_tree_store_set (store, &child, 0, 1, -1);
4771 gtk_tree_store_append (store, &grandchild, &child);
4772 gtk_tree_store_set (store, &grandchild, 0, 1, -1);
4774 gtk_tree_store_append (store, &child, &iter);
4775 /* Don't set a value: assume 0 */
4777 /* Remove leaf node, check trigger row-has-child-toggled */
4778 path = gtk_tree_path_new_from_indices (0, 3, 0, -1);
4779 gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
4780 gtk_tree_path_free (path);
4781 gtk_tree_store_remove (store, &iter);
4783 path = gtk_tree_path_new_from_indices (0, 2, -1);
4784 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
4785 gtk_tree_path_free (path);
4787 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4788 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
4790 gtk_widget_destroy (tree_view);
4794 specific_bug_346800 (void)
4796 /* This is a test case for GNOME Bugzilla bug 346800. It was written
4797 * by Jonathan Matthew.
4800 GtkTreeIter node_iters[50];
4801 GtkTreeIter child_iters[50];
4802 GtkTreeModel *model;
4803 GtkTreeModelFilter *filter;
4804 GtkTreeStore *store;
4808 columns = g_new (GType, 2);
4809 columns[0] = G_TYPE_STRING;
4810 columns[1] = G_TYPE_BOOLEAN;
4811 store = gtk_tree_store_newv (2, columns);
4812 model = GTK_TREE_MODEL (store);
4814 g_test_bug ("346800");
4816 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
4817 gtk_tree_model_filter_set_visible_column (filter, 1);
4819 for (i=0; i<items; i++)
4821 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
4824 gtk_tree_store_append (store, &node_iters[i], NULL);
4825 gtk_tree_store_set (store, &node_iters[i],
4827 1, ((i%6) == 0) ? FALSE : TRUE,
4831 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
4832 gtk_tree_store_set (store, &child_iters[i],
4833 0, "something else",
4836 gtk_tree_model_filter_refilter (filter);
4840 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
4841 (i & 1) ? TRUE : FALSE, -1);
4842 gtk_tree_model_filter_refilter (filter);
4844 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
4845 (i & 1) ? FALSE: TRUE, -1);
4846 gtk_tree_model_filter_refilter (filter);
4852 specific_bug_464173_visible_func (GtkTreeModel *model,
4856 gboolean *visible = (gboolean *)data;
4862 specific_bug_464173 (void)
4864 /* Test case for GNOME Bugzilla bug 464173, test case written
4865 * by Andreas Koehler.
4867 GtkTreeStore *model;
4868 GtkTreeModelFilter *f_model;
4869 GtkTreeIter iter1, iter2;
4870 GtkWidget *view G_GNUC_UNUSED;
4871 gboolean visible = TRUE;
4873 g_test_bug ("464173");
4875 model = gtk_tree_store_new (1, G_TYPE_STRING);
4876 gtk_tree_store_append (model, &iter1, NULL);
4877 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
4878 gtk_tree_store_append (model, &iter2, &iter1);
4879 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
4881 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
4882 gtk_tree_model_filter_set_visible_func (f_model,
4883 specific_bug_464173_visible_func,
4886 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
4889 gtk_tree_model_filter_refilter (f_model);
4894 specific_bug_540201_filter_func (GtkTreeModel *model,
4898 gboolean has_children;
4900 has_children = gtk_tree_model_iter_has_child (model, iter);
4902 return has_children;
4906 specific_bug_540201 (void)
4908 /* Test case for GNOME Bugzilla bug 540201, steps provided by
4911 GtkTreeIter iter, root;
4912 GtkTreeStore *store;
4913 GtkTreeModel *filter;
4915 GtkWidget *tree_view G_GNUC_UNUSED;
4917 g_test_bug ("540201");
4919 store = gtk_tree_store_new (1, G_TYPE_INT);
4921 gtk_tree_store_append (store, &root, NULL);
4922 gtk_tree_store_set (store, &root, 0, 33, -1);
4924 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4925 tree_view = gtk_tree_view_new_with_model (filter);
4927 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4928 specific_bug_540201_filter_func,
4931 gtk_tree_store_append (store, &iter, &root);
4932 gtk_tree_store_set (store, &iter, 0, 50, -1);
4934 gtk_tree_store_append (store, &iter, &root);
4935 gtk_tree_store_set (store, &iter, 0, 22, -1);
4938 gtk_tree_store_append (store, &root, NULL);
4939 gtk_tree_store_set (store, &root, 0, 33, -1);
4941 gtk_tree_store_append (store, &iter, &root);
4942 gtk_tree_store_set (store, &iter, 0, 22, -1);
4947 specific_bug_549287_visible_func (GtkTreeModel *model,
4951 gboolean result = FALSE;
4953 result = gtk_tree_model_iter_has_child (model, iter);
4959 specific_bug_549287 (void)
4961 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
4964 GtkTreeStore *store;
4965 GtkTreeModel *filtered;
4966 GtkWidget *view G_GNUC_UNUSED;
4968 GtkTreeIter *swap, *parent, *child;
4970 g_test_bug ("529287");
4972 store = gtk_tree_store_new (1, G_TYPE_STRING);
4973 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4974 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
4975 specific_bug_549287_visible_func,
4978 view = gtk_tree_view_new_with_model (filtered);
4980 for (i = 0; i < 4; i++)
4982 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
4984 parent = gtk_tree_iter_copy (&iter);
4985 child = gtk_tree_iter_copy (&iter);
4987 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
4996 gtk_tree_store_append (store, child, parent);
4997 gtk_tree_store_set (store, child,
5001 gtk_tree_iter_free (parent);
5002 gtk_tree_iter_free (child);
5006 gtk_tree_store_append (store, &iter, NULL);
5007 gtk_tree_store_set (store, &iter,
5012 /* since we inserted something, we changed the visibility conditions: */
5013 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
5018 specific_bug_621076_visible_func (GtkTreeModel *model,
5022 gboolean visible = FALSE;
5025 gtk_tree_model_get (model, iter, 0, &str, -1);
5026 if (str != NULL && g_str_has_prefix (str, "visible"))
5032 GtkTreeIter child_iter;
5035 /* Recursively check if we have a visible child */
5036 for (valid = gtk_tree_model_iter_children (model, &child_iter, iter);
5037 valid; valid = gtk_tree_model_iter_next (model, &child_iter))
5039 if (specific_bug_621076_visible_func (model, &child_iter, data))
5054 specific_bug_621076 (void)
5056 /* Test case for GNOME Bugzilla bug 621076, provided by Xavier Claessens */
5058 /* This test case differs from has-child-filter and root-has-child-filter
5059 * in that the visible function both filters on content and model
5060 * structure. Also, it is recursive.
5063 GtkTreeStore *store;
5064 GtkTreeModel *filter;
5066 GtkTreeIter group_iter;
5067 GtkTreeIter item_iter;
5068 SignalMonitor *monitor;
5070 g_test_bug ("621076");
5072 store = gtk_tree_store_new (1, G_TYPE_STRING);
5073 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
5074 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
5075 specific_bug_621076_visible_func,
5078 view = gtk_tree_view_new_with_model (filter);
5079 g_object_ref_sink (view);
5081 monitor = signal_monitor_new (filter);
5083 signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
5084 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5085 0, "visible-group-0",
5087 signal_monitor_assert_is_empty (monitor);
5089 /* visible-group-0 is not expanded, so ROW_INSERTED should not be emitted
5090 * for its children. However, ROW_HAS_CHILD_TOGGLED should be emitted on
5091 * visible-group-0 to tell the view that row can be expanded. */
5092 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
5093 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
5094 group_iter = item_iter;
5095 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5098 signal_monitor_assert_is_empty (monitor);
5100 signal_monitor_append_signal (monitor, ROW_INSERTED, "1");
5101 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5102 0, "visible-group-1",
5104 signal_monitor_assert_is_empty (monitor);
5106 /* We are adding an hidden item inside visible-group-1, so
5107 * ROW_HAS_CHILD_TOGGLED should not be emitted. It is emitted though,
5108 * because the signal originating at TreeStore will be propagated,
5109 * as well a generated signal because the state of the parent *could*
5110 * change by a change in the model.
5112 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5113 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5114 group_iter = item_iter;
5115 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5118 signal_monitor_assert_is_empty (monitor);
5120 /* This group is invisible and its parent too. Nothing should be emitted */
5121 group_iter = item_iter;
5122 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5125 signal_monitor_assert_is_empty (monitor);
5127 /* Adding a visible item in this group hierarchy will make all nodes
5128 * in this path visible. The first level should simply tell the view
5129 * that it now has a child, and the view will load the tree if needed
5130 * (depends on the expanded state).
5132 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5133 group_iter = item_iter;
5134 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5135 0, "visible-1:0:0:0",
5137 signal_monitor_assert_is_empty (monitor);
5139 check_level_length (GTK_TREE_MODEL_FILTER (filter), "1", 1);
5141 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5144 signal_monitor_assert_is_empty (monitor);
5146 /* Parent is invisible, and adding this invisible item won't change that,
5147 * so no signal should be emitted. */
5148 group_iter = item_iter;
5149 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5152 signal_monitor_assert_is_empty (monitor);
5154 /* This makes group-2 visible, so it gets inserted and tells it has
5157 signal_monitor_append_signal (monitor, ROW_INSERTED, "2");
5158 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5159 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5162 signal_monitor_assert_is_empty (monitor);
5164 /* group-2 is already visible, so this time it is a normal insertion */
5165 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5168 signal_monitor_assert_is_empty (monitor);
5171 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5174 signal_monitor_assert_is_empty (monitor);
5176 /* Parent is invisible, and adding this invisible item won't change that,
5177 * so no signal should be emitted. */
5178 group_iter = item_iter;
5179 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5182 signal_monitor_assert_is_empty (monitor);
5184 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5187 signal_monitor_assert_is_empty (monitor);
5189 /* This will make group 3 visible. */
5190 signal_monitor_append_signal (monitor, ROW_INSERTED, "3");
5191 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
5192 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
5193 gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
5194 signal_monitor_assert_is_empty (monitor);
5196 /* Make sure all groups are expanded, so the filter has the tree cached */
5197 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
5198 while (gtk_events_pending ())
5199 gtk_main_iteration ();
5201 /* Should only yield a row-changed */
5202 signal_monitor_append_signal (monitor, ROW_CHANGED, "3:0");
5203 gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
5204 signal_monitor_assert_is_empty (monitor);
5206 /* Now remove/hide some items. If a group loses its last item, the group
5207 * should be deleted instead of the item.
5210 signal_monitor_append_signal (monitor, ROW_DELETED, "2:1");
5211 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:2");
5212 gtk_tree_store_remove (store, &item_iter);
5213 signal_monitor_assert_is_empty (monitor);
5215 signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
5216 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5217 signal_monitor_append_signal (monitor, ROW_DELETED, "2");
5218 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:1");
5219 gtk_tree_store_set (store, &item_iter, 0, "invisible-2:1", -1);
5220 signal_monitor_assert_is_empty (monitor);
5222 signal_monitor_append_signal (monitor, ROW_DELETED, "1:0:0:0");
5223 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1:0:0");
5224 signal_monitor_append_signal (monitor, ROW_DELETED, "1:0");
5225 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5226 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "1:0:0:0");
5227 gtk_tree_store_remove (store, &item_iter);
5228 signal_monitor_assert_is_empty (monitor);
5230 /* Hide a group using row-changed instead of row-deleted */
5231 /* Caution: group 2 is gone, so offsets of the signals have moved. */
5232 signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
5233 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5234 signal_monitor_append_signal (monitor, ROW_DELETED, "2");
5235 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter,
5237 gtk_tree_store_set (store, &item_iter, 0, "invisible-3:1", -1);
5238 signal_monitor_assert_is_empty (monitor);
5243 GtkTreeViewColumn *col;
5245 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
5247 col = gtk_tree_view_column_new_with_attributes ("foo",
5248 gtk_cell_renderer_text_new (),
5250 gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
5252 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5253 g_signal_connect (window, "delete-event",
5254 G_CALLBACK (gtk_widget_destroy), NULL);
5255 g_signal_connect (window, "destroy",
5256 G_CALLBACK (gtk_main_quit), NULL);
5258 gtk_container_add (GTK_CONTAINER (window), view);
5260 gtk_widget_show (view);
5261 gtk_widget_show (window);
5268 signal_monitor_free (monitor);
5269 g_object_unref (view);
5270 g_object_unref (store);
5271 g_object_unref (filter);
5277 register_filter_model_tests (void)
5279 g_test_add ("/TreeModelFilter/self/verify-test-suite",
5283 filter_test_teardown);
5285 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-1",
5286 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5288 verify_test_suite_vroot,
5289 filter_test_teardown);
5290 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-2",
5291 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
5293 verify_test_suite_vroot,
5294 filter_test_teardown);
5297 g_test_add ("/TreeModelFilter/filled/hide-root-level",
5300 filled_hide_root_level,
5301 filter_test_teardown);
5302 g_test_add ("/TreeModelFilter/filled/hide-child-levels",
5305 filled_hide_child_levels,
5306 filter_test_teardown);
5307 g_test_add ("/TreeModelFilter/filled/hide-child-levels/root-expanded",
5310 filled_hide_child_levels_root_expanded,
5311 filter_test_teardown);
5313 g_test_add ("/TreeModelFilter/filled/hide-root-level/vroot",
5314 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5316 filled_vroot_hide_root_level,
5317 filter_test_teardown);
5318 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot",
5319 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5321 filled_vroot_hide_child_levels,
5322 filter_test_teardown);
5323 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot-root-expanded",
5324 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5326 filled_vroot_hide_child_levels_root_expanded,
5327 filter_test_teardown);
5330 g_test_add ("/TreeModelFilter/empty/show-nodes",
5332 filter_test_setup_empty,
5334 filter_test_teardown);
5335 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes",
5337 filter_test_setup_empty,
5338 empty_show_multiple_nodes,
5339 filter_test_teardown);
5341 g_test_add ("/TreeModelFilter/empty/show-nodes/vroot",
5342 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5343 filter_test_setup_empty,
5344 empty_vroot_show_nodes,
5345 filter_test_teardown);
5346 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes/vroot",
5347 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5348 filter_test_setup_empty,
5349 empty_vroot_show_multiple_nodes,
5350 filter_test_teardown);
5353 g_test_add ("/TreeModelFilter/unfiltered/hide-single",
5355 filter_test_setup_unfiltered,
5356 unfiltered_hide_single,
5357 filter_test_teardown);
5358 g_test_add ("/TreeModelFilter/unfiltered/hide-single/root-expanded",
5360 filter_test_setup_unfiltered_root_expanded,
5361 unfiltered_hide_single_root_expanded,
5362 filter_test_teardown);
5363 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child",
5365 filter_test_setup_unfiltered,
5366 unfiltered_hide_single_child,
5367 filter_test_teardown);
5368 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/root-expanded",
5370 filter_test_setup_unfiltered_root_expanded,
5371 unfiltered_hide_single_child_root_expanded,
5372 filter_test_teardown);
5373 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level",
5375 filter_test_setup_unfiltered,
5376 unfiltered_hide_single_multi_level,
5377 filter_test_teardown);
5378 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/root-expanded",
5380 filter_test_setup_unfiltered_root_expanded,
5381 unfiltered_hide_single_multi_level_root_expanded,
5382 filter_test_teardown);
5384 g_test_add ("/TreeModelFilter/unfiltered/hide-single/vroot",
5385 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5386 filter_test_setup_unfiltered,
5387 unfiltered_vroot_hide_single,
5388 filter_test_teardown);
5389 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot",
5390 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5391 filter_test_setup_unfiltered,
5392 unfiltered_vroot_hide_single_child,
5393 filter_test_teardown);
5394 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot/root-expanded",
5395 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5396 filter_test_setup_unfiltered_root_expanded,
5397 unfiltered_vroot_hide_single_child_root_expanded,
5398 filter_test_teardown);
5399 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot",
5400 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5401 filter_test_setup_unfiltered,
5402 unfiltered_vroot_hide_single_multi_level,
5403 filter_test_teardown);
5404 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot/root-expanded",
5405 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5406 filter_test_setup_unfiltered_root_expanded,
5407 unfiltered_vroot_hide_single_multi_level_root_expanded,
5408 filter_test_teardown);
5412 g_test_add ("/TreeModelFilter/unfiltered/show-single",
5414 filter_test_setup_empty_unfiltered,
5415 unfiltered_show_single,
5416 filter_test_teardown);
5417 g_test_add ("/TreeModelFilter/unfiltered/show-single-child",
5419 filter_test_setup_empty_unfiltered,
5420 unfiltered_show_single_child,
5421 filter_test_teardown);
5422 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/root-expanded",
5424 filter_test_setup_empty_unfiltered_root_expanded,
5425 unfiltered_show_single_child_root_expanded,
5426 filter_test_teardown);
5427 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level",
5429 filter_test_setup_empty_unfiltered,
5430 unfiltered_show_single_multi_level,
5431 filter_test_teardown);
5432 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/root-expanded",
5434 filter_test_setup_empty_unfiltered_root_expanded,
5435 unfiltered_show_single_multi_level_root_expanded,
5436 filter_test_teardown);
5438 g_test_add ("/TreeModelFilter/unfiltered/show-single/vroot",
5439 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5440 filter_test_setup_empty_unfiltered,
5441 unfiltered_vroot_show_single,
5442 filter_test_teardown);
5443 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot",
5444 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5445 filter_test_setup_empty_unfiltered,
5446 unfiltered_vroot_show_single_child,
5447 filter_test_teardown);
5448 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot/root-expanded",
5449 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5450 filter_test_setup_empty_unfiltered_root_expanded,
5451 unfiltered_vroot_show_single_child_root_expanded,
5452 filter_test_teardown);
5453 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot",
5454 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5455 filter_test_setup_empty_unfiltered,
5456 unfiltered_vroot_show_single_multi_level,
5457 filter_test_teardown);
5458 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot/root-expanded",
5459 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5460 filter_test_setup_empty_unfiltered_root_expanded,
5461 unfiltered_vroot_show_single_multi_level_root_expanded,
5462 filter_test_teardown);
5465 g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/root-level",
5467 filter_test_setup_unfiltered,
5468 unfiltered_rows_reordered_root_level,
5469 filter_test_teardown);
5470 g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/child-level",
5472 filter_test_setup_unfiltered,
5473 unfiltered_rows_reordered_child_level,
5474 filter_test_teardown);
5476 g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/first-hidden",
5479 filtered_rows_reordered_root_level_first_hidden,
5480 filter_test_teardown);
5481 g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/middle-hidden",
5484 filtered_rows_reordered_root_level_middle_hidden,
5485 filter_test_teardown);
5486 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/first-hidden",
5489 filtered_rows_reordered_child_level_first_hidden,
5490 filter_test_teardown);
5491 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/middle-hidden",
5494 filtered_rows_reordered_child_level_middle_hidden,
5495 filter_test_teardown);
5496 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/4-hidden",
5499 filtered_rows_reordered_child_level_4_hidden,
5500 filter_test_teardown);
5501 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/all-hidden",
5504 filtered_rows_reordered_child_level_all_hidden,
5505 filter_test_teardown);
5507 /* Inserts in child models after creation of filter model */
5508 g_test_add_func ("/TreeModelFilter/insert/before",
5510 g_test_add_func ("/TreeModelFilter/insert/child",
5513 /* Removals from child model after creating of filter model */
5514 g_test_add_func ("/TreeModelFilter/remove/node",
5516 g_test_add_func ("/TreeModelFilter/remove/node-vroot",
5518 g_test_add_func ("/TreeModelFilter/remove/vroot-ancestor",
5519 remove_vroot_ancestor);
5521 /* Reference counting */
5522 g_test_add_func ("/TreeModelFilter/ref-count/single-level",
5523 ref_count_single_level);
5524 g_test_add_func ("/TreeModelFilter/ref-count/two-levels",
5525 ref_count_two_levels);
5526 g_test_add_func ("/TreeModelFilter/ref-count/three-levels",
5527 ref_count_three_levels);
5528 g_test_add_func ("/TreeModelFilter/ref-count/delete-row",
5529 ref_count_delete_row);
5530 g_test_add_func ("/TreeModelFilter/ref-count/cleanup",
5532 g_test_add_func ("/TreeModelFilter/ref-count/row-ref",
5535 g_test_add_func ("/TreeModelFilter/specific/path-dependent-filter",
5536 specific_path_dependent_filter);
5537 g_test_add_func ("/TreeModelFilter/specific/append-after-collapse",
5538 specific_append_after_collapse);
5539 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-node",
5540 specific_sort_filter_remove_node);
5541 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-root",
5542 specific_sort_filter_remove_root);
5543 g_test_add_func ("/TreeModelFilter/specific/root-mixed-visibility",
5544 specific_root_mixed_visibility);
5545 g_test_add_func ("/TreeModelFilter/specific/has-child-filter",
5546 specific_has_child_filter);
5547 g_test_add_func ("/TreeModelFilter/specific/has-child-filter-on-sort-model",
5548 specific_has_child_filter_on_sort_model);
5549 g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter",
5550 specific_at_least_2_children_filter);
5551 g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter-on-sort-model",
5552 specific_at_least_2_children_filter_on_sort_model);
5553 g_test_add_func ("/TreeModelFilter/specific/root-has-child-filter",
5554 specific_root_has_child_filter);
5555 g_test_add_func ("/TreeModelFilter/specific/filter-add-child",
5556 specific_filter_add_child);
5557 g_test_add_func ("/TreeModelFilter/specific/list-store-clear",
5558 specific_list_store_clear);
5559 g_test_add_func ("/TreeModelFilter/specific/sort-ref-leaf-and-remove-ancestor",
5560 specific_sort_ref_leaf_and_remove_ancestor);
5561 g_test_add_func ("/TreeModelFilter/specific/ref-leaf-and-remove-ancestor",
5562 specific_ref_leaf_and_remove_ancestor);
5563 g_test_add_func ("/TreeModelFilter/specific/virtual-ref-leaf-and-remove-ancestor",
5564 specific_virtual_ref_leaf_and_remove_ancestor);
5566 g_test_add_func ("/TreeModelFilter/specific/bug-301558",
5567 specific_bug_301558);
5568 g_test_add_func ("/TreeModelFilter/specific/bug-311955",
5569 specific_bug_311955);
5570 g_test_add_func ("/TreeModelFilter/specific/bug-311955-clean",
5571 specific_bug_311955_clean);
5572 g_test_add_func ("/TreeModelFilter/specific/bug-346800",
5573 specific_bug_346800);
5574 g_test_add_func ("/TreeModelFilter/specific/bug-464173",
5575 specific_bug_464173);
5576 g_test_add_func ("/TreeModelFilter/specific/bug-540201",
5577 specific_bug_540201);
5578 g_test_add_func ("/TreeModelFilter/specific/bug-549287",
5579 specific_bug_549287);
5580 g_test_add_func ("/TreeModelFilter/specific/bug-621076",
5581 specific_bug_621076);