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);
3443 ref_count_transfer_root_level_insert (void)
3445 GtkTreeIter grandparent1, grandparent2, grandparent3;
3446 GtkTreeIter new_node;
3447 GtkTreeModel *model;
3448 GtkTreeModelRefCount *ref_model;
3449 GtkTreeModel *filter_model;
3450 GtkWidget *tree_view;
3452 model = gtk_tree_model_ref_count_new ();
3453 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3460 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3461 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3462 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
3464 filter_model = gtk_tree_model_filter_new (model, NULL);
3465 tree_view = gtk_tree_view_new_with_model (filter_model);
3467 assert_node_ref_count (ref_model, &grandparent1, 2);
3468 assert_node_ref_count (ref_model, &grandparent2, 1);
3469 assert_node_ref_count (ref_model, &grandparent3, 1);
3471 gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
3473 assert_node_ref_count (ref_model, &new_node, 2);
3474 assert_node_ref_count (ref_model, &grandparent1, 1);
3475 assert_node_ref_count (ref_model, &grandparent2, 1);
3476 assert_node_ref_count (ref_model, &grandparent3, 1);
3478 gtk_widget_destroy (tree_view);
3479 g_object_unref (filter_model);
3480 g_object_unref (ref_model);
3484 ref_count_transfer_root_level_reordered (void)
3486 GtkTreeIter grandparent1, grandparent2, grandparent3;
3487 GtkTreeModel *model;
3488 GtkTreeModelRefCount *ref_model;
3489 GtkTreeModel *filter_model;
3490 GtkWidget *tree_view;
3492 model = gtk_tree_model_ref_count_new ();
3493 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3500 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3501 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3502 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
3504 filter_model = gtk_tree_model_filter_new (model, NULL);
3505 tree_view = gtk_tree_view_new_with_model (filter_model);
3507 assert_node_ref_count (ref_model, &grandparent1, 2);
3508 assert_node_ref_count (ref_model, &grandparent2, 1);
3509 assert_node_ref_count (ref_model, &grandparent3, 1);
3511 /* gtk_tree_store_move() will emit rows-reordered */
3512 gtk_tree_store_move_after (GTK_TREE_STORE (model),
3513 &grandparent1, &grandparent3);
3515 assert_node_ref_count (ref_model, &grandparent2, 2);
3516 assert_node_ref_count (ref_model, &grandparent3, 1);
3517 assert_node_ref_count (ref_model, &grandparent1, 1);
3519 gtk_widget_destroy (tree_view);
3520 g_object_unref (filter_model);
3521 g_object_unref (ref_model);
3525 ref_count_transfer_child_level_insert (void)
3527 GtkTreeIter grandparent1;
3528 GtkTreeIter parent1, parent2, parent3;
3529 GtkTreeIter new_node;
3530 GtkTreeModel *model;
3531 GtkTreeModelRefCount *ref_model;
3532 GtkTreeModel *filter_model;
3533 GtkWidget *tree_view;
3535 model = gtk_tree_model_ref_count_new ();
3536 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3544 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3545 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
3546 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
3547 gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
3549 filter_model = gtk_tree_model_filter_new (model, NULL);
3550 tree_view = gtk_tree_view_new_with_model (filter_model);
3552 assert_node_ref_count (ref_model, &grandparent1, 3);
3553 assert_node_ref_count (ref_model, &parent1, 1);
3554 assert_node_ref_count (ref_model, &parent2, 0);
3555 assert_node_ref_count (ref_model, &parent3, 0);
3557 gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &grandparent1);
3559 assert_node_ref_count (ref_model, &grandparent1, 3);
3560 assert_node_ref_count (ref_model, &new_node, 1);
3561 assert_node_ref_count (ref_model, &parent1, 0);
3562 assert_node_ref_count (ref_model, &parent2, 0);
3563 assert_node_ref_count (ref_model, &parent3, 0);
3565 gtk_widget_destroy (tree_view);
3566 g_object_unref (filter_model);
3567 g_object_unref (ref_model);
3571 ref_count_transfer_child_level_reordered (void)
3573 GtkTreeIter grandparent1;
3574 GtkTreeIter parent1, parent2, parent3;
3575 GtkTreeModel *model;
3576 GtkTreeModelRefCount *ref_model;
3577 GtkTreeModel *filter_model;
3578 GtkWidget *tree_view;
3580 model = gtk_tree_model_ref_count_new ();
3581 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3589 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3590 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
3591 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
3592 gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
3594 filter_model = gtk_tree_model_filter_new (model, NULL);
3595 tree_view = gtk_tree_view_new_with_model (filter_model);
3597 assert_node_ref_count (ref_model, &grandparent1, 3);
3598 assert_node_ref_count (ref_model, &parent1, 1);
3599 assert_node_ref_count (ref_model, &parent2, 0);
3600 assert_node_ref_count (ref_model, &parent3, 0);
3602 /* gtk_tree_store_move() will emit rows-reordered */
3603 gtk_tree_store_move_after (GTK_TREE_STORE (model),
3604 &parent1, &parent3);
3606 assert_node_ref_count (ref_model, &grandparent1, 3);
3607 assert_node_ref_count (ref_model, &parent2, 1);
3608 assert_node_ref_count (ref_model, &parent3, 0);
3609 assert_node_ref_count (ref_model, &parent1, 0);
3611 gtk_widget_destroy (tree_view);
3612 g_object_unref (filter_model);
3613 g_object_unref (ref_model);
3618 specific_path_dependent_filter_func (GtkTreeModel *model,
3624 path = gtk_tree_model_get_path (model, iter);
3625 if (gtk_tree_path_get_indices (path)[0] < 4)
3632 specific_path_dependent_filter (void)
3638 GtkTreeModel *filter;
3640 list = gtk_list_store_new (1, G_TYPE_INT);
3641 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
3642 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
3643 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
3644 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
3645 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
3646 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
3647 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
3648 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
3650 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
3651 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
3652 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3653 specific_path_dependent_filter_func,
3656 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
3657 GTK_SORT_DESCENDING);
3659 for (i = 0; i < 4; i++)
3661 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
3663 gtk_list_store_remove (list, &iter);
3665 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
3667 gtk_list_store_remove (list, &iter);
3670 g_object_unref (filter);
3671 g_object_unref (sort);
3672 g_object_unref (list);
3677 specific_append_after_collapse_visible_func (GtkTreeModel *model,
3682 gboolean hide_negative_numbers;
3684 gtk_tree_model_get (model, iter, 1, &number, -1);
3685 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
3687 return (number >= 0 || !hide_negative_numbers);
3691 specific_append_after_collapse (void)
3693 /* This test is based on one of the test cases I found in my
3694 * old test cases directory. I unfortunately do not have a record
3695 * from who this test case originated. -Kris.
3699 * - Show tree, expand, collapse.
3704 GtkTreeIter child_iter;
3705 GtkTreeIter child_iter2;
3706 GtkTreePath *append_path;
3707 GtkTreeStore *store;
3708 GtkTreeModel *filter;
3712 GtkWidget *tree_view;
3714 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
3716 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
3717 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
3718 GINT_TO_POINTER (FALSE));
3719 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3720 specific_append_after_collapse_visible_func,
3723 sort = gtk_tree_model_sort_new_with_model (filter);
3725 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3726 tree_view = gtk_tree_view_new_with_model (sort);
3727 gtk_container_add (GTK_CONTAINER (window), tree_view);
3728 gtk_widget_realize (tree_view);
3730 while (gtk_events_pending ())
3731 gtk_main_iteration ();
3733 gtk_tree_store_prepend (store, &iter, NULL);
3734 gtk_tree_store_set (store, &iter,
3735 0, "hallo", 1, 1, -1);
3737 gtk_tree_store_append (store, &child_iter, &iter);
3738 gtk_tree_store_set (store, &child_iter,
3739 0, "toemaar", 1, 1, -1);
3741 gtk_tree_store_append (store, &child_iter2, &child_iter);
3742 gtk_tree_store_set (store, &child_iter2,
3743 0, "very deep", 1, 1, -1);
3745 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
3747 gtk_tree_store_append (store, &child_iter, &iter);
3748 gtk_tree_store_set (store, &child_iter,
3749 0, "sja", 1, 1, -1);
3751 gtk_tree_store_append (store, &child_iter, &iter);
3752 gtk_tree_store_set (store, &child_iter,
3753 0, "some word", 1, -1, -1);
3755 /* Expand and collapse the tree */
3756 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3757 while (gtk_events_pending ())
3758 gtk_main_iteration ();
3760 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
3761 while (gtk_events_pending ())
3762 gtk_main_iteration ();
3764 /* Add another it */
3765 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
3766 GINT_TO_POINTER (TRUE));
3768 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
3770 gtk_tree_store_append (store, &child_iter, &iter);
3771 gtk_tree_store_set (store, &child_iter,
3772 0, "new new new !!", 1, 1, -1);
3774 gtk_tree_path_free (append_path);
3777 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3778 while (gtk_events_pending ())
3779 gtk_main_iteration ();
3784 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
3793 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
3799 /* Do reference the model */
3800 gtk_tree_model_get (model, iter, 0, &item, -1);
3807 specific_sort_filter_remove_node (void)
3809 /* This test is based on one of the test cases I found in my
3810 * old test cases directory. I unfortunately do not have a record
3811 * from who this test case originated. -Kris.
3814 * - Create tree store, sort, filter models. The sort model has
3815 * a default sort func that is enabled, filter model a visible func
3816 * that defaults to returning FALSE.
3817 * - Remove a node from the tree store.
3821 GtkTreeStore *store;
3822 GtkTreeModel *filter;
3826 GtkWidget *tree_view;
3828 store = gtk_tree_store_new (1, G_TYPE_STRING);
3829 gtk_tree_store_append (store, &iter, NULL);
3830 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
3832 gtk_tree_store_append (store, &iter, NULL);
3833 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
3835 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
3836 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
3837 specific_sort_filter_remove_node_compare_func, NULL, NULL);
3839 filter = gtk_tree_model_filter_new (sort, NULL);
3840 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3841 specific_sort_filter_remove_node_visible_func,
3845 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3846 tree_view = gtk_tree_view_new_with_model (filter);
3847 gtk_container_add (GTK_CONTAINER (window), tree_view);
3848 gtk_widget_realize (tree_view);
3850 while (gtk_events_pending ())
3851 gtk_main_iteration ();
3854 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
3855 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
3856 gtk_tree_store_remove (store, &iter);
3858 while (gtk_events_pending ())
3859 gtk_main_iteration ();
3864 specific_sort_filter_remove_root (void)
3866 /* This test is based on one of the test cases I found in my
3867 * old test cases directory. I unfortunately do not have a record
3868 * from who this test case originated. -Kris.
3871 GtkTreeModel *model, *sort, *filter;
3872 GtkTreeIter root, mid, leaf;
3875 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
3876 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
3877 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
3878 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
3880 path = gtk_tree_model_get_path (model, &mid);
3882 sort = gtk_tree_model_sort_new_with_model (model);
3883 filter = gtk_tree_model_filter_new (sort, path);
3885 gtk_tree_path_free (path);
3887 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
3889 g_object_unref (filter);
3890 g_object_unref (sort);
3891 g_object_unref (model);
3896 specific_root_mixed_visibility (void)
3899 GtkTreeModel *filter;
3900 /* A bit nasty, apologies */
3903 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3905 for (i = 0; i < LEVEL_LENGTH; i++)
3909 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
3911 create_tree_store_set_values (fixture.store, &iter, TRUE);
3913 create_tree_store_set_values (fixture.store, &iter, FALSE);
3916 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3917 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3918 fixture.monitor = NULL;
3920 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
3922 /* In order to trigger the potential bug, we should not access
3923 * the filter model here (so don't call the check functions).
3926 /* Change visibility of an odd row to TRUE */
3927 set_path_visibility (&fixture, "3", TRUE);
3928 check_filter_model (&fixture);
3929 check_level_length (fixture.filter, NULL, 4);
3935 specific_has_child_filter_filter_func (GtkTreeModel *model,
3939 return gtk_tree_model_iter_has_child (model, iter);
3943 specific_has_child_filter (void)
3945 GtkTreeModel *filter;
3946 GtkTreeIter iter, root;
3947 FilterTest fixture; /* This is not how it should be done */
3948 GtkWidget *tree_view;
3950 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3951 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3952 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3953 fixture.monitor = signal_monitor_new (filter);
3955 tree_view = gtk_tree_view_new_with_model (filter);
3957 /* We will filter on parent state using a filter function. We will
3958 * manually keep the boolean column in sync, so that we can use
3959 * check_filter_model() to check the consistency of the model.
3961 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3962 * to be able to check the structure here. We keep the calls to
3963 * check_filter_model() commented out until then.
3965 gtk_tree_model_filter_set_visible_func (fixture.filter,
3966 specific_has_child_filter_filter_func,
3969 /* The first node will be initially invisible: no signals */
3970 gtk_tree_store_append (fixture.store, &root, NULL);
3971 create_tree_store_set_values (fixture.store, &root, FALSE);
3973 /* check_filter_model (&fixture); */
3974 check_level_length (fixture.filter, NULL, 0);
3975 signal_monitor_assert_is_empty (fixture.monitor);
3977 /* Insert a child node. This will cause the parent to become visible
3978 * since there is a child now.
3980 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3981 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3982 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3984 gtk_tree_store_append (fixture.store, &iter, &root);
3985 create_tree_store_set_values (fixture.store, &iter, TRUE);
3987 /* Parent must now be visible. Do the level length check first,
3988 * to avoid modifying the child model triggering a row-changed to
3991 check_level_length (fixture.filter, NULL, 1);
3992 check_level_length (fixture.filter, "0", 0);
3993 signal_monitor_assert_is_empty (fixture.monitor);
3995 /* This should propagate row-changed */
3996 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3997 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3999 set_path_visibility (&fixture, "0", TRUE);
4000 /* check_filter_model (&fixture); */
4001 signal_monitor_assert_is_empty (fixture.monitor);
4003 /* New root node, no child, so no signal */
4004 gtk_tree_store_append (fixture.store, &root, NULL);
4005 check_level_length (fixture.filter, NULL, 1);
4006 signal_monitor_assert_is_empty (fixture.monitor);
4008 /* When the child comes in, this node will become visible */
4009 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
4010 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4011 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4012 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
4013 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4015 gtk_tree_store_append (fixture.store, &iter, &root);
4016 check_level_length (fixture.filter, NULL, 2);
4017 check_level_length (fixture.filter, "1", 0);
4019 create_tree_store_set_values (fixture.store, &root, TRUE);
4020 create_tree_store_set_values (fixture.store, &iter, TRUE);
4022 /* check_filter_model (&fixture); */
4023 signal_monitor_assert_is_empty (fixture.monitor);
4025 /* Add another child for 1 */
4026 gtk_tree_store_append (fixture.store, &iter, &root);
4027 create_tree_store_set_values (fixture.store, &iter, TRUE);
4028 check_level_length (fixture.filter, NULL, 2);
4029 check_level_length (fixture.filter, "0", 0);
4030 check_level_length (fixture.filter, "1", 0);
4031 signal_monitor_assert_is_empty (fixture.monitor);
4033 /* Now remove one of the remaining child rows */
4034 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4036 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4038 gtk_tree_store_remove (fixture.store, &iter);
4040 check_level_length (fixture.filter, NULL, 1);
4041 check_level_length (fixture.filter, "0", 0);
4043 set_path_visibility (&fixture, "0", FALSE);
4044 /* check_filter_model (&fixture); */
4045 signal_monitor_assert_is_empty (fixture.monitor);
4050 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
4057 path = gtk_tree_model_get_path (model, iter);
4058 depth = gtk_tree_path_get_depth (path);
4059 gtk_tree_path_free (path);
4064 return gtk_tree_model_iter_has_child (model, iter);
4068 specific_root_has_child_filter (void)
4070 GtkTreeModel *filter;
4071 GtkTreeIter iter, root;
4072 FilterTest fixture; /* This is not how it should be done ... */
4073 GtkWidget *tree_view;
4075 /* This is a variation on the above test case, specific has-child-filter,
4076 * herein the has-child check for visibility only applies to root level
4077 * nodes. In this test, children are always visible because we
4078 * only filter based on the "has child" criterion.
4081 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4082 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
4083 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4084 fixture.monitor = signal_monitor_new (filter);
4086 tree_view = gtk_tree_view_new_with_model (filter);
4088 /* We will filter on parent state using a filter function. We will
4089 * manually keep the boolean column in sync, so that we can use
4090 * check_filter_model() to check the consistency of the model.
4092 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
4093 * to be able to check the structure here. We keep the calls to
4094 * check_filter_model() commented out until then.
4096 gtk_tree_model_filter_set_visible_func (fixture.filter,
4097 specific_root_has_child_filter_filter_func,
4100 /* Add a first node, this will be invisible initially, so no signal
4101 * should be emitted.
4103 gtk_tree_store_append (fixture.store, &root, NULL);
4104 create_tree_store_set_values (fixture.store, &root, FALSE);
4106 signal_monitor_assert_is_empty (fixture.monitor);
4107 /* check_filter_model (&fixture); */
4108 check_level_length (fixture.filter, NULL, 0);
4110 /* Add a child node. This will cause the parent to become visible,
4111 * so we expect row-inserted signals for both.
4113 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4114 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4115 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4117 gtk_tree_store_append (fixture.store, &iter, &root);
4118 signal_monitor_assert_is_empty (fixture.monitor);
4120 check_level_length (fixture.filter, NULL, 1);
4121 check_level_length (fixture.filter, "0", 1);
4123 /* Modify the content of iter, no signals because the parent is not
4126 create_tree_store_set_values (fixture.store, &iter, TRUE);
4127 signal_monitor_assert_is_empty (fixture.monitor);
4129 /* Parent must now be visible. Do the level length check first,
4130 * to avoid modifying the child model triggering a row-changed to
4133 check_level_length (fixture.filter, NULL, 1);
4134 check_level_length (fixture.filter, "0", 1);
4137 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4138 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4140 set_path_visibility (&fixture, "0", TRUE);
4141 /* check_filter_model (&fixture); */
4143 signal_monitor_assert_is_empty (fixture.monitor);
4145 /* Insert another node in the root level. Initially invisible, so
4146 * not expecting any signal.
4148 gtk_tree_store_append (fixture.store, &root, NULL);
4149 check_level_length (fixture.filter, NULL, 1);
4151 signal_monitor_assert_is_empty (fixture.monitor);
4153 /* Adding a child node which also makes parent at path 1 visible. */
4154 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
4155 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4156 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4158 gtk_tree_store_append (fixture.store, &iter, &root);
4159 check_level_length (fixture.filter, NULL, 2);
4160 check_level_length (fixture.filter, "1", 1);
4162 signal_monitor_assert_is_empty (fixture.monitor);
4164 /* Check if row-changed is propagated */
4165 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
4166 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4168 create_tree_store_set_values (fixture.store, &root, TRUE);
4169 create_tree_store_set_values (fixture.store, &iter, TRUE);
4170 /* check_filter_model (&fixture); */
4171 signal_monitor_assert_is_empty (fixture.monitor);
4173 /* Insert another child under node 1 */
4174 gtk_tree_store_append (fixture.store, &iter, &root);
4175 create_tree_store_set_values (fixture.store, &iter, TRUE);
4176 check_level_length (fixture.filter, NULL, 2);
4177 check_level_length (fixture.filter, "0", 1);
4178 check_level_length (fixture.filter, "1", 2);
4179 signal_monitor_assert_is_empty (fixture.monitor);
4181 /* Set a child node to invisible. This should not yield any
4182 * change, because filtering is only done on whether the root
4183 * node has a child, which it still has.
4185 set_path_visibility (&fixture, "0:0", FALSE);
4186 signal_monitor_assert_is_empty (fixture.monitor);
4188 /* Now remove one of the remaining child rows */
4189 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4190 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4192 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4194 gtk_tree_store_remove (fixture.store, &iter);
4196 check_level_length (fixture.filter, NULL, 1);
4197 check_level_length (fixture.filter, "0", 2);
4198 signal_monitor_assert_is_empty (fixture.monitor);
4200 /* Set visibility of 0 to FALSE, no-op for filter model since
4201 * the child 0:0 is already gone
4203 set_path_visibility (&fixture, "0", FALSE);
4204 /* check_filter_model (&fixture); */
4205 signal_monitor_assert_is_empty (fixture.monitor);
4209 specific_has_child_filter_on_sort_model (void)
4211 GtkTreeModel *filter;
4212 GtkTreeModel *sort_model;
4213 GtkTreeIter iter, root;
4214 FilterTest fixture; /* This is not how it should be done */
4215 GtkWidget *tree_view;
4217 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4218 sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
4219 filter = gtk_tree_model_filter_new (sort_model, NULL);
4220 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4221 fixture.monitor = signal_monitor_new (filter);
4223 tree_view = gtk_tree_view_new_with_model (filter);
4225 /* We will filter on parent state using a filter function. We will
4226 * manually keep the boolean column in sync, so that we can use
4227 * check_filter_model() to check the consistency of the model.
4229 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
4230 * to be able to check the structure here. We keep the calls to
4231 * check_filter_model() commented out until then.
4233 gtk_tree_model_filter_set_visible_func (fixture.filter,
4234 specific_has_child_filter_filter_func,
4237 /* The first node will be initially invisible: no signals */
4238 gtk_tree_store_append (fixture.store, &root, NULL);
4239 create_tree_store_set_values (fixture.store, &root, FALSE);
4241 /* check_filter_model (&fixture); */
4242 check_level_length (fixture.filter, NULL, 0);
4243 signal_monitor_assert_is_empty (fixture.monitor);
4245 /* Insert a child node. This will cause the parent to become visible
4246 * since there is a child now.
4248 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4249 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4251 gtk_tree_store_append (fixture.store, &iter, &root);
4252 create_tree_store_set_values (fixture.store, &iter, TRUE);
4254 /* Parent must now be visible. Do the level length check first,
4255 * to avoid modifying the child model triggering a row-changed to
4258 check_level_length (fixture.filter, NULL, 1);
4259 check_level_length (fixture.filter, "0", 0);
4260 signal_monitor_assert_is_empty (fixture.monitor);
4262 /* This should propagate row-changed */
4263 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4264 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4266 set_path_visibility (&fixture, "0", TRUE);
4267 /* check_filter_model (&fixture); */
4268 signal_monitor_assert_is_empty (fixture.monitor);
4270 /* New root node, no child, so no signal */
4271 gtk_tree_store_append (fixture.store, &root, NULL);
4272 check_level_length (fixture.filter, NULL, 1);
4273 signal_monitor_assert_is_empty (fixture.monitor);
4275 /* When the child comes in, this node will become visible */
4276 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
4277 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4278 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
4279 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4281 gtk_tree_store_append (fixture.store, &iter, &root);
4282 check_level_length (fixture.filter, NULL, 2);
4283 check_level_length (fixture.filter, "1", 0);
4285 create_tree_store_set_values (fixture.store, &root, TRUE);
4286 create_tree_store_set_values (fixture.store, &iter, TRUE);
4288 /* check_filter_model (&fixture); */
4289 signal_monitor_assert_is_empty (fixture.monitor);
4291 /* Add another child for 1 */
4292 gtk_tree_store_append (fixture.store, &iter, &root);
4293 create_tree_store_set_values (fixture.store, &iter, TRUE);
4294 check_level_length (fixture.filter, NULL, 2);
4295 check_level_length (fixture.filter, "0", 0);
4296 check_level_length (fixture.filter, "1", 0);
4297 signal_monitor_assert_is_empty (fixture.monitor);
4299 /* Now remove one of the remaining child rows */
4300 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4302 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4304 gtk_tree_store_remove (fixture.store, &iter);
4306 check_level_length (fixture.filter, NULL, 1);
4307 check_level_length (fixture.filter, "0", 0);
4309 set_path_visibility (&fixture, "0", FALSE);
4310 /* check_filter_model (&fixture); */
4311 signal_monitor_assert_is_empty (fixture.monitor);
4315 specific_at_least_2_children_filter_filter_func (GtkTreeModel *model,
4319 return gtk_tree_model_iter_n_children (model, iter) >= 2;
4323 specific_at_least_2_children_filter (void)
4325 GtkTreeModel *filter;
4326 GtkTreeIter iter, root;
4327 FilterTest fixture; /* This is not how it should be done */
4328 GtkWidget *tree_view;
4330 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4331 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
4332 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4333 fixture.monitor = signal_monitor_new (filter);
4335 tree_view = gtk_tree_view_new_with_model (filter);
4337 gtk_tree_model_filter_set_visible_func (fixture.filter,
4338 specific_at_least_2_children_filter_filter_func,
4341 /* The first node will be initially invisible: no signals */
4342 gtk_tree_store_append (fixture.store, &root, NULL);
4343 create_tree_store_set_values (fixture.store, &root, FALSE);
4345 /* check_filter_model (&fixture); */
4346 check_level_length (fixture.filter, NULL, 0);
4347 signal_monitor_assert_is_empty (fixture.monitor);
4349 /* Insert a child node. Nothing should happen.
4351 gtk_tree_store_append (fixture.store, &iter, &root);
4352 create_tree_store_set_values (fixture.store, &iter, TRUE);
4354 check_level_length (fixture.filter, NULL, 0);
4355 signal_monitor_assert_is_empty (fixture.monitor);
4357 /* Insert a second child node. This will cause the parent to become
4360 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4361 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4363 gtk_tree_store_append (fixture.store, &iter, &root);
4364 create_tree_store_set_values (fixture.store, &iter, TRUE);
4366 /* Parent must now be visible. Do the level length check first,
4367 * to avoid modifying the child model triggering a row-changed to
4370 check_level_length (fixture.filter, NULL, 1);
4371 check_level_length (fixture.filter, "0", 0);
4372 signal_monitor_assert_is_empty (fixture.monitor);
4374 /* This should propagate row-changed */
4375 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4376 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4378 set_path_visibility (&fixture, "0", TRUE);
4379 /* check_filter_model (&fixture); */
4380 signal_monitor_assert_is_empty (fixture.monitor);
4382 /* New root node, no child, so no signal */
4383 gtk_tree_store_append (fixture.store, &root, NULL);
4384 check_level_length (fixture.filter, NULL, 1);
4385 signal_monitor_assert_is_empty (fixture.monitor);
4387 /* First child, no signal, no change */
4388 gtk_tree_store_append (fixture.store, &iter, &root);
4389 check_level_length (fixture.filter, NULL, 1);
4390 signal_monitor_assert_is_empty (fixture.monitor);
4392 /* When the second child comes in, this node will become visible */
4393 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
4394 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4395 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
4396 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4398 gtk_tree_store_append (fixture.store, &iter, &root);
4399 check_level_length (fixture.filter, NULL, 2);
4400 check_level_length (fixture.filter, "1", 0);
4402 create_tree_store_set_values (fixture.store, &root, TRUE);
4403 create_tree_store_set_values (fixture.store, &iter, TRUE);
4405 /* check_filter_model (&fixture); */
4406 signal_monitor_assert_is_empty (fixture.monitor);
4408 /* Add another child for 1 */
4409 gtk_tree_store_append (fixture.store, &iter, &root);
4410 create_tree_store_set_values (fixture.store, &iter, TRUE);
4411 check_level_length (fixture.filter, NULL, 2);
4412 check_level_length (fixture.filter, "0", 0);
4413 check_level_length (fixture.filter, "1", 0);
4414 signal_monitor_assert_is_empty (fixture.monitor);
4416 /* Now remove one of the remaining child rows */
4417 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4419 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4421 gtk_tree_store_remove (fixture.store, &iter);
4423 check_level_length (fixture.filter, NULL, 1);
4424 check_level_length (fixture.filter, "0", 0);
4426 set_path_visibility (&fixture, "0", FALSE);
4427 /* check_filter_model (&fixture); */
4428 signal_monitor_assert_is_empty (fixture.monitor);
4432 specific_at_least_2_children_filter_on_sort_model (void)
4434 GtkTreeModel *filter;
4435 GtkTreeModel *sort_model;
4436 GtkTreeIter iter, root;
4437 FilterTest fixture; /* This is not how it should be done */
4438 GtkWidget *tree_view;
4440 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4441 sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
4442 filter = gtk_tree_model_filter_new (sort_model, NULL);
4443 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4444 fixture.monitor = signal_monitor_new (filter);
4446 tree_view = gtk_tree_view_new_with_model (filter);
4448 gtk_tree_model_filter_set_visible_func (fixture.filter,
4449 specific_at_least_2_children_filter_filter_func,
4452 /* The first node will be initially invisible: no signals */
4453 gtk_tree_store_append (fixture.store, &root, NULL);
4454 create_tree_store_set_values (fixture.store, &root, FALSE);
4456 /* check_filter_model (&fixture); */
4457 check_level_length (fixture.filter, NULL, 0);
4458 signal_monitor_assert_is_empty (fixture.monitor);
4460 /* Insert a child node. Nothing should happen.
4462 gtk_tree_store_append (fixture.store, &iter, &root);
4463 create_tree_store_set_values (fixture.store, &iter, TRUE);
4465 check_level_length (fixture.filter, NULL, 0);
4466 signal_monitor_assert_is_empty (fixture.monitor);
4469 GtkTreePath *path = gtk_tree_path_new_from_indices (0, 0, -1);
4470 GtkTreeRowReference *ref;
4472 ref = gtk_tree_row_reference_new (sort_model, path);
4473 gtk_tree_path_free (path);
4476 /* Insert a second child node. This will cause the parent to become
4479 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4480 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4482 gtk_tree_store_append (fixture.store, &iter, &root);
4483 create_tree_store_set_values (fixture.store, &iter, TRUE);
4485 /* Parent must now be visible. Do the level length check first,
4486 * to avoid modifying the child model triggering a row-changed to
4489 check_level_length (fixture.filter, NULL, 1);
4490 check_level_length (fixture.filter, "0", 0);
4491 signal_monitor_assert_is_empty (fixture.monitor);
4493 /* This should propagate row-changed */
4494 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4495 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4497 set_path_visibility (&fixture, "0", TRUE);
4498 /* check_filter_model (&fixture); */
4499 signal_monitor_assert_is_empty (fixture.monitor);
4501 /* New root node, no child, so no signal */
4502 gtk_tree_store_append (fixture.store, &root, NULL);
4503 check_level_length (fixture.filter, NULL, 1);
4504 signal_monitor_assert_is_empty (fixture.monitor);
4509 specific_filter_add_child (void)
4511 /* This test is based on one of the test cases I found in my
4512 * old test cases directory. I unfortunately do not have a record
4513 * from who this test case originated. -Kris.
4517 GtkTreeIter iter_first;
4519 GtkTreeStore *store;
4520 GtkTreeModel *filter G_GNUC_UNUSED;
4522 store = gtk_tree_store_new (1, G_TYPE_STRING);
4524 gtk_tree_store_append (store, &iter_first, NULL);
4525 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
4527 gtk_tree_store_append (store, &iter, NULL);
4528 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4530 gtk_tree_store_append (store, &iter, NULL);
4531 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4533 gtk_tree_store_append (store, &iter, NULL);
4534 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4536 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4538 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4539 gtk_tree_store_append (store, &child, &iter_first);
4540 gtk_tree_store_set (store, &child, 0, "Hello", -1);
4544 specific_list_store_clear (void)
4548 GtkTreeModel *filter;
4549 GtkWidget *view G_GNUC_UNUSED;
4551 list = gtk_list_store_new (1, G_TYPE_INT);
4552 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
4553 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
4554 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
4555 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
4556 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
4557 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
4558 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
4559 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
4561 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
4562 view = gtk_tree_view_new_with_model (filter);
4564 gtk_list_store_clear (list);
4568 specific_sort_ref_leaf_and_remove_ancestor (void)
4570 GtkTreeIter iter, child, child2, child3;
4574 GtkTreeRowReference *rowref;
4575 GtkWidget *view G_GNUC_UNUSED;
4577 tree = gtk_tree_store_new (1, G_TYPE_INT);
4578 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4579 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4580 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4581 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4583 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4584 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4585 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4587 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
4588 view = gtk_tree_view_new_with_model (sort);
4589 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4591 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4592 rowref = gtk_tree_row_reference_new (sort, path);
4593 gtk_tree_path_free (path);
4595 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4596 rowref = gtk_tree_row_reference_new (sort, path);
4597 gtk_tree_path_free (path);
4599 path = gtk_tree_path_new_from_indices (3, 0, -1);
4600 rowref = gtk_tree_row_reference_new (sort, path);
4601 gtk_tree_path_free (path);
4603 path = gtk_tree_path_new_from_indices (3, -1);
4604 rowref = gtk_tree_row_reference_new (sort, path);
4605 gtk_tree_path_free (path);
4607 /* Deleting a parent */
4608 path = gtk_tree_path_new_from_indices (3, 0, -1);
4609 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4610 gtk_tree_store_remove (tree, &iter);
4611 gtk_tree_path_free (path);
4613 gtk_tree_row_reference_free (rowref);
4617 specific_ref_leaf_and_remove_ancestor (void)
4619 GtkTreeIter iter, child, child2, child3;
4621 GtkTreeModel *filter;
4623 GtkTreeRowReference *rowref;
4624 GtkWidget *view G_GNUC_UNUSED;
4626 tree = gtk_tree_store_new (1, G_TYPE_INT);
4627 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4628 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4629 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4630 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4632 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4633 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4634 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4636 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), NULL);
4637 view = gtk_tree_view_new_with_model (filter);
4638 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4640 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4641 rowref = gtk_tree_row_reference_new (filter, path);
4642 gtk_tree_path_free (path);
4644 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4645 rowref = gtk_tree_row_reference_new (filter, path);
4646 gtk_tree_path_free (path);
4648 path = gtk_tree_path_new_from_indices (3, 0, -1);
4649 rowref = gtk_tree_row_reference_new (filter, path);
4650 gtk_tree_path_free (path);
4652 path = gtk_tree_path_new_from_indices (3, -1);
4653 rowref = gtk_tree_row_reference_new (filter, path);
4654 gtk_tree_path_free (path);
4656 /* Deleting a parent */
4657 path = gtk_tree_path_new_from_indices (3, 0, -1);
4658 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4659 gtk_tree_store_remove (tree, &iter);
4660 gtk_tree_path_free (path);
4662 gtk_tree_row_reference_free (rowref);
4666 specific_virtual_ref_leaf_and_remove_ancestor (void)
4668 GtkTreeIter iter, child, child2, child3;
4670 GtkTreeModel *filter;
4672 GtkTreeRowReference *rowref;
4673 GtkWidget *view G_GNUC_UNUSED;
4675 tree = gtk_tree_store_new (1, G_TYPE_INT);
4676 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4677 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4678 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4679 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4681 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4682 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4683 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4685 /* Set a virtual root of 3:0 */
4686 path = gtk_tree_path_new_from_indices (3, 0, -1);
4687 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
4688 gtk_tree_path_free (path);
4690 view = gtk_tree_view_new_with_model (filter);
4691 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4693 path = gtk_tree_path_new_from_indices (0, 0, -1);
4694 rowref = gtk_tree_row_reference_new (filter, path);
4695 gtk_tree_path_free (path);
4697 path = gtk_tree_path_new_from_indices (0, 0, -1);
4698 rowref = gtk_tree_row_reference_new (filter, path);
4699 gtk_tree_path_free (path);
4701 path = gtk_tree_path_new_from_indices (0, -1);
4702 rowref = gtk_tree_row_reference_new (filter, path);
4703 gtk_tree_path_free (path);
4705 /* Deleting the virtual root */
4706 path = gtk_tree_path_new_from_indices (3, 0, -1);
4707 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4708 gtk_tree_store_remove (tree, &iter);
4709 gtk_tree_path_free (path);
4711 gtk_tree_row_reference_free (rowref);
4716 specific_bug_301558_sort_func (GtkTreeModel *model,
4723 gtk_tree_model_get (model, a, 0, &i, -1);
4724 gtk_tree_model_get (model, b, 0, &j, -1);
4730 specific_bug_301558 (void)
4732 /* Test case for GNOME Bugzilla bug 301558 provided by
4736 GtkTreeModel *filter;
4738 GtkTreeIter root, iter, iter2;
4739 GtkWidget *view G_GNUC_UNUSED;
4743 g_test_bug ("301558");
4745 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
4746 gtk_tree_store_append (tree, &iter, NULL);
4747 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
4748 gtk_tree_store_append (tree, &iter2, &iter);
4749 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
4751 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
4752 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
4753 specific_bug_301558_sort_func,
4756 filter = gtk_tree_model_filter_new (sort, NULL);
4757 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
4759 view = gtk_tree_view_new_with_model (filter);
4761 while (gtk_events_pending ())
4762 gtk_main_iteration ();
4766 for (i = 0; i < 10; i++)
4768 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
4769 g_assert_not_reached ();
4773 gtk_tree_store_append (tree, &iter, &root);
4774 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
4779 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
4780 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
4782 gtk_tree_store_remove (tree, &iter);
4791 specific_bug_311955_filter_func (GtkTreeModel *model,
4797 gtk_tree_model_get (model, iter, 0, &value, -1);
4799 return (value != 0);
4803 specific_bug_311955 (void)
4805 /* This is a test case for GNOME Bugzilla bug 311955. It was written
4808 GtkTreeIter iter, child, root;
4809 GtkTreeStore *store;
4811 GtkTreeModel *filter;
4813 GtkWidget *window G_GNUC_UNUSED;
4814 GtkWidget *tree_view;
4819 g_test_bug ("311955");
4821 store = gtk_tree_store_new (1, G_TYPE_INT);
4823 gtk_tree_store_append (store, &root, NULL);
4824 gtk_tree_store_set (store, &root, 0, 33, -1);
4826 gtk_tree_store_append (store, &iter, &root);
4827 gtk_tree_store_set (store, &iter, 0, 50, -1);
4829 gtk_tree_store_append (store, &iter, NULL);
4830 gtk_tree_store_set (store, &iter, 0, 22, -1);
4832 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
4833 filter = gtk_tree_model_filter_new (sort, NULL);
4835 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4836 specific_bug_311955_filter_func,
4839 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4840 tree_view = gtk_tree_view_new_with_model (filter);
4841 g_object_unref (store);
4843 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
4845 while (gtk_events_pending ())
4846 gtk_main_iteration ();
4848 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
4849 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
4852 for (i = 0; i < 4; i++)
4854 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
4856 gtk_tree_store_append (store, &iter, &root);
4859 gtk_tree_store_set (store, &iter, 0, i, -1);
4863 gtk_tree_store_append (store, &child, &iter);
4864 gtk_tree_store_set (store, &child, 0, 10, -1);
4868 while (gtk_events_pending ())
4869 gtk_main_iteration ();
4871 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4872 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 1);
4874 /* Remove bottommost child from the tree. */
4875 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
4876 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
4878 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
4880 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
4881 gtk_tree_store_remove (store, &child);
4884 g_assert_not_reached ();
4886 path = gtk_tree_path_new_from_indices (0, 2, -1);
4887 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
4888 gtk_tree_path_free (path);
4890 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4891 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
4895 specific_bug_311955_clean (void)
4897 /* Cleaned up version of the test case for GNOME Bugzilla bug 311955,
4898 * which is easier to understand.
4900 GtkTreeIter iter, child, grandchild;
4901 GtkTreeStore *store;
4903 GtkTreeModel *filter;
4905 GtkWidget *tree_view;
4908 store = gtk_tree_store_new (1, G_TYPE_INT);
4910 gtk_tree_store_append (store, &iter, NULL);
4911 gtk_tree_store_set (store, &iter, 0, 1, -1);
4913 gtk_tree_store_append (store, &child, &iter);
4914 gtk_tree_store_set (store, &child, 0, 1, -1);
4916 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
4917 filter = gtk_tree_model_filter_new (sort, NULL);
4919 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4920 specific_bug_311955_filter_func,
4923 tree_view = gtk_tree_view_new_with_model (filter);
4924 g_object_unref (store);
4926 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
4928 while (gtk_events_pending ())
4929 gtk_main_iteration ();
4931 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
4932 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
4934 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
4936 gtk_tree_store_append (store, &child, &iter);
4937 gtk_tree_store_set (store, &child, 0, 0, -1);
4939 gtk_tree_store_append (store, &child, &iter);
4940 gtk_tree_store_set (store, &child, 0, 1, -1);
4942 gtk_tree_store_append (store, &child, &iter);
4943 gtk_tree_store_set (store, &child, 0, 1, -1);
4945 gtk_tree_store_append (store, &grandchild, &child);
4946 gtk_tree_store_set (store, &grandchild, 0, 1, -1);
4948 gtk_tree_store_append (store, &child, &iter);
4949 /* Don't set a value: assume 0 */
4951 /* Remove leaf node, check trigger row-has-child-toggled */
4952 path = gtk_tree_path_new_from_indices (0, 3, 0, -1);
4953 gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
4954 gtk_tree_path_free (path);
4955 gtk_tree_store_remove (store, &iter);
4957 path = gtk_tree_path_new_from_indices (0, 2, -1);
4958 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
4959 gtk_tree_path_free (path);
4961 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4962 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
4964 gtk_widget_destroy (tree_view);
4968 specific_bug_346800 (void)
4970 /* This is a test case for GNOME Bugzilla bug 346800. It was written
4971 * by Jonathan Matthew.
4974 GtkTreeIter node_iters[50];
4975 GtkTreeIter child_iters[50];
4976 GtkTreeModel *model;
4977 GtkTreeModelFilter *filter;
4978 GtkTreeStore *store;
4982 columns = g_new (GType, 2);
4983 columns[0] = G_TYPE_STRING;
4984 columns[1] = G_TYPE_BOOLEAN;
4985 store = gtk_tree_store_newv (2, columns);
4986 model = GTK_TREE_MODEL (store);
4988 g_test_bug ("346800");
4990 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
4991 gtk_tree_model_filter_set_visible_column (filter, 1);
4993 for (i=0; i<items; i++)
4995 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
4998 gtk_tree_store_append (store, &node_iters[i], NULL);
4999 gtk_tree_store_set (store, &node_iters[i],
5001 1, ((i%6) == 0) ? FALSE : TRUE,
5005 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
5006 gtk_tree_store_set (store, &child_iters[i],
5007 0, "something else",
5010 gtk_tree_model_filter_refilter (filter);
5014 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
5015 (i & 1) ? TRUE : FALSE, -1);
5016 gtk_tree_model_filter_refilter (filter);
5018 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
5019 (i & 1) ? FALSE: TRUE, -1);
5020 gtk_tree_model_filter_refilter (filter);
5026 specific_bug_464173_visible_func (GtkTreeModel *model,
5030 gboolean *visible = (gboolean *)data;
5036 specific_bug_464173 (void)
5038 /* Test case for GNOME Bugzilla bug 464173, test case written
5039 * by Andreas Koehler.
5041 GtkTreeStore *model;
5042 GtkTreeModelFilter *f_model;
5043 GtkTreeIter iter1, iter2;
5044 GtkWidget *view G_GNUC_UNUSED;
5045 gboolean visible = TRUE;
5047 g_test_bug ("464173");
5049 model = gtk_tree_store_new (1, G_TYPE_STRING);
5050 gtk_tree_store_append (model, &iter1, NULL);
5051 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
5052 gtk_tree_store_append (model, &iter2, &iter1);
5053 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
5055 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
5056 gtk_tree_model_filter_set_visible_func (f_model,
5057 specific_bug_464173_visible_func,
5060 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
5063 gtk_tree_model_filter_refilter (f_model);
5068 specific_bug_540201_filter_func (GtkTreeModel *model,
5072 gboolean has_children;
5074 has_children = gtk_tree_model_iter_has_child (model, iter);
5076 return has_children;
5080 specific_bug_540201 (void)
5082 /* Test case for GNOME Bugzilla bug 540201, steps provided by
5085 GtkTreeIter iter, root;
5086 GtkTreeStore *store;
5087 GtkTreeModel *filter;
5089 GtkWidget *tree_view G_GNUC_UNUSED;
5091 g_test_bug ("540201");
5093 store = gtk_tree_store_new (1, G_TYPE_INT);
5095 gtk_tree_store_append (store, &root, NULL);
5096 gtk_tree_store_set (store, &root, 0, 33, -1);
5098 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
5099 tree_view = gtk_tree_view_new_with_model (filter);
5101 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
5102 specific_bug_540201_filter_func,
5105 gtk_tree_store_append (store, &iter, &root);
5106 gtk_tree_store_set (store, &iter, 0, 50, -1);
5108 gtk_tree_store_append (store, &iter, &root);
5109 gtk_tree_store_set (store, &iter, 0, 22, -1);
5112 gtk_tree_store_append (store, &root, NULL);
5113 gtk_tree_store_set (store, &root, 0, 33, -1);
5115 gtk_tree_store_append (store, &iter, &root);
5116 gtk_tree_store_set (store, &iter, 0, 22, -1);
5121 specific_bug_549287_visible_func (GtkTreeModel *model,
5125 gboolean result = FALSE;
5127 result = gtk_tree_model_iter_has_child (model, iter);
5133 specific_bug_549287 (void)
5135 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
5138 GtkTreeStore *store;
5139 GtkTreeModel *filtered;
5140 GtkWidget *view G_GNUC_UNUSED;
5142 GtkTreeIter *swap, *parent, *child;
5144 g_test_bug ("529287");
5146 store = gtk_tree_store_new (1, G_TYPE_STRING);
5147 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
5148 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
5149 specific_bug_549287_visible_func,
5152 view = gtk_tree_view_new_with_model (filtered);
5154 for (i = 0; i < 4; i++)
5156 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
5158 parent = gtk_tree_iter_copy (&iter);
5159 child = gtk_tree_iter_copy (&iter);
5161 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
5170 gtk_tree_store_append (store, child, parent);
5171 gtk_tree_store_set (store, child,
5175 gtk_tree_iter_free (parent);
5176 gtk_tree_iter_free (child);
5180 gtk_tree_store_append (store, &iter, NULL);
5181 gtk_tree_store_set (store, &iter,
5186 /* since we inserted something, we changed the visibility conditions: */
5187 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
5192 specific_bug_621076_visible_func (GtkTreeModel *model,
5196 gboolean visible = FALSE;
5199 gtk_tree_model_get (model, iter, 0, &str, -1);
5200 if (str != NULL && g_str_has_prefix (str, "visible"))
5206 GtkTreeIter child_iter;
5209 /* Recursively check if we have a visible child */
5210 for (valid = gtk_tree_model_iter_children (model, &child_iter, iter);
5211 valid; valid = gtk_tree_model_iter_next (model, &child_iter))
5213 if (specific_bug_621076_visible_func (model, &child_iter, data))
5228 specific_bug_621076 (void)
5230 /* Test case for GNOME Bugzilla bug 621076, provided by Xavier Claessens */
5232 /* This test case differs from has-child-filter and root-has-child-filter
5233 * in that the visible function both filters on content and model
5234 * structure. Also, it is recursive.
5237 GtkTreeStore *store;
5238 GtkTreeModel *filter;
5240 GtkTreeIter group_iter;
5241 GtkTreeIter item_iter;
5242 SignalMonitor *monitor;
5244 g_test_bug ("621076");
5246 store = gtk_tree_store_new (1, G_TYPE_STRING);
5247 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
5248 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
5249 specific_bug_621076_visible_func,
5252 view = gtk_tree_view_new_with_model (filter);
5253 g_object_ref_sink (view);
5255 monitor = signal_monitor_new (filter);
5257 signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
5258 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5259 0, "visible-group-0",
5261 signal_monitor_assert_is_empty (monitor);
5263 /* visible-group-0 is not expanded, so ROW_INSERTED should not be emitted
5264 * for its children. However, ROW_HAS_CHILD_TOGGLED should be emitted on
5265 * visible-group-0 to tell the view that row can be expanded. */
5266 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
5267 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
5268 group_iter = item_iter;
5269 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5272 signal_monitor_assert_is_empty (monitor);
5274 signal_monitor_append_signal (monitor, ROW_INSERTED, "1");
5275 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5276 0, "visible-group-1",
5278 signal_monitor_assert_is_empty (monitor);
5280 /* We are adding an hidden item inside visible-group-1, so
5281 * ROW_HAS_CHILD_TOGGLED should not be emitted. It is emitted though,
5282 * because the signal originating at TreeStore will be propagated,
5283 * as well a generated signal because the state of the parent *could*
5284 * change by a change in the model.
5286 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5287 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5288 group_iter = item_iter;
5289 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5292 signal_monitor_assert_is_empty (monitor);
5294 /* This group is invisible and its parent too. Nothing should be emitted */
5295 group_iter = item_iter;
5296 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5299 signal_monitor_assert_is_empty (monitor);
5301 /* Adding a visible item in this group hierarchy will make all nodes
5302 * in this path visible. The first level should simply tell the view
5303 * that it now has a child, and the view will load the tree if needed
5304 * (depends on the expanded state).
5306 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5307 group_iter = item_iter;
5308 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5309 0, "visible-1:0:0:0",
5311 signal_monitor_assert_is_empty (monitor);
5313 check_level_length (GTK_TREE_MODEL_FILTER (filter), "1", 1);
5315 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5318 signal_monitor_assert_is_empty (monitor);
5320 /* Parent is invisible, and adding this invisible item won't change that,
5321 * so no signal should be emitted. */
5322 group_iter = item_iter;
5323 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5326 signal_monitor_assert_is_empty (monitor);
5328 /* This makes group-2 visible, so it gets inserted and tells it has
5331 signal_monitor_append_signal (monitor, ROW_INSERTED, "2");
5332 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5333 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5336 signal_monitor_assert_is_empty (monitor);
5338 /* group-2 is already visible, so this time it is a normal insertion */
5339 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5342 signal_monitor_assert_is_empty (monitor);
5345 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5348 signal_monitor_assert_is_empty (monitor);
5350 /* Parent is invisible, and adding this invisible item won't change that,
5351 * so no signal should be emitted. */
5352 group_iter = item_iter;
5353 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5356 signal_monitor_assert_is_empty (monitor);
5358 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5361 signal_monitor_assert_is_empty (monitor);
5363 /* This will make group 3 visible. */
5364 signal_monitor_append_signal (monitor, ROW_INSERTED, "3");
5365 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
5366 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
5367 gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
5368 signal_monitor_assert_is_empty (monitor);
5370 /* Make sure all groups are expanded, so the filter has the tree cached */
5371 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
5372 while (gtk_events_pending ())
5373 gtk_main_iteration ();
5375 /* Should only yield a row-changed */
5376 signal_monitor_append_signal (monitor, ROW_CHANGED, "3:0");
5377 gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
5378 signal_monitor_assert_is_empty (monitor);
5380 /* Now remove/hide some items. If a group loses its last item, the group
5381 * should be deleted instead of the item.
5384 signal_monitor_append_signal (monitor, ROW_DELETED, "2:1");
5385 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:2");
5386 gtk_tree_store_remove (store, &item_iter);
5387 signal_monitor_assert_is_empty (monitor);
5389 signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
5390 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5391 signal_monitor_append_signal (monitor, ROW_DELETED, "2");
5392 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:1");
5393 gtk_tree_store_set (store, &item_iter, 0, "invisible-2:1", -1);
5394 signal_monitor_assert_is_empty (monitor);
5396 signal_monitor_append_signal (monitor, ROW_DELETED, "1:0:0:0");
5397 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1:0:0");
5398 signal_monitor_append_signal (monitor, ROW_DELETED, "1:0");
5399 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5400 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "1:0:0:0");
5401 gtk_tree_store_remove (store, &item_iter);
5402 signal_monitor_assert_is_empty (monitor);
5404 /* Hide a group using row-changed instead of row-deleted */
5405 /* Caution: group 2 is gone, so offsets of the signals have moved. */
5406 signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
5407 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5408 signal_monitor_append_signal (monitor, ROW_DELETED, "2");
5409 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter,
5411 gtk_tree_store_set (store, &item_iter, 0, "invisible-3:1", -1);
5412 signal_monitor_assert_is_empty (monitor);
5417 GtkTreeViewColumn *col;
5419 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
5421 col = gtk_tree_view_column_new_with_attributes ("foo",
5422 gtk_cell_renderer_text_new (),
5424 gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
5426 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5427 g_signal_connect (window, "delete-event",
5428 G_CALLBACK (gtk_widget_destroy), NULL);
5429 g_signal_connect (window, "destroy",
5430 G_CALLBACK (gtk_main_quit), NULL);
5432 gtk_container_add (GTK_CONTAINER (window), view);
5434 gtk_widget_show (view);
5435 gtk_widget_show (window);
5442 signal_monitor_free (monitor);
5443 g_object_unref (view);
5444 g_object_unref (store);
5445 g_object_unref (filter);
5451 register_filter_model_tests (void)
5453 g_test_add ("/TreeModelFilter/self/verify-test-suite",
5457 filter_test_teardown);
5459 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-1",
5460 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5462 verify_test_suite_vroot,
5463 filter_test_teardown);
5464 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-2",
5465 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
5467 verify_test_suite_vroot,
5468 filter_test_teardown);
5471 g_test_add ("/TreeModelFilter/filled/hide-root-level",
5474 filled_hide_root_level,
5475 filter_test_teardown);
5476 g_test_add ("/TreeModelFilter/filled/hide-child-levels",
5479 filled_hide_child_levels,
5480 filter_test_teardown);
5481 g_test_add ("/TreeModelFilter/filled/hide-child-levels/root-expanded",
5484 filled_hide_child_levels_root_expanded,
5485 filter_test_teardown);
5487 g_test_add ("/TreeModelFilter/filled/hide-root-level/vroot",
5488 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5490 filled_vroot_hide_root_level,
5491 filter_test_teardown);
5492 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot",
5493 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5495 filled_vroot_hide_child_levels,
5496 filter_test_teardown);
5497 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot-root-expanded",
5498 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5500 filled_vroot_hide_child_levels_root_expanded,
5501 filter_test_teardown);
5504 g_test_add ("/TreeModelFilter/empty/show-nodes",
5506 filter_test_setup_empty,
5508 filter_test_teardown);
5509 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes",
5511 filter_test_setup_empty,
5512 empty_show_multiple_nodes,
5513 filter_test_teardown);
5515 g_test_add ("/TreeModelFilter/empty/show-nodes/vroot",
5516 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5517 filter_test_setup_empty,
5518 empty_vroot_show_nodes,
5519 filter_test_teardown);
5520 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes/vroot",
5521 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5522 filter_test_setup_empty,
5523 empty_vroot_show_multiple_nodes,
5524 filter_test_teardown);
5527 g_test_add ("/TreeModelFilter/unfiltered/hide-single",
5529 filter_test_setup_unfiltered,
5530 unfiltered_hide_single,
5531 filter_test_teardown);
5532 g_test_add ("/TreeModelFilter/unfiltered/hide-single/root-expanded",
5534 filter_test_setup_unfiltered_root_expanded,
5535 unfiltered_hide_single_root_expanded,
5536 filter_test_teardown);
5537 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child",
5539 filter_test_setup_unfiltered,
5540 unfiltered_hide_single_child,
5541 filter_test_teardown);
5542 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/root-expanded",
5544 filter_test_setup_unfiltered_root_expanded,
5545 unfiltered_hide_single_child_root_expanded,
5546 filter_test_teardown);
5547 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level",
5549 filter_test_setup_unfiltered,
5550 unfiltered_hide_single_multi_level,
5551 filter_test_teardown);
5552 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/root-expanded",
5554 filter_test_setup_unfiltered_root_expanded,
5555 unfiltered_hide_single_multi_level_root_expanded,
5556 filter_test_teardown);
5558 g_test_add ("/TreeModelFilter/unfiltered/hide-single/vroot",
5559 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5560 filter_test_setup_unfiltered,
5561 unfiltered_vroot_hide_single,
5562 filter_test_teardown);
5563 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot",
5564 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5565 filter_test_setup_unfiltered,
5566 unfiltered_vroot_hide_single_child,
5567 filter_test_teardown);
5568 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot/root-expanded",
5569 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5570 filter_test_setup_unfiltered_root_expanded,
5571 unfiltered_vroot_hide_single_child_root_expanded,
5572 filter_test_teardown);
5573 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot",
5574 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5575 filter_test_setup_unfiltered,
5576 unfiltered_vroot_hide_single_multi_level,
5577 filter_test_teardown);
5578 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot/root-expanded",
5579 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5580 filter_test_setup_unfiltered_root_expanded,
5581 unfiltered_vroot_hide_single_multi_level_root_expanded,
5582 filter_test_teardown);
5586 g_test_add ("/TreeModelFilter/unfiltered/show-single",
5588 filter_test_setup_empty_unfiltered,
5589 unfiltered_show_single,
5590 filter_test_teardown);
5591 g_test_add ("/TreeModelFilter/unfiltered/show-single-child",
5593 filter_test_setup_empty_unfiltered,
5594 unfiltered_show_single_child,
5595 filter_test_teardown);
5596 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/root-expanded",
5598 filter_test_setup_empty_unfiltered_root_expanded,
5599 unfiltered_show_single_child_root_expanded,
5600 filter_test_teardown);
5601 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level",
5603 filter_test_setup_empty_unfiltered,
5604 unfiltered_show_single_multi_level,
5605 filter_test_teardown);
5606 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/root-expanded",
5608 filter_test_setup_empty_unfiltered_root_expanded,
5609 unfiltered_show_single_multi_level_root_expanded,
5610 filter_test_teardown);
5612 g_test_add ("/TreeModelFilter/unfiltered/show-single/vroot",
5613 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5614 filter_test_setup_empty_unfiltered,
5615 unfiltered_vroot_show_single,
5616 filter_test_teardown);
5617 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot",
5618 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5619 filter_test_setup_empty_unfiltered,
5620 unfiltered_vroot_show_single_child,
5621 filter_test_teardown);
5622 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot/root-expanded",
5623 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5624 filter_test_setup_empty_unfiltered_root_expanded,
5625 unfiltered_vroot_show_single_child_root_expanded,
5626 filter_test_teardown);
5627 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot",
5628 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5629 filter_test_setup_empty_unfiltered,
5630 unfiltered_vroot_show_single_multi_level,
5631 filter_test_teardown);
5632 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot/root-expanded",
5633 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5634 filter_test_setup_empty_unfiltered_root_expanded,
5635 unfiltered_vroot_show_single_multi_level_root_expanded,
5636 filter_test_teardown);
5639 g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/root-level",
5641 filter_test_setup_unfiltered,
5642 unfiltered_rows_reordered_root_level,
5643 filter_test_teardown);
5644 g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/child-level",
5646 filter_test_setup_unfiltered,
5647 unfiltered_rows_reordered_child_level,
5648 filter_test_teardown);
5650 g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/first-hidden",
5653 filtered_rows_reordered_root_level_first_hidden,
5654 filter_test_teardown);
5655 g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/middle-hidden",
5658 filtered_rows_reordered_root_level_middle_hidden,
5659 filter_test_teardown);
5660 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/first-hidden",
5663 filtered_rows_reordered_child_level_first_hidden,
5664 filter_test_teardown);
5665 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/middle-hidden",
5668 filtered_rows_reordered_child_level_middle_hidden,
5669 filter_test_teardown);
5670 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/4-hidden",
5673 filtered_rows_reordered_child_level_4_hidden,
5674 filter_test_teardown);
5675 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/all-hidden",
5678 filtered_rows_reordered_child_level_all_hidden,
5679 filter_test_teardown);
5681 /* Inserts in child models after creation of filter model */
5682 g_test_add_func ("/TreeModelFilter/insert/before",
5684 g_test_add_func ("/TreeModelFilter/insert/child",
5687 /* Removals from child model after creating of filter model */
5688 g_test_add_func ("/TreeModelFilter/remove/node",
5690 g_test_add_func ("/TreeModelFilter/remove/node-vroot",
5692 g_test_add_func ("/TreeModelFilter/remove/vroot-ancestor",
5693 remove_vroot_ancestor);
5695 /* Reference counting */
5696 g_test_add_func ("/TreeModelFilter/ref-count/single-level",
5697 ref_count_single_level);
5698 g_test_add_func ("/TreeModelFilter/ref-count/two-levels",
5699 ref_count_two_levels);
5700 g_test_add_func ("/TreeModelFilter/ref-count/three-levels",
5701 ref_count_three_levels);
5702 g_test_add_func ("/TreeModelFilter/ref-count/delete-row",
5703 ref_count_delete_row);
5704 g_test_add_func ("/TreeModelFilter/ref-count/cleanup",
5706 g_test_add_func ("/TreeModelFilter/ref-count/row-ref",
5709 /* Reference counting, transfer of first reference on
5710 * first node in level. This is a GtkTreeModelFilter-specific
5713 g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/insert",
5714 ref_count_transfer_root_level_insert);
5715 g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/reordered",
5716 ref_count_transfer_root_level_reordered);
5717 g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/insert",
5718 ref_count_transfer_child_level_insert);
5719 g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/reordered",
5720 ref_count_transfer_child_level_reordered);
5722 g_test_add_func ("/TreeModelFilter/specific/path-dependent-filter",
5723 specific_path_dependent_filter);
5724 g_test_add_func ("/TreeModelFilter/specific/append-after-collapse",
5725 specific_append_after_collapse);
5726 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-node",
5727 specific_sort_filter_remove_node);
5728 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-root",
5729 specific_sort_filter_remove_root);
5730 g_test_add_func ("/TreeModelFilter/specific/root-mixed-visibility",
5731 specific_root_mixed_visibility);
5732 g_test_add_func ("/TreeModelFilter/specific/has-child-filter",
5733 specific_has_child_filter);
5734 g_test_add_func ("/TreeModelFilter/specific/has-child-filter-on-sort-model",
5735 specific_has_child_filter_on_sort_model);
5736 g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter",
5737 specific_at_least_2_children_filter);
5738 g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter-on-sort-model",
5739 specific_at_least_2_children_filter_on_sort_model);
5740 g_test_add_func ("/TreeModelFilter/specific/root-has-child-filter",
5741 specific_root_has_child_filter);
5742 g_test_add_func ("/TreeModelFilter/specific/filter-add-child",
5743 specific_filter_add_child);
5744 g_test_add_func ("/TreeModelFilter/specific/list-store-clear",
5745 specific_list_store_clear);
5746 g_test_add_func ("/TreeModelFilter/specific/sort-ref-leaf-and-remove-ancestor",
5747 specific_sort_ref_leaf_and_remove_ancestor);
5748 g_test_add_func ("/TreeModelFilter/specific/ref-leaf-and-remove-ancestor",
5749 specific_ref_leaf_and_remove_ancestor);
5750 g_test_add_func ("/TreeModelFilter/specific/virtual-ref-leaf-and-remove-ancestor",
5751 specific_virtual_ref_leaf_and_remove_ancestor);
5753 g_test_add_func ("/TreeModelFilter/specific/bug-301558",
5754 specific_bug_301558);
5755 g_test_add_func ("/TreeModelFilter/specific/bug-311955",
5756 specific_bug_311955);
5757 g_test_add_func ("/TreeModelFilter/specific/bug-311955-clean",
5758 specific_bug_311955_clean);
5759 g_test_add_func ("/TreeModelFilter/specific/bug-346800",
5760 specific_bug_346800);
5761 g_test_add_func ("/TreeModelFilter/specific/bug-464173",
5762 specific_bug_464173);
5763 g_test_add_func ("/TreeModelFilter/specific/bug-540201",
5764 specific_bug_540201);
5765 g_test_add_func ("/TreeModelFilter/specific/bug-549287",
5766 specific_bug_549287);
5767 g_test_add_func ("/TreeModelFilter/specific/bug-621076",
5768 specific_bug_621076);