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 guint signal_ids[LAST_SIGNAL];
176 signal_monitor_generic_handler (SignalMonitor *m,
183 if (g_queue_is_empty (m->queue))
185 g_error ("Signal queue empty\n");
186 g_assert_not_reached ();
189 if (m->client != model)
191 g_error ("Model mismatch; expected %p, got %p\n",
193 g_assert_not_reached ();
196 s = g_queue_peek_tail (m->queue);
199 /* For debugging: output signals that are coming in. Leaks memory. */
200 g_print ("signal=%d path=%s\n", signal, gtk_tree_path_to_string (path));
203 if (s->signal != signal
204 || gtk_tree_path_compare (s->path, path) != 0)
206 gchar *path_str, *s_path_str;
208 s_path_str = gtk_tree_path_to_string (s->path);
209 path_str = gtk_tree_path_to_string (path);
211 g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n",
212 signal_name_to_string (s->signal), s_path_str,
213 signal_name_to_string (signal), path_str);
218 g_assert_not_reached ();
221 s = g_queue_pop_tail (m->queue);
227 signal_monitor_row_inserted (GtkTreeModel *model,
232 signal_monitor_generic_handler (data, ROW_INSERTED,
237 signal_monitor_row_deleted (GtkTreeModel *model,
241 signal_monitor_generic_handler (data, ROW_DELETED,
246 signal_monitor_row_changed (GtkTreeModel *model,
251 signal_monitor_generic_handler (data, ROW_CHANGED,
256 signal_monitor_row_has_child_toggled (GtkTreeModel *model,
261 signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
266 signal_monitor_rows_reordered (GtkTreeModel *model,
272 signal_monitor_generic_handler (data, ROWS_REORDERED,
276 static SignalMonitor *
277 signal_monitor_new (GtkTreeModel *client)
281 m = g_new0 (SignalMonitor, 1);
282 m->client = g_object_ref (client);
283 m->queue = g_queue_new ();
285 m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
287 G_CALLBACK (signal_monitor_row_inserted),
289 m->signal_ids[ROW_DELETED] = g_signal_connect (client,
291 G_CALLBACK (signal_monitor_row_deleted),
293 m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
295 G_CALLBACK (signal_monitor_row_changed),
297 m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
298 "row-has-child-toggled",
299 G_CALLBACK (signal_monitor_row_has_child_toggled),
301 m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
303 G_CALLBACK (signal_monitor_rows_reordered),
310 signal_monitor_free (SignalMonitor *m)
314 for (i = 0; i < LAST_SIGNAL; i++)
315 g_signal_handler_disconnect (m->client, m->signal_ids[i]);
317 g_object_unref (m->client);
320 g_queue_free (m->queue);
326 signal_monitor_assert_is_empty (SignalMonitor *m)
328 g_assert (g_queue_is_empty (m->queue));
332 signal_monitor_append_signal_path (SignalMonitor *m,
338 s = signal_new (signal, path);
339 g_queue_push_head (m->queue, s);
343 signal_monitor_append_signal (SignalMonitor *m,
345 const gchar *path_string)
350 path = gtk_tree_path_new_from_string (path_string);
352 s = signal_new (signal, path);
353 g_queue_push_head (m->queue, s);
355 gtk_tree_path_free (path);
364 GtkWidget *tree_view;
367 GtkTreeModelFilter *filter;
369 SignalMonitor *monitor;
373 filter_test_setup_generic (FilterTest *fixture,
374 gconstpointer test_data,
379 const GtkTreePath *vroot = test_data;
380 GtkTreeModel *filter;
382 fixture->store = create_tree_store (depth, !empty);
384 /* Please forgive me for casting const away. */
385 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
386 (GtkTreePath *)vroot);
387 fixture->filter = GTK_TREE_MODEL_FILTER (filter);
390 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
392 /* We need a tree view that's listening to get ref counting from that
395 fixture->tree_view = gtk_tree_view_new_with_model (filter);
397 fixture->monitor = signal_monitor_new (filter);
401 filter_test_setup (FilterTest *fixture,
402 gconstpointer test_data)
404 filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
408 filter_test_setup_empty (FilterTest *fixture,
409 gconstpointer test_data)
411 filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
415 filter_test_setup_unfiltered (FilterTest *fixture,
416 gconstpointer test_data)
418 filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
422 filter_test_setup_empty_unfiltered (FilterTest *fixture,
423 gconstpointer test_data)
425 filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
429 strip_virtual_root (GtkTreePath *path,
430 GtkTreePath *root_path)
432 GtkTreePath *real_path;
437 int depth = gtk_tree_path_get_depth (path);
438 int root_depth = gtk_tree_path_get_depth (root_path);
440 real_path = gtk_tree_path_new ();
442 for (j = 0; j < depth - root_depth; j++)
443 gtk_tree_path_append_index (real_path,
444 gtk_tree_path_get_indices (path)[root_depth + j]);
447 real_path = gtk_tree_path_copy (path);
453 filter_test_append_refilter_signals_recurse (FilterTest *fixture,
454 GtkTreePath *store_path,
455 GtkTreePath *filter_path,
457 GtkTreePath *root_path)
460 int rows_deleted = 0;
463 gtk_tree_path_down (store_path);
464 gtk_tree_path_down (filter_path);
466 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
469 for (i = 0; i < LEVEL_LENGTH; i++)
472 GtkTreePath *real_path;
474 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
479 (!gtk_tree_path_is_descendant (store_path, root_path)
480 || !gtk_tree_path_compare (store_path, root_path)))
482 if (!gtk_tree_path_compare (store_path, root_path))
485 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
488 GtkTreePath *store_copy;
489 GtkTreePath *filter_copy;
491 store_copy = gtk_tree_path_copy (store_path);
492 filter_copy = gtk_tree_path_copy (filter_path);
493 filter_test_append_refilter_signals_recurse (fixture,
498 gtk_tree_path_free (store_copy);
499 gtk_tree_path_free (filter_copy);
503 gtk_tree_path_next (store_path);
504 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
507 gtk_tree_path_next (filter_path);
512 real_path = strip_virtual_root (filter_path, root_path);
516 /* This row will be inserted */
517 signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
519 signal_monitor_append_signal_path (fixture->monitor,
520 ROW_HAS_CHILD_TOGGLED,
524 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
527 GtkTreePath *store_copy;
528 GtkTreePath *filter_copy;
530 store_copy = gtk_tree_path_copy (store_path);
531 filter_copy = gtk_tree_path_copy (filter_path);
532 filter_test_append_refilter_signals_recurse (fixture,
537 gtk_tree_path_free (store_copy);
538 gtk_tree_path_free (filter_copy);
541 gtk_tree_path_next (filter_path);
545 /* This row will be deleted */
547 signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
551 gtk_tree_path_free (real_path);
553 gtk_tree_path_next (store_path);
554 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
557 if (rows_deleted == LEVEL_LENGTH
558 && gtk_tree_path_get_depth (filter_path) > 1)
560 GtkTreePath *real_path;
562 gtk_tree_path_up (store_path);
563 gtk_tree_path_up (filter_path);
565 /* A row-has-child-toggled will be emitted on the parent */
568 && gtk_tree_path_is_descendant (store_path, root_path)
569 && gtk_tree_path_compare (store_path, root_path)))
571 real_path = strip_virtual_root (filter_path, root_path);
572 signal_monitor_append_signal_path (fixture->monitor,
573 ROW_HAS_CHILD_TOGGLED,
576 gtk_tree_path_free (real_path);
582 filter_test_append_refilter_signals (FilterTest *fixture,
585 /* A special function that walks the tree store like the
586 * model validation functions below.
589 GtkTreePath *filter_path;
591 path = gtk_tree_path_new ();
592 filter_path = gtk_tree_path_new ();
593 filter_test_append_refilter_signals_recurse (fixture,
598 gtk_tree_path_free (path);
599 gtk_tree_path_free (filter_path);
603 filter_test_append_refilter_signals_with_vroot (FilterTest *fixture,
605 GtkTreePath *root_path)
607 /* A special function that walks the tree store like the
608 * model validation functions below.
611 GtkTreePath *filter_path;
613 path = gtk_tree_path_new ();
614 filter_path = gtk_tree_path_new ();
615 filter_test_append_refilter_signals_recurse (fixture,
620 gtk_tree_path_free (path);
621 gtk_tree_path_free (filter_path);
625 filter_test_enable_filter (FilterTest *fixture)
627 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
628 gtk_tree_model_filter_refilter (fixture->filter);
632 filter_test_teardown (FilterTest *fixture,
633 gconstpointer test_data)
635 signal_monitor_free (fixture->monitor);
637 g_object_unref (fixture->filter);
638 g_object_unref (fixture->store);
642 * Model structure validation
646 check_filter_model_recurse (FilterTest *fixture,
647 GtkTreePath *store_parent_path,
648 GtkTreePath *filter_parent_path)
651 GtkTreeIter store_iter;
652 GtkTreeIter filter_iter;
653 gboolean store_has_next, filter_has_next;
655 gtk_tree_path_down (store_parent_path);
656 gtk_tree_path_down (filter_parent_path);
658 store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
659 &store_iter, store_parent_path);
660 filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
661 &filter_iter, filter_parent_path);
663 for (i = 0; i < LEVEL_LENGTH; i++)
667 g_return_if_fail (store_has_next == TRUE);
669 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
677 gchar *filter_str, *store_str;
679 g_return_if_fail (filter_has_next == TRUE);
682 tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
684 g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
686 /* Verify model content */
687 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
691 gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
696 g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
701 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
704 g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
706 check_filter_model_recurse (fixture,
707 gtk_tree_path_copy (store_parent_path),
711 gtk_tree_path_next (filter_parent_path);
712 filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
715 gtk_tree_path_next (store_parent_path);
716 store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
719 /* Both models should have no more content! */
720 g_return_if_fail (store_has_next == FALSE);
721 g_return_if_fail (filter_has_next == FALSE);
723 gtk_tree_path_free (store_parent_path);
724 gtk_tree_path_free (filter_parent_path);
728 check_filter_model (FilterTest *fixture)
732 if (fixture->monitor)
733 signal_monitor_assert_is_empty (fixture->monitor);
735 path = gtk_tree_path_new ();
737 check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
741 check_filter_model_with_root (FilterTest *fixture,
744 if (fixture->monitor)
745 signal_monitor_assert_is_empty (fixture->monitor);
747 check_filter_model_recurse (fixture,
748 gtk_tree_path_copy (path),
749 gtk_tree_path_new ());
755 check_level_length (GtkTreeModelFilter *filter,
761 int l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
762 g_return_if_fail (l == length);
767 gboolean retrieved_iter = FALSE;
770 retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
772 g_return_if_fail (retrieved_iter);
773 l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
774 g_return_if_fail (l == length);
779 set_path_visibility (FilterTest *fixture,
783 GtkTreeIter store_iter;
785 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
787 gtk_tree_store_set (fixture->store, &store_iter,
794 insert_path_with_visibility (FilterTest *fixture,
795 const gchar *path_string,
800 GtkTreeIter parent, iter;
802 path = gtk_tree_path_new_from_string (path_string);
803 position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
804 gtk_tree_path_up (path);
806 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
808 gtk_tree_store_insert (fixture->store, &iter, &parent, position);
809 create_tree_store_set_values (fixture->store, &iter, visible);
811 gtk_tree_path_free (path);
820 verify_test_suite (FilterTest *fixture,
821 gconstpointer user_data)
823 check_filter_model (fixture);
827 verify_test_suite_vroot (FilterTest *fixture,
828 gconstpointer user_data)
830 check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
835 filled_hide_root_level (FilterTest *fixture,
836 gconstpointer user_data)
838 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
839 set_path_visibility (fixture, "2", FALSE);
840 check_filter_model (fixture);
841 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
843 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
844 set_path_visibility (fixture, "0", FALSE);
845 check_filter_model (fixture);
846 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
848 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
849 set_path_visibility (fixture, "4", FALSE);
850 check_filter_model (fixture);
851 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
855 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
856 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
858 set_path_visibility (fixture, "1", FALSE);
859 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
861 set_path_visibility (fixture, "3", FALSE);
862 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
864 check_filter_model (fixture);
867 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
868 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
869 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
870 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
872 set_path_visibility (fixture, "1", TRUE);
873 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
875 set_path_visibility (fixture, "3", TRUE);
876 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
878 check_filter_model (fixture);
882 filled_hide_child_levels (FilterTest *fixture,
883 gconstpointer user_data)
885 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
886 set_path_visibility (fixture, "0:2", FALSE);
887 check_filter_model (fixture);
888 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
889 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
891 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
892 set_path_visibility (fixture, "0:4", FALSE);
893 check_filter_model (fixture);
894 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
895 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
897 set_path_visibility (fixture, "0:4:3", FALSE);
898 check_filter_model (fixture);
899 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
900 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
902 set_path_visibility (fixture, "0:4:0", FALSE);
903 set_path_visibility (fixture, "0:4:1", FALSE);
904 set_path_visibility (fixture, "0:4:2", FALSE);
905 set_path_visibility (fixture, "0:4:4", FALSE);
906 check_filter_model (fixture);
907 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
908 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
910 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
911 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
912 /* FIXME: Actually, the filter model should not be emitted the
913 * row-has-child-toggled signal here. *However* an extraneous emission
914 * of this signal does not hurt and is allowed.
916 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
917 set_path_visibility (fixture, "0:4", TRUE);
918 check_filter_model (fixture);
919 check_level_length (fixture->filter, "0:3", 0);
921 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
922 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
923 set_path_visibility (fixture, "0:2", TRUE);
924 check_filter_model (fixture);
925 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
926 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
927 check_level_length (fixture->filter, "0:4", 0);
929 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
930 /* Once 0:4:0 got inserted, 0:4 became a parent */
931 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
932 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:0");
933 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
934 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:1");
936 set_path_visibility (fixture, "0:4:2", TRUE);
937 set_path_visibility (fixture, "0:4:4", TRUE);
938 signal_monitor_assert_is_empty (fixture->monitor);
939 check_level_length (fixture->filter, "0:4", 2);
944 filled_vroot_hide_root_level (FilterTest *fixture,
945 gconstpointer user_data)
947 GtkTreePath *path = (GtkTreePath *)user_data;
949 /* These changes do not affect the filter's root level */
950 set_path_visibility (fixture, "0", FALSE);
951 check_filter_model_with_root (fixture, path);
952 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
953 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
955 set_path_visibility (fixture, "4", FALSE);
956 check_filter_model_with_root (fixture, path);
957 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
958 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
960 /* Even though we set the virtual root parent node to FALSE,
961 * the virtual root contents remain.
963 set_path_visibility (fixture, "2", FALSE);
964 check_filter_model_with_root (fixture, path);
965 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
966 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
969 set_path_visibility (fixture, "1", FALSE);
970 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
971 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
973 set_path_visibility (fixture, "3", FALSE);
974 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
975 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
977 check_filter_model_with_root (fixture, path);
980 set_path_visibility (fixture, "2", TRUE);
981 check_filter_model_with_root (fixture, path);
982 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
983 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
985 set_path_visibility (fixture, "1", TRUE);
986 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
987 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
989 set_path_visibility (fixture, "3", TRUE);
990 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
991 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
993 check_filter_model_with_root (fixture, path);
995 /* Now test changes in the virtual root level */
996 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
997 set_path_visibility (fixture, "2:2", FALSE);
998 check_filter_model_with_root (fixture, path);
999 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1001 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
1002 set_path_visibility (fixture, "2:4", FALSE);
1003 check_filter_model_with_root (fixture, path);
1004 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1006 set_path_visibility (fixture, "1:4", FALSE);
1007 check_filter_model_with_root (fixture, path);
1008 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1010 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
1011 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
1012 set_path_visibility (fixture, "2:4", TRUE);
1013 check_filter_model_with_root (fixture, path);
1014 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1016 set_path_visibility (fixture, "2", FALSE);
1017 check_filter_model_with_root (fixture, path);
1018 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1020 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1021 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1022 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1023 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1024 set_path_visibility (fixture, "2:0", FALSE);
1025 set_path_visibility (fixture, "2:1", FALSE);
1026 set_path_visibility (fixture, "2:2", FALSE);
1027 set_path_visibility (fixture, "2:3", FALSE);
1028 set_path_visibility (fixture, "2:4", FALSE);
1029 check_filter_model_with_root (fixture, path);
1030 check_level_length (fixture->filter, NULL, 0);
1032 set_path_visibility (fixture, "2", TRUE);
1033 check_filter_model_with_root (fixture, path);
1034 check_level_length (fixture->filter, NULL, 0);
1036 set_path_visibility (fixture, "1:4", FALSE);
1037 check_filter_model_with_root (fixture, path);
1038 check_level_length (fixture->filter, NULL, 0);
1040 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1041 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1042 set_path_visibility (fixture, "2:4", TRUE);
1043 check_filter_model_with_root (fixture, path);
1044 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
1046 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1047 set_path_visibility (fixture, "2:4", FALSE);
1048 check_filter_model_with_root (fixture, path);
1049 check_level_length (fixture->filter, NULL, 0);
1051 set_path_visibility (fixture, "2", FALSE);
1052 check_filter_model_with_root (fixture, path);
1053 check_level_length (fixture->filter, NULL, 0);
1055 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1056 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1057 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1058 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1059 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
1060 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1061 set_path_visibility (fixture, "2:0", TRUE);
1062 set_path_visibility (fixture, "2:1", TRUE);
1063 set_path_visibility (fixture, "2:2", TRUE);
1064 check_filter_model_with_root (fixture, path);
1065 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1067 set_path_visibility (fixture, "2", TRUE);
1068 check_filter_model_with_root (fixture, path);
1069 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1073 filled_vroot_hide_child_levels (FilterTest *fixture,
1074 gconstpointer user_data)
1076 GtkTreePath *path = (GtkTreePath *)user_data;
1078 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1079 set_path_visibility (fixture, "2:0:2", FALSE);
1080 check_filter_model_with_root (fixture, path);
1081 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1082 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1084 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1085 set_path_visibility (fixture, "2:0:4", FALSE);
1086 check_filter_model_with_root (fixture, path);
1087 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1088 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1090 set_path_visibility (fixture, "2:0:4:3", FALSE);
1091 check_filter_model_with_root (fixture, path);
1092 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1093 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1095 set_path_visibility (fixture, "2:0:4:0", FALSE);
1096 set_path_visibility (fixture, "2:0:4:1", FALSE);
1097 set_path_visibility (fixture, "2:0:4:2", FALSE);
1098 set_path_visibility (fixture, "2:0:4:4", FALSE);
1099 check_filter_model_with_root (fixture, path);
1100 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1101 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1103 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1104 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1105 /* FIXME: Actually, the filter model should not be emitted the
1106 * row-has-child-toggled signal here. *However* an extraneous emission
1107 * of this signal does not hurt and is allowed.
1109 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1110 set_path_visibility (fixture, "2:0:4", TRUE);
1111 check_filter_model_with_root (fixture, path);
1112 check_level_length (fixture->filter, "0:3", 0);
1114 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1115 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1116 set_path_visibility (fixture, "2:0:2", TRUE);
1117 check_filter_model_with_root (fixture, path);
1118 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1119 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1120 check_level_length (fixture->filter, "0:4", 0);
1122 /* FIXME: Inconsistency! For the non-vroot case we also receive two
1123 * row-has-child-toggled signals here.
1125 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
1126 /* Once 0:4:0 got inserted, 0:4 became a parent */
1127 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1128 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
1129 set_path_visibility (fixture, "2:0:4:2", TRUE);
1130 set_path_visibility (fixture, "2:0:4:4", TRUE);
1131 check_level_length (fixture->filter, "0:4", 2);
1136 empty_show_nodes (FilterTest *fixture,
1137 gconstpointer user_data)
1139 check_filter_model (fixture);
1140 check_level_length (fixture->filter, NULL, 0);
1142 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1143 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1144 set_path_visibility (fixture, "3", TRUE);
1145 check_filter_model (fixture);
1146 check_level_length (fixture->filter, NULL, 1);
1147 check_level_length (fixture->filter, "0", 0);
1149 set_path_visibility (fixture, "3:2:2", TRUE);
1150 check_filter_model (fixture);
1151 check_level_length (fixture->filter, NULL, 1);
1152 check_level_length (fixture->filter, "0", 0);
1154 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
1155 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1156 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
1157 set_path_visibility (fixture, "3:2", TRUE);
1158 check_filter_model (fixture);
1159 check_level_length (fixture->filter, NULL, 1);
1160 check_level_length (fixture->filter, "0", 1);
1161 check_level_length (fixture->filter, "0:0", 1);
1162 check_level_length (fixture->filter, "0:0:0", 0);
1164 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1165 set_path_visibility (fixture, "3", FALSE);
1166 check_filter_model (fixture);
1167 check_level_length (fixture->filter, NULL, 0);
1169 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1170 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1171 set_path_visibility (fixture, "3:2:1", TRUE);
1172 set_path_visibility (fixture, "3", TRUE);
1173 check_filter_model (fixture);
1174 check_level_length (fixture->filter, NULL, 1);
1175 check_level_length (fixture->filter, "0", 1);
1176 check_level_length (fixture->filter, "0:0", 2);
1177 check_level_length (fixture->filter, "0:0:0", 0);
1181 empty_vroot_show_nodes (FilterTest *fixture,
1182 gconstpointer user_data)
1184 GtkTreePath *path = (GtkTreePath *)user_data;
1186 check_filter_model_with_root (fixture, path);
1187 check_level_length (fixture->filter, NULL, 0);
1189 set_path_visibility (fixture, "2", TRUE);
1190 check_filter_model_with_root (fixture, path);
1191 check_level_length (fixture->filter, NULL, 0);
1193 set_path_visibility (fixture, "2:2:2", TRUE);
1194 check_filter_model_with_root (fixture, path);
1195 check_level_length (fixture->filter, NULL, 0);
1197 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1198 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1199 set_path_visibility (fixture, "2:2", TRUE);
1200 check_filter_model_with_root (fixture, path);
1201 check_level_length (fixture->filter, NULL, 1);
1202 check_level_length (fixture->filter, "0", 1);
1203 check_level_length (fixture->filter, "0:0", 0);
1205 set_path_visibility (fixture, "3", TRUE);
1206 check_filter_model_with_root (fixture, path);
1207 check_level_length (fixture->filter, NULL, 1);
1209 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1210 set_path_visibility (fixture, "2:2", FALSE);
1211 check_filter_model_with_root (fixture, path);
1212 check_level_length (fixture->filter, NULL, 0);
1214 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1215 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1216 set_path_visibility (fixture, "2:2:1", TRUE);
1217 set_path_visibility (fixture, "2:2", TRUE);
1218 check_filter_model_with_root (fixture, path);
1219 check_level_length (fixture->filter, NULL, 1);
1220 check_level_length (fixture->filter, "0", 2);
1221 check_level_length (fixture->filter, "0:1", 0);
1226 unfiltered_hide_single (FilterTest *fixture,
1227 gconstpointer user_data)
1230 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1231 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1232 set_path_visibility (fixture, "2", FALSE);
1234 signal_monitor_assert_is_empty (fixture->monitor);
1235 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1237 /* The view only shows the root level, so the filter model only has
1238 * the first two levels cached.
1240 filter_test_append_refilter_signals (fixture, 2);
1241 filter_test_enable_filter (fixture);
1243 check_filter_model (fixture);
1244 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1248 unfiltered_hide_single_child (FilterTest *fixture,
1249 gconstpointer user_data)
1252 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1253 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1254 set_path_visibility (fixture, "2:2", FALSE);
1256 signal_monitor_assert_is_empty (fixture->monitor);
1257 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1258 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1260 /* The view only shows the root level, so the filter model only has
1261 * the first two levels cached.
1263 filter_test_append_refilter_signals (fixture, 2);
1264 filter_test_enable_filter (fixture);
1266 check_filter_model (fixture);
1267 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1268 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1272 unfiltered_hide_single_multi_level (FilterTest *fixture,
1273 gconstpointer user_data)
1276 /* This row is not shown, so its signal is not propagated */
1277 set_path_visibility (fixture, "2:2:2", FALSE);
1279 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1280 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1281 set_path_visibility (fixture, "2:2", FALSE);
1283 signal_monitor_assert_is_empty (fixture->monitor);
1284 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1285 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1286 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1288 /* The view only shows the root level, so the filter model only has
1289 * the first two levels cached.
1291 filter_test_append_refilter_signals (fixture, 2);
1292 filter_test_enable_filter (fixture);
1294 check_filter_model (fixture);
1295 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1296 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1298 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1299 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1300 set_path_visibility (fixture, "2:2", TRUE);
1302 check_filter_model (fixture);
1303 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1304 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1305 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1310 unfiltered_vroot_hide_single (FilterTest *fixture,
1311 gconstpointer user_data)
1314 GtkTreePath *path = (GtkTreePath *)user_data;
1316 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1317 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1318 set_path_visibility (fixture, "2:2", FALSE);
1320 signal_monitor_assert_is_empty (fixture->monitor);
1321 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1323 /* The view only shows the root level, so the filter model only has
1324 * the first two levels cached. (We add an additional level to
1325 * take the virtual root into account).
1327 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1328 filter_test_enable_filter (fixture);
1330 check_filter_model_with_root (fixture, path);
1331 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1335 unfiltered_vroot_hide_single_child (FilterTest *fixture,
1336 gconstpointer user_data)
1339 GtkTreePath *path = (GtkTreePath *)user_data;
1341 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1342 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1343 set_path_visibility (fixture, "2:2:2", FALSE);
1345 signal_monitor_assert_is_empty (fixture->monitor);
1346 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1347 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1349 /* The view only shows the root level, so the filter model only has
1350 * the first two levels cached. (We add an additional level to take
1351 * the virtual root into account).
1353 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1354 filter_test_enable_filter (fixture);
1356 check_filter_model_with_root (fixture, path);
1357 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1358 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1362 unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
1363 gconstpointer user_data)
1366 GtkTreePath *path = (GtkTreePath *)user_data;
1368 /* This row is not shown, so its signal is not propagated */
1369 set_path_visibility (fixture, "2:2:2:2", FALSE);
1371 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1372 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1373 set_path_visibility (fixture, "2:2:2", FALSE);
1375 signal_monitor_assert_is_empty (fixture->monitor);
1376 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1377 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1378 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1380 /* The view only shows the root level, so the filter model only has
1381 * the first two levels cached.
1383 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1384 filter_test_enable_filter (fixture);
1386 check_filter_model_with_root (fixture, path);
1387 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1388 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1390 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1391 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1392 set_path_visibility (fixture, "2:2:2", TRUE);
1394 check_filter_model_with_root (fixture, path);
1395 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1396 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1397 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1403 unfiltered_show_single (FilterTest *fixture,
1404 gconstpointer user_data)
1407 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1408 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1409 set_path_visibility (fixture, "2", TRUE);
1411 signal_monitor_assert_is_empty (fixture->monitor);
1412 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1414 /* The view only shows the root level, so the filter model only has
1415 * the first two levels cached.
1417 filter_test_append_refilter_signals (fixture, 2);
1418 filter_test_enable_filter (fixture);
1420 check_filter_model (fixture);
1421 check_level_length (fixture->filter, NULL, 1);
1425 unfiltered_show_single_child (FilterTest *fixture,
1426 gconstpointer user_data)
1429 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1430 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1431 set_path_visibility (fixture, "2:2", TRUE);
1433 signal_monitor_assert_is_empty (fixture->monitor);
1434 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1435 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1437 /* The view only shows the root level, so the filter model only has
1438 * the first two levels cached.
1440 filter_test_append_refilter_signals (fixture, 3);
1441 filter_test_enable_filter (fixture);
1443 check_filter_model (fixture);
1444 check_level_length (fixture->filter, NULL, 0);
1446 /* From here we are filtered, "2" in the real model is "0" in the filter
1449 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1450 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1451 set_path_visibility (fixture, "2", TRUE);
1452 signal_monitor_assert_is_empty (fixture->monitor);
1453 check_level_length (fixture->filter, NULL, 1);
1454 check_level_length (fixture->filter, "0", 1);
1458 unfiltered_show_single_multi_level (FilterTest *fixture,
1459 gconstpointer user_data)
1462 /* The view is not showing this row (collapsed state), so it is not
1463 * referenced. The signal should not go through.
1465 set_path_visibility (fixture, "2:2:2", TRUE);
1467 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1468 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1469 set_path_visibility (fixture, "2:2", TRUE);
1471 signal_monitor_assert_is_empty (fixture->monitor);
1472 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1473 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1474 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1476 /* The view only shows the root level, so the filter model only has
1477 * the first two levels cached.
1479 filter_test_append_refilter_signals (fixture, 3);
1480 filter_test_enable_filter (fixture);
1482 check_filter_model (fixture);
1483 check_level_length (fixture->filter, NULL, 0);
1485 /* From here we are filtered, "2" in the real model is "0" in the filter
1488 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1489 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1490 set_path_visibility (fixture, "2", TRUE);
1491 check_filter_model (fixture);
1492 check_level_length (fixture->filter, NULL, 1);
1493 check_level_length (fixture->filter, "0", 1);
1494 check_level_length (fixture->filter, "0:0", 1);
1499 unfiltered_vroot_show_single (FilterTest *fixture,
1500 gconstpointer user_data)
1503 GtkTreePath *path = (GtkTreePath *)user_data;
1505 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1506 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1507 set_path_visibility (fixture, "2:2", TRUE);
1509 signal_monitor_assert_is_empty (fixture->monitor);
1510 check_level_length (fixture->filter, NULL, 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_with_vroot (fixture, 3, path);
1516 filter_test_enable_filter (fixture);
1518 check_filter_model_with_root (fixture, path);
1519 check_level_length (fixture->filter, NULL, 1);
1523 unfiltered_vroot_show_single_child (FilterTest *fixture,
1524 gconstpointer user_data)
1527 GtkTreePath *path = (GtkTreePath *)user_data;
1529 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1530 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1531 set_path_visibility (fixture, "2:2:2", TRUE);
1533 signal_monitor_assert_is_empty (fixture->monitor);
1534 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1535 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1537 /* The view only shows the root level, so the filter model only has
1538 * the first two levels cached.
1540 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1541 filter_test_enable_filter (fixture);
1543 check_filter_model_with_root (fixture, path);
1544 check_level_length (fixture->filter, NULL, 0);
1546 /* From here we are filtered, "2" in the real model is "0" in the filter
1549 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1550 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1551 set_path_visibility (fixture, "2:2", TRUE);
1552 signal_monitor_assert_is_empty (fixture->monitor);
1553 check_level_length (fixture->filter, NULL, 1);
1554 check_level_length (fixture->filter, "0", 1);
1558 unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
1559 gconstpointer user_data)
1562 GtkTreePath *path = (GtkTreePath *)user_data;
1564 /* The view is not showing this row (collapsed state), so it is not
1565 * referenced. The signal should not go through.
1567 set_path_visibility (fixture, "2:2:2:2", TRUE);
1569 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1570 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1571 set_path_visibility (fixture, "2:2:2", TRUE);
1573 signal_monitor_assert_is_empty (fixture->monitor);
1574 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1575 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1576 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1578 /* The view only shows the root level, so the filter model only has
1579 * the first two levels cached.
1581 filter_test_append_refilter_signals_with_vroot (fixture, 4, path);
1582 filter_test_enable_filter (fixture);
1584 check_filter_model_with_root (fixture, path);
1585 check_level_length (fixture->filter, NULL, 0);
1587 /* From here we are filtered, "2" in the real model is "0" in the filter
1590 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1591 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1592 set_path_visibility (fixture, "2:2", TRUE);
1593 check_filter_model_with_root (fixture, path);
1594 check_level_length (fixture->filter, NULL, 1);
1595 check_level_length (fixture->filter, "0", 1);
1596 check_level_length (fixture->filter, "0:0", 1);
1601 specific_path_dependent_filter_func (GtkTreeModel *model,
1607 path = gtk_tree_model_get_path (model, iter);
1608 if (gtk_tree_path_get_indices (path)[0] < 4)
1615 specific_path_dependent_filter (void)
1621 GtkTreeModel *filter;
1623 list = gtk_list_store_new (1, G_TYPE_INT);
1624 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
1625 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
1626 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
1627 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
1628 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
1629 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
1630 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
1631 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
1633 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
1634 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
1635 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1636 specific_path_dependent_filter_func,
1639 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
1640 GTK_SORT_DESCENDING);
1642 for (i = 0; i < 4; i++)
1644 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1646 gtk_list_store_remove (list, &iter);
1648 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1650 gtk_list_store_remove (list, &iter);
1656 specific_append_after_collapse_visible_func (GtkTreeModel *model,
1661 gboolean hide_negative_numbers;
1663 gtk_tree_model_get (model, iter, 1, &number, -1);
1664 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
1666 return (number >= 0 || !hide_negative_numbers);
1670 specific_append_after_collapse (void)
1672 /* This test is based on one of the test cases I found in my
1673 * old test cases directory. I unfortunately do not have a record
1674 * from who this test case originated. -Kris.
1678 * - Show tree, expand, collapse.
1683 GtkTreeIter child_iter;
1684 GtkTreeIter child_iter2;
1685 GtkTreePath *append_path;
1686 GtkTreeStore *store;
1687 GtkTreeModel *filter;
1691 GtkWidget *tree_view;
1693 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
1695 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
1696 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
1697 GINT_TO_POINTER (FALSE));
1698 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1699 specific_append_after_collapse_visible_func,
1702 sort = gtk_tree_model_sort_new_with_model (filter);
1704 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1705 tree_view = gtk_tree_view_new_with_model (sort);
1706 gtk_container_add (GTK_CONTAINER (window), tree_view);
1707 gtk_widget_realize (tree_view);
1709 while (gtk_events_pending ())
1710 gtk_main_iteration ();
1712 gtk_tree_store_prepend (store, &iter, NULL);
1713 gtk_tree_store_set (store, &iter,
1714 0, "hallo", 1, 1, -1);
1716 gtk_tree_store_append (store, &child_iter, &iter);
1717 gtk_tree_store_set (store, &child_iter,
1718 0, "toemaar", 1, 1, -1);
1720 gtk_tree_store_append (store, &child_iter2, &child_iter);
1721 gtk_tree_store_set (store, &child_iter2,
1722 0, "very deep", 1, 1, -1);
1724 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
1726 gtk_tree_store_append (store, &child_iter, &iter);
1727 gtk_tree_store_set (store, &child_iter,
1728 0, "sja", 1, 1, -1);
1730 gtk_tree_store_append (store, &child_iter, &iter);
1731 gtk_tree_store_set (store, &child_iter,
1732 0, "some word", 1, -1, -1);
1734 /* Expand and collapse the tree */
1735 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
1736 while (gtk_events_pending ())
1737 gtk_main_iteration ();
1739 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
1740 while (gtk_events_pending ())
1741 gtk_main_iteration ();
1743 /* Add another it */
1744 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
1745 GINT_TO_POINTER (TRUE));
1747 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
1749 gtk_tree_store_append (store, &child_iter, &iter);
1750 gtk_tree_store_set (store, &child_iter,
1751 0, "new new new !!", 1, 1, -1);
1753 gtk_tree_path_free (append_path);
1756 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
1757 while (gtk_events_pending ())
1758 gtk_main_iteration ();
1763 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
1772 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
1778 /* Do reference the model */
1779 gtk_tree_model_get (model, iter, 0, &item, -1);
1786 specific_sort_filter_remove_node (void)
1788 /* This test is based on one of the test cases I found in my
1789 * old test cases directory. I unfortunately do not have a record
1790 * from who this test case originated. -Kris.
1793 * - Create tree store, sort, filter models. The sort model has
1794 * a default sort func that is enabled, filter model a visible func
1795 * that defaults to returning FALSE.
1796 * - Remove a node from the tree store.
1800 GtkTreeStore *store;
1801 GtkTreeModel *filter;
1805 GtkWidget *tree_view;
1807 store = gtk_tree_store_new (1, G_TYPE_STRING);
1808 gtk_tree_store_append (store, &iter, NULL);
1809 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
1811 gtk_tree_store_append (store, &iter, NULL);
1812 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
1814 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
1815 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
1816 specific_sort_filter_remove_node_compare_func, NULL, NULL);
1818 filter = gtk_tree_model_filter_new (sort, NULL);
1819 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1820 specific_sort_filter_remove_node_visible_func,
1824 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1825 tree_view = gtk_tree_view_new_with_model (filter);
1826 gtk_container_add (GTK_CONTAINER (window), tree_view);
1827 gtk_widget_realize (tree_view);
1829 while (gtk_events_pending ())
1830 gtk_main_iteration ();
1833 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
1834 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
1835 gtk_tree_store_remove (store, &iter);
1837 while (gtk_events_pending ())
1838 gtk_main_iteration ();
1843 specific_sort_filter_remove_root (void)
1845 /* This test is based on one of the test cases I found in my
1846 * old test cases directory. I unfortunately do not have a record
1847 * from who this test case originated. -Kris.
1850 GtkTreeModel *model, *sort, *filter;
1851 GtkTreeIter root, mid, leaf;
1854 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
1855 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
1856 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
1857 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
1859 path = gtk_tree_model_get_path (model, &mid);
1861 sort = gtk_tree_model_sort_new_with_model (model);
1862 filter = gtk_tree_model_filter_new (sort, path);
1864 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
1866 g_object_unref (filter);
1867 g_object_unref (sort);
1868 g_object_unref (model);
1873 specific_root_mixed_visibility (void)
1876 GtkTreeModel *filter;
1877 /* A bit nasty, apologies */
1880 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1882 for (i = 0; i < LEVEL_LENGTH; i++)
1886 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
1888 create_tree_store_set_values (fixture.store, &iter, TRUE);
1890 create_tree_store_set_values (fixture.store, &iter, FALSE);
1893 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1894 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1895 fixture.monitor = NULL;
1897 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
1899 /* In order to trigger the potential bug, we should not access
1900 * the filter model here (so don't call the check functions).
1903 /* Change visibility of an odd row to TRUE */
1904 set_path_visibility (&fixture, "3", TRUE);
1905 check_filter_model (&fixture);
1906 check_level_length (fixture.filter, NULL, 4);
1912 specific_has_child_filter_filter_func (GtkTreeModel *model,
1916 return gtk_tree_model_iter_has_child (model, iter);
1920 specific_has_child_filter (void)
1922 GtkTreeModel *filter;
1923 GtkTreeIter iter, root;
1924 /* A bit nasty, apologies */
1927 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1928 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1929 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1930 fixture.monitor = NULL;
1932 /* We will filter on parent state using a filter function. We will
1933 * manually keep the boolean column in sync, so that we can use
1934 * check_filter_model() to check the consistency of the model.
1936 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
1937 * to be able to check the structure here. We keep the calls to
1938 * check_filter_model() commented out until then.
1940 gtk_tree_model_filter_set_visible_func (fixture.filter,
1941 specific_has_child_filter_filter_func,
1944 gtk_tree_store_append (fixture.store, &root, NULL);
1945 create_tree_store_set_values (fixture.store, &root, FALSE);
1947 /* check_filter_model (&fixture); */
1948 check_level_length (fixture.filter, NULL, 0);
1950 gtk_tree_store_append (fixture.store, &iter, &root);
1951 create_tree_store_set_values (fixture.store, &iter, TRUE);
1953 /* Parent must now be visible. Do the level length check first,
1954 * to avoid modifying the child model triggering a row-changed to
1957 check_level_length (fixture.filter, NULL, 1);
1958 check_level_length (fixture.filter, "0", 0);
1960 set_path_visibility (&fixture, "0", TRUE);
1961 /* check_filter_model (&fixture); */
1963 gtk_tree_store_append (fixture.store, &root, NULL);
1964 check_level_length (fixture.filter, NULL, 1);
1966 gtk_tree_store_append (fixture.store, &iter, &root);
1967 check_level_length (fixture.filter, NULL, 2);
1968 check_level_length (fixture.filter, "1", 0);
1970 create_tree_store_set_values (fixture.store, &root, TRUE);
1971 create_tree_store_set_values (fixture.store, &iter, TRUE);
1973 /* check_filter_model (&fixture); */
1975 gtk_tree_store_append (fixture.store, &iter, &root);
1976 create_tree_store_set_values (fixture.store, &iter, TRUE);
1977 check_level_length (fixture.filter, NULL, 2);
1978 check_level_length (fixture.filter, "0", 0);
1979 check_level_length (fixture.filter, "1", 0);
1981 /* Now remove one of the remaining child rows */
1982 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
1984 gtk_tree_store_remove (fixture.store, &iter);
1986 check_level_length (fixture.filter, NULL, 1);
1987 check_level_length (fixture.filter, "0", 0);
1989 set_path_visibility (&fixture, "0", FALSE);
1990 /* check_filter_model (&fixture); */
1995 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
2002 path = gtk_tree_model_get_path (model, iter);
2003 depth = gtk_tree_path_get_depth (path);
2004 gtk_tree_path_free (path);
2009 return gtk_tree_model_iter_has_child (model, iter);
2013 specific_root_has_child_filter (void)
2015 GtkTreeModel *filter;
2016 GtkTreeIter iter, root;
2017 /* A bit nasty, apologies */
2020 /* This is a variation on the above test case wherein the has-child
2021 * check for visibility only applies to root level nodes.
2024 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2025 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
2026 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
2027 fixture.monitor = NULL;
2029 /* We will filter on parent state using a filter function. We will
2030 * manually keep the boolean column in sync, so that we can use
2031 * check_filter_model() to check the consistency of the model.
2033 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
2034 * to be able to check the structure here. We keep the calls to
2035 * check_filter_model() commented out until then.
2037 gtk_tree_model_filter_set_visible_func (fixture.filter,
2038 specific_root_has_child_filter_filter_func,
2041 gtk_tree_store_append (fixture.store, &root, NULL);
2042 create_tree_store_set_values (fixture.store, &root, FALSE);
2044 /* check_filter_model (&fixture); */
2045 check_level_length (fixture.filter, NULL, 0);
2047 gtk_tree_store_append (fixture.store, &iter, &root);
2048 create_tree_store_set_values (fixture.store, &iter, TRUE);
2050 /* Parent must now be visible. Do the level length check first,
2051 * to avoid modifying the child model triggering a row-changed to
2054 check_level_length (fixture.filter, NULL, 1);
2055 check_level_length (fixture.filter, "0", 1);
2057 set_path_visibility (&fixture, "0", TRUE);
2058 /* check_filter_model (&fixture); */
2060 gtk_tree_store_append (fixture.store, &root, NULL);
2061 check_level_length (fixture.filter, NULL, 1);
2063 gtk_tree_store_append (fixture.store, &iter, &root);
2064 check_level_length (fixture.filter, NULL, 2);
2065 check_level_length (fixture.filter, "1", 1);
2067 create_tree_store_set_values (fixture.store, &root, TRUE);
2068 create_tree_store_set_values (fixture.store, &iter, TRUE);
2070 /* check_filter_model (&fixture); */
2072 gtk_tree_store_append (fixture.store, &iter, &root);
2073 create_tree_store_set_values (fixture.store, &iter, TRUE);
2074 check_level_length (fixture.filter, NULL, 2);
2075 check_level_length (fixture.filter, "0", 1);
2076 check_level_length (fixture.filter, "1", 2);
2078 /* Now remove one of the remaining child rows */
2079 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
2081 gtk_tree_store_remove (fixture.store, &iter);
2083 check_level_length (fixture.filter, NULL, 1);
2084 check_level_length (fixture.filter, "0", 2);
2086 set_path_visibility (&fixture, "0", FALSE);
2087 /* check_filter_model (&fixture); */
2092 specific_filter_add_child (void)
2094 /* This test is based on one of the test cases I found in my
2095 * old test cases directory. I unfortunately do not have a record
2096 * from who this test case originated. -Kris.
2100 GtkTreeIter iter_first;
2102 GtkTreeStore *store;
2103 GtkTreeModel *filter;
2105 store = gtk_tree_store_new (1, G_TYPE_STRING);
2107 gtk_tree_store_append (store, &iter_first, NULL);
2108 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
2110 gtk_tree_store_append (store, &iter, NULL);
2111 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2113 gtk_tree_store_append (store, &iter, NULL);
2114 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2116 gtk_tree_store_append (store, &iter, NULL);
2117 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2119 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2121 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2122 gtk_tree_store_append (store, &child, &iter_first);
2123 gtk_tree_store_set (store, &child, 0, "Hello", -1);
2127 specific_list_store_clear (void)
2132 GtkTreeModel *filter;
2135 list = gtk_list_store_new (1, G_TYPE_INT);
2136 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
2137 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
2138 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
2139 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
2140 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
2141 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
2142 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
2143 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
2145 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
2146 view = gtk_tree_view_new_with_model (filter);
2148 gtk_list_store_clear (list);
2152 specific_bug_300089 (void)
2154 /* Test case for GNOME Bugzilla bug 300089. Written by
2157 GtkTreeModel *sort_model, *child_model;
2159 GtkTreeIter iter, iter2, sort_iter;
2161 child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
2163 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2164 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
2165 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2166 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "B", -1);
2168 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
2169 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "D", -1);
2170 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
2171 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "E", -1);
2173 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2174 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "C", -1);
2177 sort_model = GTK_TREE_MODEL (gtk_tree_model_sort_new_with_model (child_model));
2178 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
2179 0, GTK_SORT_ASCENDING);
2181 path = gtk_tree_path_new_from_indices (1, 1, -1);
2183 /* make sure a level is constructed */
2184 gtk_tree_model_get_iter (sort_model, &sort_iter, path);
2186 /* change the "E" row in a way that causes it to change position */
2187 gtk_tree_model_get_iter (child_model, &iter, path);
2188 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
2193 specific_bug_301558_sort_func (GtkTreeModel *model,
2200 gtk_tree_model_get (model, a, 0, &i, -1);
2201 gtk_tree_model_get (model, b, 0, &j, -1);
2207 specific_bug_301558 (void)
2209 /* Test case for GNOME Bugzilla bug 301558 provided by
2213 GtkTreeModel *filter;
2215 GtkTreeIter root, iter, iter2;
2220 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
2221 gtk_tree_store_append (tree, &iter, NULL);
2222 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
2223 gtk_tree_store_append (tree, &iter2, &iter);
2224 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
2226 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
2227 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
2228 specific_bug_301558_sort_func,
2231 filter = gtk_tree_model_filter_new (sort, NULL);
2232 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
2234 view = gtk_tree_view_new_with_model (filter);
2236 while (gtk_events_pending ())
2237 gtk_main_iteration ();
2241 for (i = 0; i < 10; i++)
2243 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
2244 g_assert_not_reached ();
2248 gtk_tree_store_append (tree, &iter, &root);
2249 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
2254 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
2255 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
2257 gtk_tree_store_remove (tree, &iter);
2266 specific_bug_311955_filter_func (GtkTreeModel *model,
2272 gtk_tree_model_get (model, iter, 0, &value, -1);
2274 return (value != 0);
2278 specific_bug_311955 (void)
2280 /* This is a test case for GNOME Bugzilla bug 311955. It was written
2283 GtkTreeIter iter, child, root;
2284 GtkTreeStore *store;
2286 GtkTreeModel *filter;
2289 GtkWidget *tree_view;
2293 store = gtk_tree_store_new (1, G_TYPE_INT);
2295 gtk_tree_store_append (store, &root, NULL);
2296 gtk_tree_store_set (store, &root, 0, 33, -1);
2298 gtk_tree_store_append (store, &iter, &root);
2299 gtk_tree_store_set (store, &iter, 0, 50, -1);
2301 gtk_tree_store_append (store, &iter, NULL);
2302 gtk_tree_store_set (store, &iter, 0, 22, -1);
2304 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2305 filter = gtk_tree_model_filter_new (sort, NULL);
2307 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2308 specific_bug_311955_filter_func,
2311 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2312 tree_view = gtk_tree_view_new_with_model (filter);
2313 g_object_unref (store);
2315 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2317 while (gtk_events_pending ())
2318 gtk_main_iteration ();
2321 for (i = 0; i < 4; i++)
2323 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2325 gtk_tree_store_append (store, &iter, &root);
2328 gtk_tree_store_set (store, &iter, 0, i, -1);
2332 gtk_tree_store_append (store, &child, &iter);
2333 gtk_tree_store_set (store, &child, 0, 10, -1);
2337 while (gtk_events_pending ())
2338 gtk_main_iteration ();
2340 /* Remove bottommost child from the tree. */
2341 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2342 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
2344 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
2346 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
2347 gtk_tree_store_remove (store, &child);
2350 g_assert_not_reached ();
2354 specific_bug_346800 (void)
2356 /* This is a test case for GNOME Bugzilla bug 346800. It was written
2357 * by Jonathan Matthew.
2360 GtkTreeIter node_iters[50];
2361 GtkTreeIter child_iters[50];
2362 GtkTreeModel *model;
2363 GtkTreeModelFilter *filter;
2364 GtkTreeStore *store;
2368 columns = g_new (GType, 2);
2369 columns[0] = G_TYPE_STRING;
2370 columns[1] = G_TYPE_BOOLEAN;
2371 store = gtk_tree_store_newv (2, columns);
2372 model = GTK_TREE_MODEL (store);
2374 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
2375 gtk_tree_model_filter_set_visible_column (filter, 1);
2377 for (i=0; i<items; i++)
2379 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
2382 gtk_tree_store_append (store, &node_iters[i], NULL);
2383 gtk_tree_store_set (store, &node_iters[i],
2385 1, ((i%6) == 0) ? FALSE : TRUE,
2389 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
2390 gtk_tree_store_set (store, &child_iters[i],
2391 0, "something else",
2394 gtk_tree_model_filter_refilter (filter);
2398 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
2399 (i & 1) ? TRUE : FALSE, -1);
2400 gtk_tree_model_filter_refilter (filter);
2402 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
2403 (i & 1) ? FALSE: TRUE, -1);
2404 gtk_tree_model_filter_refilter (filter);
2411 specific_bug_364946 (void)
2413 /* This is a test case for GNOME Bugzilla bug 364946. It was written
2414 * by Andreas Koehler.
2416 GtkTreeStore *store;
2417 GtkTreeIter a, aa, aaa, aab, iter;
2418 GtkTreeModel *s_model;
2420 store = gtk_tree_store_new (1, G_TYPE_STRING);
2422 gtk_tree_store_append (store, &a, NULL);
2423 gtk_tree_store_set (store, &a, 0, "0", -1);
2425 gtk_tree_store_append (store, &aa, &a);
2426 gtk_tree_store_set (store, &aa, 0, "0:0", -1);
2428 gtk_tree_store_append (store, &aaa, &aa);
2429 gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
2431 gtk_tree_store_append (store, &aab, &aa);
2432 gtk_tree_store_set (store, &aab, 0, "0:0:1", -1);
2434 s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2435 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model), 0,
2436 GTK_SORT_ASCENDING);
2438 gtk_tree_model_get_iter_from_string (s_model, &iter, "0:0:0");
2440 gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
2441 gtk_tree_store_remove (store, &aaa);
2442 gtk_tree_store_remove (store, &aab);
2444 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model));
2449 specific_bug_464173_visible_func (GtkTreeModel *model,
2453 gboolean *visible = (gboolean *)data;
2459 specific_bug_464173 (void)
2461 /* Test case for GNOME Bugzilla bug 464173, test case written
2462 * by Andreas Koehler.
2464 GtkTreeStore *model;
2465 GtkTreeModelFilter *f_model;
2466 GtkTreeIter iter1, iter2;
2468 gboolean visible = TRUE;
2470 model = gtk_tree_store_new (1, G_TYPE_STRING);
2471 gtk_tree_store_append (model, &iter1, NULL);
2472 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
2473 gtk_tree_store_append (model, &iter2, &iter1);
2474 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
2476 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
2477 gtk_tree_model_filter_set_visible_func (f_model,
2478 specific_bug_464173_visible_func,
2481 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
2484 gtk_tree_model_filter_refilter (f_model);
2489 specific_bug_540201_filter_func (GtkTreeModel *model,
2493 gboolean has_children;
2495 has_children = gtk_tree_model_iter_has_child (model, iter);
2497 return has_children;
2501 specific_bug_540201 (void)
2503 /* Test case for GNOME Bugzilla bug 540201, steps provided by
2506 GtkTreeIter iter, root;
2507 GtkTreeStore *store;
2508 GtkTreeModel *filter;
2510 GtkWidget *tree_view;
2512 store = gtk_tree_store_new (1, G_TYPE_INT);
2514 gtk_tree_store_append (store, &root, NULL);
2515 gtk_tree_store_set (store, &root, 0, 33, -1);
2517 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2518 tree_view = gtk_tree_view_new_with_model (filter);
2520 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2521 specific_bug_540201_filter_func,
2524 gtk_tree_store_append (store, &iter, &root);
2525 gtk_tree_store_set (store, &iter, 0, 50, -1);
2527 gtk_tree_store_append (store, &iter, &root);
2528 gtk_tree_store_set (store, &iter, 0, 22, -1);
2531 gtk_tree_store_append (store, &root, NULL);
2532 gtk_tree_store_set (store, &root, 0, 33, -1);
2534 gtk_tree_store_append (store, &iter, &root);
2535 gtk_tree_store_set (store, &iter, 0, 22, -1);
2540 specific_bug_549287_visible_func (GtkTreeModel *model,
2544 gboolean result = FALSE;
2546 result = gtk_tree_model_iter_has_child (model, iter);
2552 specific_bug_549287 (void)
2554 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
2557 GtkTreeStore *store;
2558 GtkTreeModel *filtered;
2561 GtkTreeIter *swap, *parent, *child;
2563 store = gtk_tree_store_new (1, G_TYPE_STRING);
2564 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2565 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
2566 specific_bug_549287_visible_func,
2569 view = gtk_tree_view_new_with_model (filtered);
2571 for (i = 0; i < 4; i++)
2573 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
2575 parent = gtk_tree_iter_copy (&iter);
2576 child = gtk_tree_iter_copy (&iter);
2578 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
2587 gtk_tree_store_append (store, child, parent);
2588 gtk_tree_store_set (store, child,
2592 gtk_tree_iter_free (parent);
2593 gtk_tree_iter_free (child);
2597 gtk_tree_store_append (store, &iter, NULL);
2598 gtk_tree_store_set (store, &iter,
2603 /* since we inserted something, we changed the visibility conditions: */
2604 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
2614 gtk_test_init (&argc, &argv, NULL);
2616 g_test_add ("/FilterModel/self/verify-test-suite",
2620 filter_test_teardown);
2622 g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-1",
2623 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2625 verify_test_suite_vroot,
2626 filter_test_teardown);
2627 g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-2",
2628 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
2630 verify_test_suite_vroot,
2631 filter_test_teardown);
2634 g_test_add ("/FilterModel/filled/hide-root-level",
2637 filled_hide_root_level,
2638 filter_test_teardown);
2639 g_test_add ("/FilterModel/filled/hide-child-levels",
2642 filled_hide_child_levels,
2643 filter_test_teardown);
2645 g_test_add ("/FilterModel/filled/hide-root-level/vroot",
2646 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2648 filled_vroot_hide_root_level,
2649 filter_test_teardown);
2650 g_test_add ("/FilterModel/filled/hide-child-levels/vroot",
2651 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2653 filled_vroot_hide_child_levels,
2654 filter_test_teardown);
2657 g_test_add ("/FilterModel/empty/show-nodes",
2659 filter_test_setup_empty,
2661 filter_test_teardown);
2663 g_test_add ("/FilterModel/empty/show-nodes/vroot",
2664 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2665 filter_test_setup_empty,
2666 empty_vroot_show_nodes,
2667 filter_test_teardown);
2670 g_test_add ("/FilterModel/unfiltered/hide-single",
2672 filter_test_setup_unfiltered,
2673 unfiltered_hide_single,
2674 filter_test_teardown);
2675 g_test_add ("/FilterModel/unfiltered/hide-single-child",
2677 filter_test_setup_unfiltered,
2678 unfiltered_hide_single_child,
2679 filter_test_teardown);
2680 g_test_add ("/FilterModel/unfiltered/hide-single-multi-level",
2682 filter_test_setup_unfiltered,
2683 unfiltered_hide_single_multi_level,
2684 filter_test_teardown);
2686 g_test_add ("/FilterModel/unfiltered/hide-single/vroot",
2687 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2688 filter_test_setup_unfiltered,
2689 unfiltered_vroot_hide_single,
2690 filter_test_teardown);
2691 g_test_add ("/FilterModel/unfiltered/hide-single-child/vroot",
2692 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2693 filter_test_setup_unfiltered,
2694 unfiltered_vroot_hide_single_child,
2695 filter_test_teardown);
2696 g_test_add ("/FilterModel/unfiltered/hide-single-multi-level/vroot",
2697 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2698 filter_test_setup_unfiltered,
2699 unfiltered_vroot_hide_single_multi_level,
2700 filter_test_teardown);
2704 g_test_add ("/FilterModel/unfiltered/show-single",
2706 filter_test_setup_empty_unfiltered,
2707 unfiltered_show_single,
2708 filter_test_teardown);
2709 g_test_add ("/FilterModel/unfiltered/show-single-child",
2711 filter_test_setup_empty_unfiltered,
2712 unfiltered_show_single_child,
2713 filter_test_teardown);
2714 g_test_add ("/FilterModel/unfiltered/show-single-multi-level",
2716 filter_test_setup_empty_unfiltered,
2717 unfiltered_show_single_multi_level,
2718 filter_test_teardown);
2720 g_test_add ("/FilterModel/unfiltered/show-single/vroot",
2721 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2722 filter_test_setup_empty_unfiltered,
2723 unfiltered_vroot_show_single,
2724 filter_test_teardown);
2725 g_test_add ("/FilterModel/unfiltered/show-single-child/vroot",
2726 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2727 filter_test_setup_empty_unfiltered,
2728 unfiltered_vroot_show_single_child,
2729 filter_test_teardown);
2730 g_test_add ("/FilterModel/unfiltered/show-single-multi-level/vroot",
2731 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2732 filter_test_setup_empty_unfiltered,
2733 unfiltered_vroot_show_single_multi_level,
2734 filter_test_teardown);
2737 g_test_add_func ("/FilterModel/specific/path-dependent-filter",
2738 specific_path_dependent_filter);
2739 g_test_add_func ("/FilterModel/specific/append-after-collapse",
2740 specific_append_after_collapse);
2741 g_test_add_func ("/FilterModel/specific/sort-filter-remove-node",
2742 specific_sort_filter_remove_node);
2743 g_test_add_func ("/FilterModel/specific/sort-filter-remove-root",
2744 specific_sort_filter_remove_root);
2745 g_test_add_func ("/FilterModel/specific/root-mixed-visibility",
2746 specific_root_mixed_visibility);
2747 g_test_add_func ("/FilterModel/specific/has-child-filter",
2748 specific_has_child_filter);
2749 g_test_add_func ("/FilterModel/specific/root-has-child-filter",
2750 specific_root_has_child_filter);
2751 g_test_add_func ("/FilterModel/specific/filter-add-child",
2752 specific_filter_add_child);
2753 g_test_add_func ("/FilterModel/specific/list-store-clear",
2754 specific_list_store_clear);
2756 g_test_add_func ("/FilterModel/specific/bug-300089",
2757 specific_bug_300089);
2758 g_test_add_func ("/FilterModel/specific/bug-301558",
2759 specific_bug_301558);
2760 g_test_add_func ("/FilterModel/specific/bug-311955",
2761 specific_bug_311955);
2762 g_test_add_func ("/FilterModel/specific/bug-346800",
2763 specific_bug_346800);
2764 g_test_add_func ("/FilterModel/specific/bug-364946",
2765 specific_bug_364946);
2766 g_test_add_func ("/FilterModel/specific/bug-464173",
2767 specific_bug_464173);
2768 g_test_add_func ("/FilterModel/specific/bug-540201",
2769 specific_bug_540201);
2770 g_test_add_func ("/FilterModel/specific/bug-549287",
2771 specific_bug_549287);
2773 return g_test_run ();