1 /* Extensive GtkTreeModelFilter tests.
2 * Copyright (C) 2009 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.
24 * - Proper coverage checking to see if the unit tests cover
26 * - Verify if the ref counting is done properly for both the
27 * normal ref_count and the zero_ref_count. One way to test
28 * this area is by collapsing/expanding branches on the view
29 * that is connected to the filter model.
30 * - Check if the iterator stamp is incremented at the correct times.
38 #define LEVEL_LENGTH 5
41 create_tree_store_set_values (GtkTreeStore *store,
48 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
49 path_string = gtk_tree_path_to_string (path);
51 gtk_tree_store_set (store, iter,
56 gtk_tree_path_free (path);
61 create_tree_store_recurse (int depth,
68 for (i = 0; i < LEVEL_LENGTH; i++)
72 gtk_tree_store_insert (store, &iter, parent, i);
73 create_tree_store_set_values (store, &iter, visible);
76 create_tree_store_recurse (depth - 1, store, &iter, visible);
81 create_tree_store (int depth,
86 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
88 create_tree_store_recurse (depth, store, NULL, visible);
102 ROW_HAS_CHILD_TOGGLED,
109 signal_name_to_string (SignalName signal)
114 return "row-inserted";
117 return "row-deleted";
120 return "row-changed";
122 case ROW_HAS_CHILD_TOGGLED:
123 return "row-has-child-toggled";
126 return "rows-reordered";
145 signal_new (SignalName signal, GtkTreePath *path)
149 s = g_new0 (Signal, 1);
151 s->path = gtk_tree_path_copy (path);
157 signal_free (Signal *s)
160 gtk_tree_path_free (s->path);
169 GtkTreeModel *client;
170 gulong signal_ids[LAST_SIGNAL];
176 signal_monitor_generic_handler (SignalMonitor *m,
183 if (g_queue_is_empty (m->queue))
187 path_str = gtk_tree_path_to_string (path);
188 g_error ("Signal queue empty, got signal %s path %s\n",
189 signal_name_to_string (signal), path_str);
192 g_assert_not_reached ();
195 if (m->client != model)
197 g_error ("Model mismatch; expected %p, got %p\n",
199 g_assert_not_reached ();
202 s = g_queue_peek_tail (m->queue);
205 /* For debugging: output signals that are coming in. Leaks memory. */
206 g_print ("signal=%s path=%s\n", signal_name_to_string (signal),
207 gtk_tree_path_to_string (path));
210 if (s->signal != signal
211 || gtk_tree_path_compare (s->path, path) != 0)
213 gchar *path_str, *s_path_str;
215 s_path_str = gtk_tree_path_to_string (s->path);
216 path_str = gtk_tree_path_to_string (path);
218 g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n",
219 signal_name_to_string (s->signal), s_path_str,
220 signal_name_to_string (signal), path_str);
225 g_assert_not_reached ();
228 s = g_queue_pop_tail (m->queue);
234 signal_monitor_row_inserted (GtkTreeModel *model,
239 signal_monitor_generic_handler (data, ROW_INSERTED,
244 signal_monitor_row_deleted (GtkTreeModel *model,
248 signal_monitor_generic_handler (data, ROW_DELETED,
253 signal_monitor_row_changed (GtkTreeModel *model,
258 signal_monitor_generic_handler (data, ROW_CHANGED,
263 signal_monitor_row_has_child_toggled (GtkTreeModel *model,
268 signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
273 signal_monitor_rows_reordered (GtkTreeModel *model,
279 signal_monitor_generic_handler (data, ROWS_REORDERED,
283 static SignalMonitor *
284 signal_monitor_new (GtkTreeModel *client)
288 m = g_new0 (SignalMonitor, 1);
289 m->client = g_object_ref (client);
290 m->queue = g_queue_new ();
292 m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
294 G_CALLBACK (signal_monitor_row_inserted),
296 m->signal_ids[ROW_DELETED] = g_signal_connect (client,
298 G_CALLBACK (signal_monitor_row_deleted),
300 m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
302 G_CALLBACK (signal_monitor_row_changed),
304 m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
305 "row-has-child-toggled",
306 G_CALLBACK (signal_monitor_row_has_child_toggled),
308 m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
310 G_CALLBACK (signal_monitor_rows_reordered),
317 signal_monitor_free (SignalMonitor *m)
321 for (i = 0; i < LAST_SIGNAL; i++)
322 g_signal_handler_disconnect (m->client, m->signal_ids[i]);
324 g_object_unref (m->client);
327 g_queue_free (m->queue);
333 signal_monitor_assert_is_empty (SignalMonitor *m)
335 g_assert (g_queue_is_empty (m->queue));
339 signal_monitor_append_signal_path (SignalMonitor *m,
345 s = signal_new (signal, path);
346 g_queue_push_head (m->queue, s);
350 signal_monitor_append_signal (SignalMonitor *m,
352 const gchar *path_string)
357 path = gtk_tree_path_new_from_string (path_string);
359 s = signal_new (signal, path);
360 g_queue_push_head (m->queue, s);
362 gtk_tree_path_free (path);
371 GtkWidget *tree_view;
374 GtkTreeModelFilter *filter;
376 SignalMonitor *monitor;
378 guint block_signals : 1;
383 filter_test_store_signal (FilterTest *fixture)
385 if (fixture->block_signals)
386 g_signal_stop_emission_by_name (fixture->store, "row-changed");
391 filter_test_setup_generic (FilterTest *fixture,
392 gconstpointer test_data,
397 const GtkTreePath *vroot = test_data;
398 GtkTreeModel *filter;
400 fixture->store = create_tree_store (depth, !empty);
402 g_signal_connect_swapped (fixture->store, "row-changed",
403 G_CALLBACK (filter_test_store_signal), fixture);
405 /* Please forgive me for casting const away. */
406 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
407 (GtkTreePath *)vroot);
408 fixture->filter = GTK_TREE_MODEL_FILTER (filter);
411 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
413 /* We need a tree view that's listening to get ref counting from that
416 fixture->tree_view = gtk_tree_view_new_with_model (filter);
418 fixture->monitor = signal_monitor_new (filter);
422 filter_test_setup (FilterTest *fixture,
423 gconstpointer test_data)
425 filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
429 filter_test_setup_empty (FilterTest *fixture,
430 gconstpointer test_data)
432 filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
436 filter_test_setup_unfiltered (FilterTest *fixture,
437 gconstpointer test_data)
439 filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
443 filter_test_setup_empty_unfiltered (FilterTest *fixture,
444 gconstpointer test_data)
446 filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
450 strip_virtual_root (GtkTreePath *path,
451 GtkTreePath *root_path)
453 GtkTreePath *real_path;
458 int depth = gtk_tree_path_get_depth (path);
459 int root_depth = gtk_tree_path_get_depth (root_path);
461 real_path = gtk_tree_path_new ();
463 for (j = 0; j < depth - root_depth; j++)
464 gtk_tree_path_append_index (real_path,
465 gtk_tree_path_get_indices (path)[root_depth + j]);
468 real_path = gtk_tree_path_copy (path);
474 filter_test_append_refilter_signals_recurse (FilterTest *fixture,
475 GtkTreePath *store_path,
476 GtkTreePath *filter_path,
478 GtkTreePath *root_path)
481 int rows_deleted = 0;
484 gtk_tree_path_down (store_path);
485 gtk_tree_path_down (filter_path);
487 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
490 for (i = 0; i < LEVEL_LENGTH; i++)
493 GtkTreePath *real_path;
495 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
500 (!gtk_tree_path_is_descendant (store_path, root_path)
501 || !gtk_tree_path_compare (store_path, root_path)))
503 if (!gtk_tree_path_compare (store_path, root_path))
506 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
509 GtkTreePath *store_copy;
510 GtkTreePath *filter_copy;
512 store_copy = gtk_tree_path_copy (store_path);
513 filter_copy = gtk_tree_path_copy (filter_path);
514 filter_test_append_refilter_signals_recurse (fixture,
519 gtk_tree_path_free (store_copy);
520 gtk_tree_path_free (filter_copy);
524 gtk_tree_path_next (store_path);
525 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
528 gtk_tree_path_next (filter_path);
533 real_path = strip_virtual_root (filter_path, root_path);
537 /* This row will be inserted */
538 signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
540 signal_monitor_append_signal_path (fixture->monitor,
541 ROW_HAS_CHILD_TOGGLED,
545 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
548 GtkTreePath *store_copy;
549 GtkTreePath *filter_copy;
551 store_copy = gtk_tree_path_copy (store_path);
552 filter_copy = gtk_tree_path_copy (filter_path);
553 filter_test_append_refilter_signals_recurse (fixture,
558 gtk_tree_path_free (store_copy);
559 gtk_tree_path_free (filter_copy);
562 gtk_tree_path_next (filter_path);
566 /* This row will be deleted */
568 signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
572 gtk_tree_path_free (real_path);
574 gtk_tree_path_next (store_path);
575 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
578 if (rows_deleted == LEVEL_LENGTH
579 && gtk_tree_path_get_depth (filter_path) > 1)
581 GtkTreePath *real_path;
583 gtk_tree_path_up (store_path);
584 gtk_tree_path_up (filter_path);
586 /* A row-has-child-toggled will be emitted on the parent */
589 && gtk_tree_path_is_descendant (store_path, root_path)
590 && gtk_tree_path_compare (store_path, root_path)))
592 real_path = strip_virtual_root (filter_path, root_path);
593 signal_monitor_append_signal_path (fixture->monitor,
594 ROW_HAS_CHILD_TOGGLED,
597 gtk_tree_path_free (real_path);
603 filter_test_append_refilter_signals (FilterTest *fixture,
606 /* A special function that walks the tree store like the
607 * model validation functions below.
610 GtkTreePath *filter_path;
612 path = gtk_tree_path_new ();
613 filter_path = gtk_tree_path_new ();
614 filter_test_append_refilter_signals_recurse (fixture,
619 gtk_tree_path_free (path);
620 gtk_tree_path_free (filter_path);
624 filter_test_append_refilter_signals_with_vroot (FilterTest *fixture,
626 GtkTreePath *root_path)
628 /* A special function that walks the tree store like the
629 * model validation functions below.
632 GtkTreePath *filter_path;
634 path = gtk_tree_path_new ();
635 filter_path = gtk_tree_path_new ();
636 filter_test_append_refilter_signals_recurse (fixture,
641 gtk_tree_path_free (path);
642 gtk_tree_path_free (filter_path);
646 filter_test_enable_filter (FilterTest *fixture)
648 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
649 gtk_tree_model_filter_refilter (fixture->filter);
653 filter_test_block_signals (FilterTest *fixture)
655 fixture->block_signals = TRUE;
659 filter_test_unblock_signals (FilterTest *fixture)
661 fixture->block_signals = FALSE;
665 filter_test_teardown (FilterTest *fixture,
666 gconstpointer test_data)
668 signal_monitor_free (fixture->monitor);
670 g_object_unref (fixture->filter);
671 g_object_unref (fixture->store);
675 * Model structure validation
679 check_filter_model_recurse (FilterTest *fixture,
680 GtkTreePath *store_parent_path,
681 GtkTreePath *filter_parent_path)
684 GtkTreeIter store_iter;
685 GtkTreeIter filter_iter;
686 gboolean store_has_next, filter_has_next;
688 gtk_tree_path_down (store_parent_path);
689 gtk_tree_path_down (filter_parent_path);
691 store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
692 &store_iter, store_parent_path);
693 filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
694 &filter_iter, filter_parent_path);
696 for (i = 0; i < LEVEL_LENGTH; i++)
700 g_return_if_fail (store_has_next == TRUE);
702 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
710 gchar *filter_str, *store_str;
712 g_return_if_fail (filter_has_next == TRUE);
715 tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
717 g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
719 /* Verify model content */
720 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
724 gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
729 g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
734 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
737 g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
739 check_filter_model_recurse (fixture,
740 gtk_tree_path_copy (store_parent_path),
744 gtk_tree_path_next (filter_parent_path);
745 filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
748 gtk_tree_path_next (store_parent_path);
749 store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
752 /* Both models should have no more content! */
753 g_return_if_fail (store_has_next == FALSE);
754 g_return_if_fail (filter_has_next == FALSE);
756 gtk_tree_path_free (store_parent_path);
757 gtk_tree_path_free (filter_parent_path);
761 check_filter_model (FilterTest *fixture)
765 if (fixture->monitor)
766 signal_monitor_assert_is_empty (fixture->monitor);
768 path = gtk_tree_path_new ();
770 check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
774 check_filter_model_with_root (FilterTest *fixture,
777 if (fixture->monitor)
778 signal_monitor_assert_is_empty (fixture->monitor);
780 check_filter_model_recurse (fixture,
781 gtk_tree_path_copy (path),
782 gtk_tree_path_new ());
788 check_level_length (GtkTreeModelFilter *filter,
794 int l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
795 g_return_if_fail (l == length);
800 gboolean retrieved_iter = FALSE;
803 retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
805 g_return_if_fail (retrieved_iter);
806 l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
807 g_return_if_fail (l == length);
812 set_path_visibility (FilterTest *fixture,
816 GtkTreeIter store_iter;
818 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
820 gtk_tree_store_set (fixture->store, &store_iter,
827 insert_path_with_visibility (FilterTest *fixture,
828 const gchar *path_string,
833 GtkTreeIter parent, iter;
835 path = gtk_tree_path_new_from_string (path_string);
836 position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
837 gtk_tree_path_up (path);
839 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
841 gtk_tree_store_insert (fixture->store, &iter, &parent, position);
842 create_tree_store_set_values (fixture->store, &iter, visible);
844 gtk_tree_path_free (path);
853 verify_test_suite (FilterTest *fixture,
854 gconstpointer user_data)
856 check_filter_model (fixture);
860 verify_test_suite_vroot (FilterTest *fixture,
861 gconstpointer user_data)
863 check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
868 filled_hide_root_level (FilterTest *fixture,
869 gconstpointer user_data)
871 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
872 set_path_visibility (fixture, "2", FALSE);
873 check_filter_model (fixture);
874 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
876 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
877 set_path_visibility (fixture, "0", FALSE);
878 check_filter_model (fixture);
879 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
881 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
882 set_path_visibility (fixture, "4", FALSE);
883 check_filter_model (fixture);
884 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
888 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
889 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
891 set_path_visibility (fixture, "1", FALSE);
892 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
894 set_path_visibility (fixture, "3", FALSE);
895 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
897 check_filter_model (fixture);
900 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
901 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
902 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
903 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
905 set_path_visibility (fixture, "1", TRUE);
906 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
908 set_path_visibility (fixture, "3", TRUE);
909 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
911 check_filter_model (fixture);
915 filled_hide_child_levels (FilterTest *fixture,
916 gconstpointer user_data)
918 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
919 set_path_visibility (fixture, "0:2", FALSE);
920 check_filter_model (fixture);
921 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
922 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
924 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
925 set_path_visibility (fixture, "0:4", FALSE);
926 check_filter_model (fixture);
927 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
928 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
930 set_path_visibility (fixture, "0:4:3", FALSE);
931 check_filter_model (fixture);
932 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
933 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
935 set_path_visibility (fixture, "0:4:0", FALSE);
936 set_path_visibility (fixture, "0:4:1", FALSE);
937 set_path_visibility (fixture, "0:4:2", FALSE);
938 set_path_visibility (fixture, "0:4:4", FALSE);
939 check_filter_model (fixture);
940 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
941 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
943 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
944 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
945 /* FIXME: Actually, the filter model should not be emitted the
946 * row-has-child-toggled signal here. *However* an extraneous emission
947 * of this signal does not hurt and is allowed.
949 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
950 set_path_visibility (fixture, "0:4", TRUE);
951 check_filter_model (fixture);
952 check_level_length (fixture->filter, "0:3", 0);
954 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
955 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
956 set_path_visibility (fixture, "0:2", TRUE);
957 check_filter_model (fixture);
958 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
959 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
960 check_level_length (fixture->filter, "0:4", 0);
962 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
963 /* Once 0:4:0 got inserted, 0:4 became a parent */
964 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
965 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:0");
966 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
967 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:1");
969 set_path_visibility (fixture, "0:4:2", TRUE);
970 set_path_visibility (fixture, "0:4:4", TRUE);
971 signal_monitor_assert_is_empty (fixture->monitor);
972 check_level_length (fixture->filter, "0:4", 2);
977 filled_vroot_hide_root_level (FilterTest *fixture,
978 gconstpointer user_data)
980 GtkTreePath *path = (GtkTreePath *)user_data;
982 /* These changes do not affect the filter's root level */
983 set_path_visibility (fixture, "0", FALSE);
984 check_filter_model_with_root (fixture, path);
985 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
986 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
988 set_path_visibility (fixture, "4", FALSE);
989 check_filter_model_with_root (fixture, path);
990 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
991 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
993 /* Even though we set the virtual root parent node to FALSE,
994 * the virtual root contents remain.
996 set_path_visibility (fixture, "2", FALSE);
997 check_filter_model_with_root (fixture, path);
998 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
999 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1002 set_path_visibility (fixture, "1", FALSE);
1003 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1004 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1006 set_path_visibility (fixture, "3", FALSE);
1007 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1008 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1010 check_filter_model_with_root (fixture, path);
1013 set_path_visibility (fixture, "2", TRUE);
1014 check_filter_model_with_root (fixture, path);
1015 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1016 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1018 set_path_visibility (fixture, "1", TRUE);
1019 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1020 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1022 set_path_visibility (fixture, "3", TRUE);
1023 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1024 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1026 check_filter_model_with_root (fixture, path);
1028 /* Now test changes in the virtual root level */
1029 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
1030 set_path_visibility (fixture, "2:2", FALSE);
1031 check_filter_model_with_root (fixture, path);
1032 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1034 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
1035 set_path_visibility (fixture, "2:4", FALSE);
1036 check_filter_model_with_root (fixture, path);
1037 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1039 set_path_visibility (fixture, "1:4", FALSE);
1040 check_filter_model_with_root (fixture, path);
1041 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1043 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
1044 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
1045 set_path_visibility (fixture, "2:4", TRUE);
1046 check_filter_model_with_root (fixture, path);
1047 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1049 set_path_visibility (fixture, "2", FALSE);
1050 check_filter_model_with_root (fixture, path);
1051 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1053 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1054 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1055 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1056 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1057 set_path_visibility (fixture, "2:0", FALSE);
1058 set_path_visibility (fixture, "2:1", FALSE);
1059 set_path_visibility (fixture, "2:2", FALSE);
1060 set_path_visibility (fixture, "2:3", FALSE);
1061 set_path_visibility (fixture, "2:4", FALSE);
1062 check_filter_model_with_root (fixture, path);
1063 check_level_length (fixture->filter, NULL, 0);
1065 set_path_visibility (fixture, "2", TRUE);
1066 check_filter_model_with_root (fixture, path);
1067 check_level_length (fixture->filter, NULL, 0);
1069 set_path_visibility (fixture, "1:4", FALSE);
1070 check_filter_model_with_root (fixture, path);
1071 check_level_length (fixture->filter, NULL, 0);
1073 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1074 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1075 set_path_visibility (fixture, "2:4", TRUE);
1076 check_filter_model_with_root (fixture, path);
1077 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
1079 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1080 set_path_visibility (fixture, "2:4", FALSE);
1081 check_filter_model_with_root (fixture, path);
1082 check_level_length (fixture->filter, NULL, 0);
1084 set_path_visibility (fixture, "2", FALSE);
1085 check_filter_model_with_root (fixture, path);
1086 check_level_length (fixture->filter, NULL, 0);
1088 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1089 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1090 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1091 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1092 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
1093 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1094 set_path_visibility (fixture, "2:0", TRUE);
1095 set_path_visibility (fixture, "2:1", TRUE);
1096 set_path_visibility (fixture, "2:2", TRUE);
1097 check_filter_model_with_root (fixture, path);
1098 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1100 set_path_visibility (fixture, "2", TRUE);
1101 check_filter_model_with_root (fixture, path);
1102 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1106 filled_vroot_hide_child_levels (FilterTest *fixture,
1107 gconstpointer user_data)
1109 GtkTreePath *path = (GtkTreePath *)user_data;
1111 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1112 set_path_visibility (fixture, "2:0:2", FALSE);
1113 check_filter_model_with_root (fixture, path);
1114 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1115 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1117 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1118 set_path_visibility (fixture, "2:0:4", FALSE);
1119 check_filter_model_with_root (fixture, path);
1120 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1121 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1123 set_path_visibility (fixture, "2:0:4:3", FALSE);
1124 check_filter_model_with_root (fixture, path);
1125 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1126 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1128 set_path_visibility (fixture, "2:0:4:0", FALSE);
1129 set_path_visibility (fixture, "2:0:4:1", FALSE);
1130 set_path_visibility (fixture, "2:0:4:2", FALSE);
1131 set_path_visibility (fixture, "2:0:4:4", FALSE);
1132 check_filter_model_with_root (fixture, path);
1133 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1134 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1136 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1137 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1138 /* FIXME: Actually, the filter model should not be emitted the
1139 * row-has-child-toggled signal here. *However* an extraneous emission
1140 * of this signal does not hurt and is allowed.
1142 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1143 set_path_visibility (fixture, "2:0:4", TRUE);
1144 check_filter_model_with_root (fixture, path);
1145 check_level_length (fixture->filter, "0:3", 0);
1147 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1148 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1149 set_path_visibility (fixture, "2:0:2", TRUE);
1150 check_filter_model_with_root (fixture, path);
1151 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1152 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1153 check_level_length (fixture->filter, "0:4", 0);
1155 /* FIXME: Inconsistency! For the non-vroot case we also receive two
1156 * row-has-child-toggled signals here.
1158 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
1159 /* Once 0:4:0 got inserted, 0:4 became a parent */
1160 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1161 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
1162 set_path_visibility (fixture, "2:0:4:2", TRUE);
1163 set_path_visibility (fixture, "2:0:4:4", TRUE);
1164 check_level_length (fixture->filter, "0:4", 2);
1169 empty_show_nodes (FilterTest *fixture,
1170 gconstpointer user_data)
1172 check_filter_model (fixture);
1173 check_level_length (fixture->filter, NULL, 0);
1175 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1176 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1177 set_path_visibility (fixture, "3", TRUE);
1178 check_filter_model (fixture);
1179 check_level_length (fixture->filter, NULL, 1);
1180 check_level_length (fixture->filter, "0", 0);
1182 set_path_visibility (fixture, "3:2:2", TRUE);
1183 check_filter_model (fixture);
1184 check_level_length (fixture->filter, NULL, 1);
1185 check_level_length (fixture->filter, "0", 0);
1187 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
1188 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1189 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
1190 set_path_visibility (fixture, "3:2", TRUE);
1191 check_filter_model (fixture);
1192 check_level_length (fixture->filter, NULL, 1);
1193 check_level_length (fixture->filter, "0", 1);
1194 check_level_length (fixture->filter, "0:0", 1);
1195 check_level_length (fixture->filter, "0:0:0", 0);
1197 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1198 set_path_visibility (fixture, "3", FALSE);
1199 check_filter_model (fixture);
1200 check_level_length (fixture->filter, NULL, 0);
1202 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1203 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1204 set_path_visibility (fixture, "3:2:1", TRUE);
1205 set_path_visibility (fixture, "3", TRUE);
1206 check_filter_model (fixture);
1207 check_level_length (fixture->filter, NULL, 1);
1208 check_level_length (fixture->filter, "0", 1);
1209 check_level_length (fixture->filter, "0:0", 2);
1210 check_level_length (fixture->filter, "0:0:0", 0);
1214 empty_show_multiple_nodes (FilterTest *fixture,
1215 gconstpointer user_data)
1218 GtkTreePath *changed_path;
1220 check_filter_model (fixture);
1221 check_level_length (fixture->filter, NULL, 0);
1223 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1224 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1225 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1226 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1227 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "1");
1228 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1230 /* We simulate a change in visible func condition with this. The
1231 * visibility state of multiple nodes changes at once, we emit row-changed
1232 * for these nodes (and others) after that.
1234 filter_test_block_signals (fixture);
1235 set_path_visibility (fixture, "3", TRUE);
1236 set_path_visibility (fixture, "4", TRUE);
1237 filter_test_unblock_signals (fixture);
1239 changed_path = gtk_tree_path_new ();
1240 gtk_tree_path_append_index (changed_path, 2);
1241 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1242 &iter, changed_path);
1243 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1244 changed_path, &iter);
1246 gtk_tree_path_next (changed_path);
1247 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1248 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1249 changed_path, &iter);
1251 gtk_tree_path_next (changed_path);
1252 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1253 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1254 changed_path, &iter);
1256 gtk_tree_path_free (changed_path);
1258 check_filter_model (fixture);
1259 check_level_length (fixture->filter, NULL, 2);
1260 check_level_length (fixture->filter, "0", 0);
1262 set_path_visibility (fixture, "3:2:2", TRUE);
1263 check_filter_model (fixture);
1264 check_level_length (fixture->filter, NULL, 2);
1265 check_level_length (fixture->filter, "0", 0);
1267 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
1268 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1269 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
1270 set_path_visibility (fixture, "3:2", TRUE);
1271 check_filter_model (fixture);
1272 check_level_length (fixture->filter, NULL, 2);
1273 check_level_length (fixture->filter, "0", 1);
1274 check_level_length (fixture->filter, "0:0", 1);
1275 check_level_length (fixture->filter, "0:0:0", 0);
1277 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1278 set_path_visibility (fixture, "3", FALSE);
1279 check_filter_model (fixture);
1280 check_level_length (fixture->filter, NULL, 1);
1282 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1283 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1284 set_path_visibility (fixture, "3:2:1", TRUE);
1285 set_path_visibility (fixture, "3", TRUE);
1286 check_filter_model (fixture);
1287 check_level_length (fixture->filter, NULL, 2);
1288 check_level_length (fixture->filter, "0", 1);
1289 check_level_length (fixture->filter, "0:0", 2);
1290 check_level_length (fixture->filter, "0:0:0", 0);
1294 empty_vroot_show_nodes (FilterTest *fixture,
1295 gconstpointer user_data)
1297 GtkTreePath *path = (GtkTreePath *)user_data;
1299 check_filter_model_with_root (fixture, path);
1300 check_level_length (fixture->filter, NULL, 0);
1302 set_path_visibility (fixture, "2", TRUE);
1303 check_filter_model_with_root (fixture, path);
1304 check_level_length (fixture->filter, NULL, 0);
1306 set_path_visibility (fixture, "2:2:2", TRUE);
1307 check_filter_model_with_root (fixture, path);
1308 check_level_length (fixture->filter, NULL, 0);
1310 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1311 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1312 set_path_visibility (fixture, "2:2", TRUE);
1313 check_filter_model_with_root (fixture, path);
1314 check_level_length (fixture->filter, NULL, 1);
1315 check_level_length (fixture->filter, "0", 1);
1316 check_level_length (fixture->filter, "0:0", 0);
1318 set_path_visibility (fixture, "3", TRUE);
1319 check_filter_model_with_root (fixture, path);
1320 check_level_length (fixture->filter, NULL, 1);
1322 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1323 set_path_visibility (fixture, "2:2", FALSE);
1324 check_filter_model_with_root (fixture, path);
1325 check_level_length (fixture->filter, NULL, 0);
1327 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1328 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1329 set_path_visibility (fixture, "2:2:1", TRUE);
1330 set_path_visibility (fixture, "2:2", TRUE);
1331 check_filter_model_with_root (fixture, path);
1332 check_level_length (fixture->filter, NULL, 1);
1333 check_level_length (fixture->filter, "0", 2);
1334 check_level_length (fixture->filter, "0:1", 0);
1338 empty_vroot_show_multiple_nodes (FilterTest *fixture,
1339 gconstpointer user_data)
1342 GtkTreePath *changed_path;
1343 GtkTreePath *path = (GtkTreePath *)user_data;
1345 check_filter_model_with_root (fixture, path);
1346 check_level_length (fixture->filter, NULL, 0);
1348 /* We simulate a change in visible func condition with this. The
1349 * visibility state of multiple nodes changes at once, we emit row-changed
1350 * for these nodes (and others) after that.
1352 filter_test_block_signals (fixture);
1353 set_path_visibility (fixture, "2", TRUE);
1354 set_path_visibility (fixture, "3", TRUE);
1355 filter_test_unblock_signals (fixture);
1357 changed_path = gtk_tree_path_new ();
1358 gtk_tree_path_append_index (changed_path, 1);
1359 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1360 &iter, changed_path);
1361 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1362 changed_path, &iter);
1364 gtk_tree_path_next (changed_path);
1365 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1366 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1367 changed_path, &iter);
1369 gtk_tree_path_next (changed_path);
1370 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1371 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1372 changed_path, &iter);
1374 gtk_tree_path_next (changed_path);
1375 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1376 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1377 changed_path, &iter);
1379 gtk_tree_path_free (changed_path);
1381 check_filter_model_with_root (fixture, path);
1382 check_level_length (fixture->filter, NULL, 0);
1384 set_path_visibility (fixture, "2:2:2", TRUE);
1385 check_filter_model_with_root (fixture, path);
1386 check_level_length (fixture->filter, NULL, 0);
1388 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1389 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1390 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1391 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1393 /* Again, we simulate a call to refilter */
1394 filter_test_block_signals (fixture);
1395 set_path_visibility (fixture, "2:2", TRUE);
1396 set_path_visibility (fixture, "2:3", TRUE);
1397 filter_test_unblock_signals (fixture);
1399 changed_path = gtk_tree_path_new ();
1400 gtk_tree_path_append_index (changed_path, 2);
1401 gtk_tree_path_append_index (changed_path, 1);
1402 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1403 &iter, changed_path);
1404 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1405 changed_path, &iter);
1407 gtk_tree_path_next (changed_path);
1408 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1409 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1410 changed_path, &iter);
1412 gtk_tree_path_next (changed_path);
1413 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1414 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1415 changed_path, &iter);
1417 gtk_tree_path_next (changed_path);
1418 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1419 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1420 changed_path, &iter);
1422 gtk_tree_path_free (changed_path);
1424 check_filter_model_with_root (fixture, path);
1425 check_level_length (fixture->filter, NULL, 2);
1426 check_level_length (fixture->filter, "0", 1);
1427 check_level_length (fixture->filter, "0:0", 0);
1429 set_path_visibility (fixture, "3", TRUE);
1430 check_filter_model_with_root (fixture, path);
1431 check_level_length (fixture->filter, NULL, 2);
1433 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1434 set_path_visibility (fixture, "2:2", FALSE);
1435 check_filter_model_with_root (fixture, path);
1436 check_level_length (fixture->filter, NULL, 1);
1438 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1439 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1440 set_path_visibility (fixture, "2:2:1", TRUE);
1441 set_path_visibility (fixture, "2:2", TRUE);
1442 check_filter_model_with_root (fixture, path);
1443 check_level_length (fixture->filter, NULL, 2);
1444 check_level_length (fixture->filter, "0", 2);
1445 check_level_length (fixture->filter, "0:1", 0);
1450 unfiltered_hide_single (FilterTest *fixture,
1451 gconstpointer user_data)
1454 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1455 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1456 set_path_visibility (fixture, "2", FALSE);
1458 signal_monitor_assert_is_empty (fixture->monitor);
1459 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1461 /* The view only shows the root level, so the filter model only has
1462 * the first two levels cached.
1464 filter_test_append_refilter_signals (fixture, 2);
1465 filter_test_enable_filter (fixture);
1467 check_filter_model (fixture);
1468 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1472 unfiltered_hide_single_child (FilterTest *fixture,
1473 gconstpointer user_data)
1476 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1477 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1478 set_path_visibility (fixture, "2:2", FALSE);
1480 signal_monitor_assert_is_empty (fixture->monitor);
1481 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1482 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1484 /* The view only shows the root level, so the filter model only has
1485 * the first two levels cached.
1487 filter_test_append_refilter_signals (fixture, 2);
1488 filter_test_enable_filter (fixture);
1490 check_filter_model (fixture);
1491 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1492 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1496 unfiltered_hide_single_multi_level (FilterTest *fixture,
1497 gconstpointer user_data)
1500 /* This row is not shown, so its signal is not propagated */
1501 set_path_visibility (fixture, "2:2:2", FALSE);
1503 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1504 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1505 set_path_visibility (fixture, "2:2", FALSE);
1507 signal_monitor_assert_is_empty (fixture->monitor);
1508 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1509 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1510 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1512 /* The view only shows the root level, so the filter model only has
1513 * the first two levels cached.
1515 filter_test_append_refilter_signals (fixture, 2);
1516 filter_test_enable_filter (fixture);
1518 check_filter_model (fixture);
1519 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1520 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1522 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1523 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1524 set_path_visibility (fixture, "2:2", TRUE);
1526 check_filter_model (fixture);
1527 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1528 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1529 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1534 unfiltered_vroot_hide_single (FilterTest *fixture,
1535 gconstpointer user_data)
1538 GtkTreePath *path = (GtkTreePath *)user_data;
1540 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1541 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1542 set_path_visibility (fixture, "2:2", FALSE);
1544 signal_monitor_assert_is_empty (fixture->monitor);
1545 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1547 /* The view only shows the root level, so the filter model only has
1548 * the first two levels cached. (We add an additional level to
1549 * take the virtual root into account).
1551 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1552 filter_test_enable_filter (fixture);
1554 check_filter_model_with_root (fixture, path);
1555 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1559 unfiltered_vroot_hide_single_child (FilterTest *fixture,
1560 gconstpointer user_data)
1563 GtkTreePath *path = (GtkTreePath *)user_data;
1565 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1566 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1567 set_path_visibility (fixture, "2:2:2", FALSE);
1569 signal_monitor_assert_is_empty (fixture->monitor);
1570 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1571 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1573 /* The view only shows the root level, so the filter model only has
1574 * the first two levels cached. (We add an additional level to take
1575 * the virtual root into account).
1577 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1578 filter_test_enable_filter (fixture);
1580 check_filter_model_with_root (fixture, path);
1581 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1582 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1586 unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
1587 gconstpointer user_data)
1590 GtkTreePath *path = (GtkTreePath *)user_data;
1592 /* This row is not shown, so its signal is not propagated */
1593 set_path_visibility (fixture, "2:2:2:2", FALSE);
1595 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1596 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1597 set_path_visibility (fixture, "2:2:2", FALSE);
1599 signal_monitor_assert_is_empty (fixture->monitor);
1600 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1601 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1602 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1604 /* The view only shows the root level, so the filter model only has
1605 * the first two levels cached.
1607 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1608 filter_test_enable_filter (fixture);
1610 check_filter_model_with_root (fixture, path);
1611 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1612 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1614 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1615 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1616 set_path_visibility (fixture, "2:2:2", TRUE);
1618 check_filter_model_with_root (fixture, path);
1619 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1620 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1621 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1627 unfiltered_show_single (FilterTest *fixture,
1628 gconstpointer user_data)
1631 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1632 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1633 set_path_visibility (fixture, "2", TRUE);
1635 signal_monitor_assert_is_empty (fixture->monitor);
1636 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1638 /* The view only shows the root level, so the filter model only has
1639 * the first two levels cached.
1641 filter_test_append_refilter_signals (fixture, 2);
1642 filter_test_enable_filter (fixture);
1644 check_filter_model (fixture);
1645 check_level_length (fixture->filter, NULL, 1);
1649 unfiltered_show_single_child (FilterTest *fixture,
1650 gconstpointer user_data)
1653 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1654 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1655 set_path_visibility (fixture, "2:2", TRUE);
1657 signal_monitor_assert_is_empty (fixture->monitor);
1658 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1659 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1661 /* The view only shows the root level, so the filter model only has
1662 * the first two levels cached.
1664 filter_test_append_refilter_signals (fixture, 3);
1665 filter_test_enable_filter (fixture);
1667 check_filter_model (fixture);
1668 check_level_length (fixture->filter, NULL, 0);
1670 /* From here we are filtered, "2" in the real model is "0" in the filter
1673 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1674 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1675 set_path_visibility (fixture, "2", TRUE);
1676 signal_monitor_assert_is_empty (fixture->monitor);
1677 check_level_length (fixture->filter, NULL, 1);
1678 check_level_length (fixture->filter, "0", 1);
1682 unfiltered_show_single_multi_level (FilterTest *fixture,
1683 gconstpointer user_data)
1686 /* The view is not showing this row (collapsed state), so it is not
1687 * referenced. The signal should not go through.
1689 set_path_visibility (fixture, "2:2:2", TRUE);
1691 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1692 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1693 set_path_visibility (fixture, "2:2", TRUE);
1695 signal_monitor_assert_is_empty (fixture->monitor);
1696 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1697 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1698 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1700 /* The view only shows the root level, so the filter model only has
1701 * the first two levels cached.
1703 filter_test_append_refilter_signals (fixture, 3);
1704 filter_test_enable_filter (fixture);
1706 check_filter_model (fixture);
1707 check_level_length (fixture->filter, NULL, 0);
1709 /* From here we are filtered, "2" in the real model is "0" in the filter
1712 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1713 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1714 set_path_visibility (fixture, "2", TRUE);
1715 check_filter_model (fixture);
1716 check_level_length (fixture->filter, NULL, 1);
1717 check_level_length (fixture->filter, "0", 1);
1718 check_level_length (fixture->filter, "0:0", 1);
1723 unfiltered_vroot_show_single (FilterTest *fixture,
1724 gconstpointer user_data)
1727 GtkTreePath *path = (GtkTreePath *)user_data;
1729 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1730 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1731 set_path_visibility (fixture, "2:2", TRUE);
1733 signal_monitor_assert_is_empty (fixture->monitor);
1734 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1736 /* The view only shows the root level, so the filter model only has
1737 * the first two levels cached.
1739 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1740 filter_test_enable_filter (fixture);
1742 check_filter_model_with_root (fixture, path);
1743 check_level_length (fixture->filter, NULL, 1);
1747 unfiltered_vroot_show_single_child (FilterTest *fixture,
1748 gconstpointer user_data)
1751 GtkTreePath *path = (GtkTreePath *)user_data;
1753 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1754 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1755 set_path_visibility (fixture, "2:2:2", TRUE);
1757 signal_monitor_assert_is_empty (fixture->monitor);
1758 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1759 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1761 /* The view only shows the root level, so the filter model only has
1762 * the first two levels cached.
1764 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1765 filter_test_enable_filter (fixture);
1767 check_filter_model_with_root (fixture, path);
1768 check_level_length (fixture->filter, NULL, 0);
1770 /* From here we are filtered, "2" in the real model is "0" in the filter
1773 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1774 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1775 set_path_visibility (fixture, "2:2", TRUE);
1776 signal_monitor_assert_is_empty (fixture->monitor);
1777 check_level_length (fixture->filter, NULL, 1);
1778 check_level_length (fixture->filter, "0", 1);
1782 unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
1783 gconstpointer user_data)
1786 GtkTreePath *path = (GtkTreePath *)user_data;
1788 /* The view is not showing this row (collapsed state), so it is not
1789 * referenced. The signal should not go through.
1791 set_path_visibility (fixture, "2:2:2:2", TRUE);
1793 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1794 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1795 set_path_visibility (fixture, "2:2:2", TRUE);
1797 signal_monitor_assert_is_empty (fixture->monitor);
1798 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1799 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1800 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1802 /* The view only shows the root level, so the filter model only has
1803 * the first two levels cached.
1805 filter_test_append_refilter_signals_with_vroot (fixture, 4, path);
1806 filter_test_enable_filter (fixture);
1808 check_filter_model_with_root (fixture, path);
1809 check_level_length (fixture->filter, NULL, 0);
1811 /* From here we are filtered, "2" in the real model is "0" in the filter
1814 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1815 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1816 set_path_visibility (fixture, "2:2", TRUE);
1817 check_filter_model_with_root (fixture, path);
1818 check_level_length (fixture->filter, NULL, 1);
1819 check_level_length (fixture->filter, "0", 1);
1820 check_level_length (fixture->filter, "0:0", 1);
1825 specific_remove_node (void)
1827 GtkTreeIter iter, iter1, iter2, iter3;
1829 GtkTreeModel *filter;
1830 GtkWidget *view G_GNUC_UNUSED;
1832 list = gtk_list_store_new (1, G_TYPE_INT);
1833 gtk_list_store_insert_with_values (list, &iter1, 0, 0, 1, -1);
1834 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
1835 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
1836 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
1837 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
1838 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
1839 gtk_list_store_insert_with_values (list, &iter2, 6, 0, 7, -1);
1840 gtk_list_store_insert_with_values (list, &iter3, 7, 0, 8, -1);
1842 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
1843 view = gtk_tree_view_new_with_model (filter);
1845 gtk_list_store_remove (list, &iter1);
1846 gtk_list_store_remove (list, &iter3);
1847 gtk_list_store_remove (list, &iter2);
1851 specific_remove_node_vroot (void)
1853 GtkTreeIter parent, root;
1854 GtkTreeIter iter, iter1, iter2, iter3;
1856 GtkTreeModel *filter;
1858 GtkWidget *view G_GNUC_UNUSED;
1860 tree = gtk_tree_store_new (1, G_TYPE_INT);
1861 gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
1862 gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
1864 gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
1865 gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
1866 gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
1867 gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
1868 gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
1869 gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
1870 gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
1871 gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
1873 path = gtk_tree_path_new_from_indices (0, 0, -1);
1874 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
1875 gtk_tree_path_free (path);
1877 view = gtk_tree_view_new_with_model (filter);
1879 gtk_tree_store_remove (tree, &iter1);
1880 gtk_tree_store_remove (tree, &iter3);
1881 gtk_tree_store_remove (tree, &iter2);
1885 specific_remove_vroot_ancestor (void)
1887 GtkTreeIter parent, root;
1888 GtkTreeIter iter, iter1, iter2, iter3;
1890 GtkTreeModel *filter;
1892 GtkWidget *view G_GNUC_UNUSED;
1894 tree = gtk_tree_store_new (1, G_TYPE_INT);
1895 gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
1896 gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
1898 gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
1899 gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
1900 gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
1901 gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
1902 gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
1903 gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
1904 gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
1905 gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
1907 path = gtk_tree_path_new_from_indices (0, 0, -1);
1908 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
1909 gtk_tree_path_free (path);
1911 view = gtk_tree_view_new_with_model (filter);
1913 gtk_tree_store_remove (tree, &parent);
1918 specific_path_dependent_filter_func (GtkTreeModel *model,
1924 path = gtk_tree_model_get_path (model, iter);
1925 if (gtk_tree_path_get_indices (path)[0] < 4)
1932 specific_path_dependent_filter (void)
1938 GtkTreeModel *filter;
1940 list = gtk_list_store_new (1, G_TYPE_INT);
1941 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
1942 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
1943 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
1944 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
1945 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
1946 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
1947 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
1948 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
1950 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
1951 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
1952 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1953 specific_path_dependent_filter_func,
1956 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
1957 GTK_SORT_DESCENDING);
1959 for (i = 0; i < 4; i++)
1961 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1963 gtk_list_store_remove (list, &iter);
1965 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1967 gtk_list_store_remove (list, &iter);
1973 specific_append_after_collapse_visible_func (GtkTreeModel *model,
1978 gboolean hide_negative_numbers;
1980 gtk_tree_model_get (model, iter, 1, &number, -1);
1981 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
1983 return (number >= 0 || !hide_negative_numbers);
1987 specific_append_after_collapse (void)
1989 /* This test is based on one of the test cases I found in my
1990 * old test cases directory. I unfortunately do not have a record
1991 * from who this test case originated. -Kris.
1995 * - Show tree, expand, collapse.
2000 GtkTreeIter child_iter;
2001 GtkTreeIter child_iter2;
2002 GtkTreePath *append_path;
2003 GtkTreeStore *store;
2004 GtkTreeModel *filter;
2008 GtkWidget *tree_view;
2010 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
2012 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2013 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
2014 GINT_TO_POINTER (FALSE));
2015 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2016 specific_append_after_collapse_visible_func,
2019 sort = gtk_tree_model_sort_new_with_model (filter);
2021 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2022 tree_view = gtk_tree_view_new_with_model (sort);
2023 gtk_container_add (GTK_CONTAINER (window), tree_view);
2024 gtk_widget_realize (tree_view);
2026 while (gtk_events_pending ())
2027 gtk_main_iteration ();
2029 gtk_tree_store_prepend (store, &iter, NULL);
2030 gtk_tree_store_set (store, &iter,
2031 0, "hallo", 1, 1, -1);
2033 gtk_tree_store_append (store, &child_iter, &iter);
2034 gtk_tree_store_set (store, &child_iter,
2035 0, "toemaar", 1, 1, -1);
2037 gtk_tree_store_append (store, &child_iter2, &child_iter);
2038 gtk_tree_store_set (store, &child_iter2,
2039 0, "very deep", 1, 1, -1);
2041 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
2043 gtk_tree_store_append (store, &child_iter, &iter);
2044 gtk_tree_store_set (store, &child_iter,
2045 0, "sja", 1, 1, -1);
2047 gtk_tree_store_append (store, &child_iter, &iter);
2048 gtk_tree_store_set (store, &child_iter,
2049 0, "some word", 1, -1, -1);
2051 /* Expand and collapse the tree */
2052 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2053 while (gtk_events_pending ())
2054 gtk_main_iteration ();
2056 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
2057 while (gtk_events_pending ())
2058 gtk_main_iteration ();
2060 /* Add another it */
2061 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
2062 GINT_TO_POINTER (TRUE));
2064 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
2066 gtk_tree_store_append (store, &child_iter, &iter);
2067 gtk_tree_store_set (store, &child_iter,
2068 0, "new new new !!", 1, 1, -1);
2070 gtk_tree_path_free (append_path);
2073 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2074 while (gtk_events_pending ())
2075 gtk_main_iteration ();
2080 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
2089 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
2095 /* Do reference the model */
2096 gtk_tree_model_get (model, iter, 0, &item, -1);
2103 specific_sort_filter_remove_node (void)
2105 /* This test is based on one of the test cases I found in my
2106 * old test cases directory. I unfortunately do not have a record
2107 * from who this test case originated. -Kris.
2110 * - Create tree store, sort, filter models. The sort model has
2111 * a default sort func that is enabled, filter model a visible func
2112 * that defaults to returning FALSE.
2113 * - Remove a node from the tree store.
2117 GtkTreeStore *store;
2118 GtkTreeModel *filter;
2122 GtkWidget *tree_view;
2124 store = gtk_tree_store_new (1, G_TYPE_STRING);
2125 gtk_tree_store_append (store, &iter, NULL);
2126 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
2128 gtk_tree_store_append (store, &iter, NULL);
2129 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
2131 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2132 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
2133 specific_sort_filter_remove_node_compare_func, NULL, NULL);
2135 filter = gtk_tree_model_filter_new (sort, NULL);
2136 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2137 specific_sort_filter_remove_node_visible_func,
2141 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2142 tree_view = gtk_tree_view_new_with_model (filter);
2143 gtk_container_add (GTK_CONTAINER (window), tree_view);
2144 gtk_widget_realize (tree_view);
2146 while (gtk_events_pending ())
2147 gtk_main_iteration ();
2150 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
2151 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
2152 gtk_tree_store_remove (store, &iter);
2154 while (gtk_events_pending ())
2155 gtk_main_iteration ();
2160 specific_sort_filter_remove_root (void)
2162 /* This test is based on one of the test cases I found in my
2163 * old test cases directory. I unfortunately do not have a record
2164 * from who this test case originated. -Kris.
2167 GtkTreeModel *model, *sort, *filter;
2168 GtkTreeIter root, mid, leaf;
2171 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
2172 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
2173 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
2174 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
2176 path = gtk_tree_model_get_path (model, &mid);
2178 sort = gtk_tree_model_sort_new_with_model (model);
2179 filter = gtk_tree_model_filter_new (sort, path);
2181 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
2183 g_object_unref (filter);
2184 g_object_unref (sort);
2185 g_object_unref (model);
2190 specific_root_mixed_visibility (void)
2193 GtkTreeModel *filter;
2194 /* A bit nasty, apologies */
2197 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2199 for (i = 0; i < LEVEL_LENGTH; i++)
2203 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
2205 create_tree_store_set_values (fixture.store, &iter, TRUE);
2207 create_tree_store_set_values (fixture.store, &iter, FALSE);
2210 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
2211 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
2212 fixture.monitor = NULL;
2214 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
2216 /* In order to trigger the potential bug, we should not access
2217 * the filter model here (so don't call the check functions).
2220 /* Change visibility of an odd row to TRUE */
2221 set_path_visibility (&fixture, "3", TRUE);
2222 check_filter_model (&fixture);
2223 check_level_length (fixture.filter, NULL, 4);
2229 specific_has_child_filter_filter_func (GtkTreeModel *model,
2233 return gtk_tree_model_iter_has_child (model, iter);
2237 specific_has_child_filter (void)
2239 GtkTreeModel *filter;
2240 GtkTreeIter iter, root;
2241 /* A bit nasty, apologies */
2244 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2245 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
2246 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
2247 fixture.monitor = NULL;
2249 /* We will filter on parent state using a filter function. We will
2250 * manually keep the boolean column in sync, so that we can use
2251 * check_filter_model() to check the consistency of the model.
2253 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
2254 * to be able to check the structure here. We keep the calls to
2255 * check_filter_model() commented out until then.
2257 gtk_tree_model_filter_set_visible_func (fixture.filter,
2258 specific_has_child_filter_filter_func,
2261 gtk_tree_store_append (fixture.store, &root, NULL);
2262 create_tree_store_set_values (fixture.store, &root, FALSE);
2264 /* check_filter_model (&fixture); */
2265 check_level_length (fixture.filter, NULL, 0);
2267 gtk_tree_store_append (fixture.store, &iter, &root);
2268 create_tree_store_set_values (fixture.store, &iter, TRUE);
2270 /* Parent must now be visible. Do the level length check first,
2271 * to avoid modifying the child model triggering a row-changed to
2274 check_level_length (fixture.filter, NULL, 1);
2275 check_level_length (fixture.filter, "0", 0);
2277 set_path_visibility (&fixture, "0", TRUE);
2278 /* check_filter_model (&fixture); */
2280 gtk_tree_store_append (fixture.store, &root, NULL);
2281 check_level_length (fixture.filter, NULL, 1);
2283 gtk_tree_store_append (fixture.store, &iter, &root);
2284 check_level_length (fixture.filter, NULL, 2);
2285 check_level_length (fixture.filter, "1", 0);
2287 create_tree_store_set_values (fixture.store, &root, TRUE);
2288 create_tree_store_set_values (fixture.store, &iter, TRUE);
2290 /* check_filter_model (&fixture); */
2292 gtk_tree_store_append (fixture.store, &iter, &root);
2293 create_tree_store_set_values (fixture.store, &iter, TRUE);
2294 check_level_length (fixture.filter, NULL, 2);
2295 check_level_length (fixture.filter, "0", 0);
2296 check_level_length (fixture.filter, "1", 0);
2298 /* Now remove one of the remaining child rows */
2299 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
2301 gtk_tree_store_remove (fixture.store, &iter);
2303 check_level_length (fixture.filter, NULL, 1);
2304 check_level_length (fixture.filter, "0", 0);
2306 set_path_visibility (&fixture, "0", FALSE);
2307 /* check_filter_model (&fixture); */
2312 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
2319 path = gtk_tree_model_get_path (model, iter);
2320 depth = gtk_tree_path_get_depth (path);
2321 gtk_tree_path_free (path);
2326 return gtk_tree_model_iter_has_child (model, iter);
2330 specific_root_has_child_filter (void)
2332 GtkTreeModel *filter;
2333 GtkTreeIter iter, root;
2334 /* A bit nasty, apologies */
2337 /* This is a variation on the above test case wherein the has-child
2338 * check for visibility only applies to root level nodes.
2341 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2342 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
2343 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
2344 fixture.monitor = NULL;
2346 /* We will filter on parent state using a filter function. We will
2347 * manually keep the boolean column in sync, so that we can use
2348 * check_filter_model() to check the consistency of the model.
2350 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
2351 * to be able to check the structure here. We keep the calls to
2352 * check_filter_model() commented out until then.
2354 gtk_tree_model_filter_set_visible_func (fixture.filter,
2355 specific_root_has_child_filter_filter_func,
2358 gtk_tree_store_append (fixture.store, &root, NULL);
2359 create_tree_store_set_values (fixture.store, &root, FALSE);
2361 /* check_filter_model (&fixture); */
2362 check_level_length (fixture.filter, NULL, 0);
2364 gtk_tree_store_append (fixture.store, &iter, &root);
2365 create_tree_store_set_values (fixture.store, &iter, TRUE);
2367 /* Parent must now be visible. Do the level length check first,
2368 * to avoid modifying the child model triggering a row-changed to
2371 check_level_length (fixture.filter, NULL, 1);
2372 check_level_length (fixture.filter, "0", 1);
2374 set_path_visibility (&fixture, "0", TRUE);
2375 /* check_filter_model (&fixture); */
2377 gtk_tree_store_append (fixture.store, &root, NULL);
2378 check_level_length (fixture.filter, NULL, 1);
2380 gtk_tree_store_append (fixture.store, &iter, &root);
2381 check_level_length (fixture.filter, NULL, 2);
2382 check_level_length (fixture.filter, "1", 1);
2384 create_tree_store_set_values (fixture.store, &root, TRUE);
2385 create_tree_store_set_values (fixture.store, &iter, TRUE);
2387 /* check_filter_model (&fixture); */
2389 gtk_tree_store_append (fixture.store, &iter, &root);
2390 create_tree_store_set_values (fixture.store, &iter, TRUE);
2391 check_level_length (fixture.filter, NULL, 2);
2392 check_level_length (fixture.filter, "0", 1);
2393 check_level_length (fixture.filter, "1", 2);
2395 /* Now remove one of the remaining child rows */
2396 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
2398 gtk_tree_store_remove (fixture.store, &iter);
2400 check_level_length (fixture.filter, NULL, 1);
2401 check_level_length (fixture.filter, "0", 2);
2403 set_path_visibility (&fixture, "0", FALSE);
2404 /* check_filter_model (&fixture); */
2409 specific_filter_add_child (void)
2411 /* This test is based on one of the test cases I found in my
2412 * old test cases directory. I unfortunately do not have a record
2413 * from who this test case originated. -Kris.
2417 GtkTreeIter iter_first;
2419 GtkTreeStore *store;
2420 GtkTreeModel *filter G_GNUC_UNUSED;
2422 store = gtk_tree_store_new (1, G_TYPE_STRING);
2424 gtk_tree_store_append (store, &iter_first, NULL);
2425 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
2427 gtk_tree_store_append (store, &iter, NULL);
2428 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2430 gtk_tree_store_append (store, &iter, NULL);
2431 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2433 gtk_tree_store_append (store, &iter, NULL);
2434 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2436 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2438 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2439 gtk_tree_store_append (store, &child, &iter_first);
2440 gtk_tree_store_set (store, &child, 0, "Hello", -1);
2444 specific_list_store_clear (void)
2448 GtkTreeModel *filter;
2449 GtkWidget *view G_GNUC_UNUSED;
2451 list = gtk_list_store_new (1, G_TYPE_INT);
2452 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
2453 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
2454 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
2455 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
2456 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
2457 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
2458 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
2459 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
2461 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
2462 view = gtk_tree_view_new_with_model (filter);
2464 gtk_list_store_clear (list);
2468 specific_sort_ref_leaf_and_remove_ancestor (void)
2470 GtkTreeIter iter, child, child2, child3;
2474 GtkTreeRowReference *rowref;
2475 GtkWidget *view G_GNUC_UNUSED;
2477 tree = gtk_tree_store_new (1, G_TYPE_INT);
2478 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
2479 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
2480 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
2481 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
2483 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
2484 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
2485 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
2487 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
2488 view = gtk_tree_view_new_with_model (sort);
2489 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
2491 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
2492 rowref = gtk_tree_row_reference_new (sort, path);
2493 gtk_tree_path_free (path);
2495 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
2496 rowref = gtk_tree_row_reference_new (sort, path);
2497 gtk_tree_path_free (path);
2499 path = gtk_tree_path_new_from_indices (3, 0, -1);
2500 rowref = gtk_tree_row_reference_new (sort, path);
2501 gtk_tree_path_free (path);
2503 path = gtk_tree_path_new_from_indices (3, -1);
2504 rowref = gtk_tree_row_reference_new (sort, path);
2505 gtk_tree_path_free (path);
2507 /* Deleting a parent */
2508 path = gtk_tree_path_new_from_indices (3, 0, -1);
2509 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
2510 gtk_tree_store_remove (tree, &iter);
2511 gtk_tree_path_free (path);
2513 gtk_tree_row_reference_free (rowref);
2517 specific_ref_leaf_and_remove_ancestor (void)
2519 GtkTreeIter iter, child, child2, child3;
2521 GtkTreeModel *filter;
2523 GtkTreeRowReference *rowref;
2524 GtkWidget *view G_GNUC_UNUSED;
2526 tree = gtk_tree_store_new (1, G_TYPE_INT);
2527 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
2528 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
2529 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
2530 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
2532 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
2533 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
2534 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
2536 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), NULL);
2537 view = gtk_tree_view_new_with_model (filter);
2538 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
2540 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
2541 rowref = gtk_tree_row_reference_new (filter, path);
2542 gtk_tree_path_free (path);
2544 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
2545 rowref = gtk_tree_row_reference_new (filter, path);
2546 gtk_tree_path_free (path);
2548 path = gtk_tree_path_new_from_indices (3, 0, -1);
2549 rowref = gtk_tree_row_reference_new (filter, path);
2550 gtk_tree_path_free (path);
2552 path = gtk_tree_path_new_from_indices (3, -1);
2553 rowref = gtk_tree_row_reference_new (filter, path);
2554 gtk_tree_path_free (path);
2556 /* Deleting a parent */
2557 path = gtk_tree_path_new_from_indices (3, 0, -1);
2558 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
2559 gtk_tree_store_remove (tree, &iter);
2560 gtk_tree_path_free (path);
2562 gtk_tree_row_reference_free (rowref);
2566 specific_virtual_ref_leaf_and_remove_ancestor (void)
2568 GtkTreeIter iter, child, child2, child3;
2570 GtkTreeModel *filter;
2572 GtkTreeRowReference *rowref;
2573 GtkWidget *view G_GNUC_UNUSED;
2575 tree = gtk_tree_store_new (1, G_TYPE_INT);
2576 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
2577 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
2578 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
2579 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
2581 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
2582 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
2583 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
2585 /* Set a virtual root of 3:0 */
2586 path = gtk_tree_path_new_from_indices (3, 0, -1);
2587 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
2588 gtk_tree_path_free (path);
2590 view = gtk_tree_view_new_with_model (filter);
2591 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
2593 path = gtk_tree_path_new_from_indices (0, 0, -1);
2594 rowref = gtk_tree_row_reference_new (filter, path);
2595 gtk_tree_path_free (path);
2597 path = gtk_tree_path_new_from_indices (0, 0, -1);
2598 rowref = gtk_tree_row_reference_new (filter, path);
2599 gtk_tree_path_free (path);
2601 path = gtk_tree_path_new_from_indices (0, -1);
2602 rowref = gtk_tree_row_reference_new (filter, path);
2603 gtk_tree_path_free (path);
2605 /* Deleting the virtual root */
2606 path = gtk_tree_path_new_from_indices (3, 0, -1);
2607 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
2608 gtk_tree_store_remove (tree, &iter);
2609 gtk_tree_path_free (path);
2611 gtk_tree_row_reference_free (rowref);
2616 specific_bug_301558_sort_func (GtkTreeModel *model,
2623 gtk_tree_model_get (model, a, 0, &i, -1);
2624 gtk_tree_model_get (model, b, 0, &j, -1);
2630 specific_bug_301558 (void)
2632 /* Test case for GNOME Bugzilla bug 301558 provided by
2636 GtkTreeModel *filter;
2638 GtkTreeIter root, iter, iter2;
2639 GtkWidget *view G_GNUC_UNUSED;
2643 g_test_bug ("301558");
2645 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
2646 gtk_tree_store_append (tree, &iter, NULL);
2647 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
2648 gtk_tree_store_append (tree, &iter2, &iter);
2649 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
2651 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
2652 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
2653 specific_bug_301558_sort_func,
2656 filter = gtk_tree_model_filter_new (sort, NULL);
2657 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
2659 view = gtk_tree_view_new_with_model (filter);
2661 while (gtk_events_pending ())
2662 gtk_main_iteration ();
2666 for (i = 0; i < 10; i++)
2668 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
2669 g_assert_not_reached ();
2673 gtk_tree_store_append (tree, &iter, &root);
2674 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
2679 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
2680 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
2682 gtk_tree_store_remove (tree, &iter);
2691 specific_bug_311955_filter_func (GtkTreeModel *model,
2697 gtk_tree_model_get (model, iter, 0, &value, -1);
2699 return (value != 0);
2703 specific_bug_311955 (void)
2705 /* This is a test case for GNOME Bugzilla bug 311955. It was written
2708 GtkTreeIter iter, child, root;
2709 GtkTreeStore *store;
2711 GtkTreeModel *filter;
2713 GtkWidget *window G_GNUC_UNUSED;
2714 GtkWidget *tree_view;
2718 g_test_bug ("311955");
2720 store = gtk_tree_store_new (1, G_TYPE_INT);
2722 gtk_tree_store_append (store, &root, NULL);
2723 gtk_tree_store_set (store, &root, 0, 33, -1);
2725 gtk_tree_store_append (store, &iter, &root);
2726 gtk_tree_store_set (store, &iter, 0, 50, -1);
2728 gtk_tree_store_append (store, &iter, NULL);
2729 gtk_tree_store_set (store, &iter, 0, 22, -1);
2731 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2732 filter = gtk_tree_model_filter_new (sort, NULL);
2734 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2735 specific_bug_311955_filter_func,
2738 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2739 tree_view = gtk_tree_view_new_with_model (filter);
2740 g_object_unref (store);
2742 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2744 while (gtk_events_pending ())
2745 gtk_main_iteration ();
2748 for (i = 0; i < 4; i++)
2750 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2752 gtk_tree_store_append (store, &iter, &root);
2755 gtk_tree_store_set (store, &iter, 0, i, -1);
2759 gtk_tree_store_append (store, &child, &iter);
2760 gtk_tree_store_set (store, &child, 0, 10, -1);
2764 while (gtk_events_pending ())
2765 gtk_main_iteration ();
2767 /* Remove bottommost child from the tree. */
2768 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2769 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
2771 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
2773 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
2774 gtk_tree_store_remove (store, &child);
2777 g_assert_not_reached ();
2781 specific_bug_346800 (void)
2783 /* This is a test case for GNOME Bugzilla bug 346800. It was written
2784 * by Jonathan Matthew.
2787 GtkTreeIter node_iters[50];
2788 GtkTreeIter child_iters[50];
2789 GtkTreeModel *model;
2790 GtkTreeModelFilter *filter;
2791 GtkTreeStore *store;
2795 columns = g_new (GType, 2);
2796 columns[0] = G_TYPE_STRING;
2797 columns[1] = G_TYPE_BOOLEAN;
2798 store = gtk_tree_store_newv (2, columns);
2799 model = GTK_TREE_MODEL (store);
2801 g_test_bug ("346800");
2803 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
2804 gtk_tree_model_filter_set_visible_column (filter, 1);
2806 for (i=0; i<items; i++)
2808 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
2811 gtk_tree_store_append (store, &node_iters[i], NULL);
2812 gtk_tree_store_set (store, &node_iters[i],
2814 1, ((i%6) == 0) ? FALSE : TRUE,
2818 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
2819 gtk_tree_store_set (store, &child_iters[i],
2820 0, "something else",
2823 gtk_tree_model_filter_refilter (filter);
2827 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
2828 (i & 1) ? TRUE : FALSE, -1);
2829 gtk_tree_model_filter_refilter (filter);
2831 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
2832 (i & 1) ? FALSE: TRUE, -1);
2833 gtk_tree_model_filter_refilter (filter);
2839 specific_bug_464173_visible_func (GtkTreeModel *model,
2843 gboolean *visible = (gboolean *)data;
2849 specific_bug_464173 (void)
2851 /* Test case for GNOME Bugzilla bug 464173, test case written
2852 * by Andreas Koehler.
2854 GtkTreeStore *model;
2855 GtkTreeModelFilter *f_model;
2856 GtkTreeIter iter1, iter2;
2857 GtkWidget *view G_GNUC_UNUSED;
2858 gboolean visible = TRUE;
2860 g_test_bug ("464173");
2862 model = gtk_tree_store_new (1, G_TYPE_STRING);
2863 gtk_tree_store_append (model, &iter1, NULL);
2864 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
2865 gtk_tree_store_append (model, &iter2, &iter1);
2866 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
2868 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
2869 gtk_tree_model_filter_set_visible_func (f_model,
2870 specific_bug_464173_visible_func,
2873 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
2876 gtk_tree_model_filter_refilter (f_model);
2881 specific_bug_540201_filter_func (GtkTreeModel *model,
2885 gboolean has_children;
2887 has_children = gtk_tree_model_iter_has_child (model, iter);
2889 return has_children;
2893 specific_bug_540201 (void)
2895 /* Test case for GNOME Bugzilla bug 540201, steps provided by
2898 GtkTreeIter iter, root;
2899 GtkTreeStore *store;
2900 GtkTreeModel *filter;
2902 GtkWidget *tree_view G_GNUC_UNUSED;
2904 g_test_bug ("540201");
2906 store = gtk_tree_store_new (1, G_TYPE_INT);
2908 gtk_tree_store_append (store, &root, NULL);
2909 gtk_tree_store_set (store, &root, 0, 33, -1);
2911 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2912 tree_view = gtk_tree_view_new_with_model (filter);
2914 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2915 specific_bug_540201_filter_func,
2918 gtk_tree_store_append (store, &iter, &root);
2919 gtk_tree_store_set (store, &iter, 0, 50, -1);
2921 gtk_tree_store_append (store, &iter, &root);
2922 gtk_tree_store_set (store, &iter, 0, 22, -1);
2925 gtk_tree_store_append (store, &root, NULL);
2926 gtk_tree_store_set (store, &root, 0, 33, -1);
2928 gtk_tree_store_append (store, &iter, &root);
2929 gtk_tree_store_set (store, &iter, 0, 22, -1);
2934 specific_bug_549287_visible_func (GtkTreeModel *model,
2938 gboolean result = FALSE;
2940 result = gtk_tree_model_iter_has_child (model, iter);
2946 specific_bug_549287 (void)
2948 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
2951 GtkTreeStore *store;
2952 GtkTreeModel *filtered;
2953 GtkWidget *view G_GNUC_UNUSED;
2955 GtkTreeIter *swap, *parent, *child;
2957 g_test_bug ("529287");
2959 store = gtk_tree_store_new (1, G_TYPE_STRING);
2960 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2961 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
2962 specific_bug_549287_visible_func,
2965 view = gtk_tree_view_new_with_model (filtered);
2967 for (i = 0; i < 4; i++)
2969 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
2971 parent = gtk_tree_iter_copy (&iter);
2972 child = gtk_tree_iter_copy (&iter);
2974 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
2983 gtk_tree_store_append (store, child, parent);
2984 gtk_tree_store_set (store, child,
2988 gtk_tree_iter_free (parent);
2989 gtk_tree_iter_free (child);
2993 gtk_tree_store_append (store, &iter, NULL);
2994 gtk_tree_store_set (store, &iter,
2999 /* since we inserted something, we changed the visibility conditions: */
3000 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
3007 register_filter_model_tests (void)
3009 g_test_add ("/TreeModelFilter/self/verify-test-suite",
3013 filter_test_teardown);
3015 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-1",
3016 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3018 verify_test_suite_vroot,
3019 filter_test_teardown);
3020 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-2",
3021 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
3023 verify_test_suite_vroot,
3024 filter_test_teardown);
3027 g_test_add ("/TreeModelFilter/filled/hide-root-level",
3030 filled_hide_root_level,
3031 filter_test_teardown);
3032 g_test_add ("/TreeModelFilter/filled/hide-child-levels",
3035 filled_hide_child_levels,
3036 filter_test_teardown);
3038 g_test_add ("/TreeModelFilter/filled/hide-root-level/vroot",
3039 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3041 filled_vroot_hide_root_level,
3042 filter_test_teardown);
3043 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot",
3044 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3046 filled_vroot_hide_child_levels,
3047 filter_test_teardown);
3050 g_test_add ("/TreeModelFilter/empty/show-nodes",
3052 filter_test_setup_empty,
3054 filter_test_teardown);
3055 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes",
3057 filter_test_setup_empty,
3058 empty_show_multiple_nodes,
3059 filter_test_teardown);
3061 g_test_add ("/TreeModelFilter/empty/show-nodes/vroot",
3062 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3063 filter_test_setup_empty,
3064 empty_vroot_show_nodes,
3065 filter_test_teardown);
3066 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes/vroot",
3067 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3068 filter_test_setup_empty,
3069 empty_vroot_show_multiple_nodes,
3070 filter_test_teardown);
3073 g_test_add ("/TreeModelFilter/unfiltered/hide-single",
3075 filter_test_setup_unfiltered,
3076 unfiltered_hide_single,
3077 filter_test_teardown);
3078 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child",
3080 filter_test_setup_unfiltered,
3081 unfiltered_hide_single_child,
3082 filter_test_teardown);
3083 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level",
3085 filter_test_setup_unfiltered,
3086 unfiltered_hide_single_multi_level,
3087 filter_test_teardown);
3089 g_test_add ("/TreeModelFilter/unfiltered/hide-single/vroot",
3090 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3091 filter_test_setup_unfiltered,
3092 unfiltered_vroot_hide_single,
3093 filter_test_teardown);
3094 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot",
3095 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3096 filter_test_setup_unfiltered,
3097 unfiltered_vroot_hide_single_child,
3098 filter_test_teardown);
3099 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot",
3100 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3101 filter_test_setup_unfiltered,
3102 unfiltered_vroot_hide_single_multi_level,
3103 filter_test_teardown);
3107 g_test_add ("/TreeModelFilter/unfiltered/show-single",
3109 filter_test_setup_empty_unfiltered,
3110 unfiltered_show_single,
3111 filter_test_teardown);
3112 g_test_add ("/TreeModelFilter/unfiltered/show-single-child",
3114 filter_test_setup_empty_unfiltered,
3115 unfiltered_show_single_child,
3116 filter_test_teardown);
3117 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level",
3119 filter_test_setup_empty_unfiltered,
3120 unfiltered_show_single_multi_level,
3121 filter_test_teardown);
3123 g_test_add ("/TreeModelFilter/unfiltered/show-single/vroot",
3124 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3125 filter_test_setup_empty_unfiltered,
3126 unfiltered_vroot_show_single,
3127 filter_test_teardown);
3128 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot",
3129 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3130 filter_test_setup_empty_unfiltered,
3131 unfiltered_vroot_show_single_child,
3132 filter_test_teardown);
3133 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot",
3134 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3135 filter_test_setup_empty_unfiltered,
3136 unfiltered_vroot_show_single_multi_level,
3137 filter_test_teardown);
3139 g_test_add_func ("/TreeModelFilter/specific/remove-node",
3140 specific_remove_node);
3141 g_test_add_func ("/TreeModelFilter/specific/remove-node-vroot",
3142 specific_remove_node_vroot);
3143 g_test_add_func ("/TreeModelFilter/specific/remove-vroot-ancestor",
3144 specific_remove_vroot_ancestor);
3146 g_test_add_func ("/TreeModelFilter/specific/path-dependent-filter",
3147 specific_path_dependent_filter);
3148 g_test_add_func ("/TreeModelFilter/specific/append-after-collapse",
3149 specific_append_after_collapse);
3150 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-node",
3151 specific_sort_filter_remove_node);
3152 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-root",
3153 specific_sort_filter_remove_root);
3154 g_test_add_func ("/TreeModelFilter/specific/root-mixed-visibility",
3155 specific_root_mixed_visibility);
3156 g_test_add_func ("/TreeModelFilter/specific/has-child-filter",
3157 specific_has_child_filter);
3158 g_test_add_func ("/TreeModelFilter/specific/root-has-child-filter",
3159 specific_root_has_child_filter);
3160 g_test_add_func ("/TreeModelFilter/specific/filter-add-child",
3161 specific_filter_add_child);
3162 g_test_add_func ("/TreeModelFilter/specific/list-store-clear",
3163 specific_list_store_clear);
3164 g_test_add_func ("/TreeModelFilter/specific/sort-ref-leaf-and-remove-ancestor",
3165 specific_sort_ref_leaf_and_remove_ancestor);
3166 g_test_add_func ("/TreeModelFilter/specific/ref-leaf-and-remove-ancestor",
3167 specific_ref_leaf_and_remove_ancestor);
3168 g_test_add_func ("/TreeModelFilter/specific/virtual-ref-leaf-and-remove-ancestor",
3169 specific_virtual_ref_leaf_and_remove_ancestor);
3171 g_test_add_func ("/TreeModelFilter/specific/bug-301558",
3172 specific_bug_301558);
3173 g_test_add_func ("/TreeModelFilter/specific/bug-311955",
3174 specific_bug_311955);
3175 g_test_add_func ("/TreeModelFilter/specific/bug-346800",
3176 specific_bug_346800);
3177 g_test_add_func ("/TreeModelFilter/specific/bug-464173",
3178 specific_bug_464173);
3179 g_test_add_func ("/TreeModelFilter/specific/bug-540201",
3180 specific_bug_540201);
3181 g_test_add_func ("/TreeModelFilter/specific/bug-549287",
3182 specific_bug_549287);