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.
27 #define LEVEL_LENGTH 5
30 create_tree_store_set_values (GtkTreeStore *store,
36 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
37 gtk_tree_store_set (store, iter,
38 0, gtk_tree_path_to_string (path),
41 gtk_tree_path_free (path);
45 create_tree_store_recurse (int depth,
52 for (i = 0; i < LEVEL_LENGTH; i++)
56 gtk_tree_store_insert (store, &iter, parent, i);
57 create_tree_store_set_values (store, &iter, visible);
60 create_tree_store_recurse (depth - 1, store, &iter, visible);
65 create_tree_store (int depth,
70 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
72 create_tree_store_recurse (depth, store, NULL, visible);
86 ROW_HAS_CHILD_TOGGLED,
101 signal_new (SignalName signal, GtkTreePath *path)
105 s = g_new0 (Signal, 1);
107 s->path = gtk_tree_path_copy (path);
113 signal_free (Signal *s)
116 gtk_tree_path_free (s->path);
125 GtkTreeModel *client;
126 guint signal_ids[LAST_SIGNAL];
132 signal_monitor_generic_handler (SignalMonitor *m,
139 g_return_if_fail (m->client == model);
140 g_return_if_fail (!g_queue_is_empty (m->queue));
143 /* For debugging: output signals that are coming in. Leaks memory. */
144 g_print ("signal=%d path=%s\n", signal, gtk_tree_path_to_string (path));
147 s = g_queue_peek_tail (m->queue);
149 g_return_if_fail (s->signal == signal);
151 s = g_queue_pop_tail (m->queue);
153 g_return_if_fail (!gtk_tree_path_compare (path, s->path));
159 signal_monitor_row_inserted (GtkTreeModel *model,
164 signal_monitor_generic_handler (data, ROW_INSERTED,
169 signal_monitor_row_deleted (GtkTreeModel *model,
173 signal_monitor_generic_handler (data, ROW_DELETED,
178 signal_monitor_row_changed (GtkTreeModel *model,
183 signal_monitor_generic_handler (data, ROW_CHANGED,
188 signal_monitor_row_has_child_toggled (GtkTreeModel *model,
193 signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
198 signal_monitor_rows_reordered (GtkTreeModel *model,
204 signal_monitor_generic_handler (data, ROWS_REORDERED,
208 static SignalMonitor *
209 signal_monitor_new (GtkTreeModel *client)
213 m = g_new0 (SignalMonitor, 1);
214 m->client = g_object_ref (client);
215 m->queue = g_queue_new ();
217 m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
219 G_CALLBACK (signal_monitor_row_inserted),
221 m->signal_ids[ROW_DELETED] = g_signal_connect (client,
223 G_CALLBACK (signal_monitor_row_deleted),
225 m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
227 G_CALLBACK (signal_monitor_row_changed),
229 m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
230 "row-has-child-toggled",
231 G_CALLBACK (signal_monitor_row_has_child_toggled),
233 m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
235 G_CALLBACK (signal_monitor_rows_reordered),
242 signal_monitor_free (SignalMonitor *m)
246 for (i = 0; i < LAST_SIGNAL; i++)
247 g_signal_handler_disconnect (m->client, m->signal_ids[i]);
249 g_object_unref (m->client);
252 g_queue_free (m->queue);
258 signal_monitor_assert_is_empty (SignalMonitor *m)
260 g_assert (g_queue_is_empty (m->queue));
264 signal_monitor_append_signal_path (SignalMonitor *m,
270 s = signal_new (signal, path);
271 g_queue_push_head (m->queue, s);
275 signal_monitor_append_signal (SignalMonitor *m,
277 const gchar *path_string)
282 path = gtk_tree_path_new_from_string (path_string);
284 s = signal_new (signal, path);
285 g_queue_push_head (m->queue, s);
287 gtk_tree_path_free (path);
296 GtkWidget *tree_view;
299 GtkTreeModelFilter *filter;
301 SignalMonitor *monitor;
305 filter_test_setup_generic (FilterTest *fixture,
306 gconstpointer test_data,
311 const GtkTreePath *vroot = test_data;
312 GtkTreeModel *filter;
314 fixture->store = create_tree_store (depth, !empty);
316 /* Please forgive me for casting const away. */
317 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
318 (GtkTreePath *)vroot);
319 fixture->filter = GTK_TREE_MODEL_FILTER (filter);
322 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
324 /* We need a tree view that's listening to get ref counting from that
327 fixture->tree_view = gtk_tree_view_new_with_model (filter);
329 fixture->monitor = signal_monitor_new (filter);
333 filter_test_setup (FilterTest *fixture,
334 gconstpointer test_data)
336 filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
340 filter_test_setup_empty (FilterTest *fixture,
341 gconstpointer test_data)
343 filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
347 filter_test_setup_unfiltered (FilterTest *fixture,
348 gconstpointer test_data)
350 filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
354 filter_test_setup_empty_unfiltered (FilterTest *fixture,
355 gconstpointer test_data)
357 filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
361 strip_virtual_root (GtkTreePath *path,
362 GtkTreePath *root_path)
364 GtkTreePath *real_path;
369 int depth = gtk_tree_path_get_depth (path);
370 int root_depth = gtk_tree_path_get_depth (root_path);
372 real_path = gtk_tree_path_new ();
374 for (j = 0; j < depth - root_depth; j++)
375 gtk_tree_path_append_index (real_path,
376 gtk_tree_path_get_indices (path)[root_depth + j]);
379 real_path = gtk_tree_path_copy (path);
385 filter_test_append_refilter_signals_recurse (FilterTest *fixture,
386 GtkTreePath *store_path,
387 GtkTreePath *filter_path,
389 GtkTreePath *root_path)
392 int rows_deleted = 0;
395 gtk_tree_path_down (store_path);
396 gtk_tree_path_down (filter_path);
398 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
401 for (i = 0; i < LEVEL_LENGTH; i++)
404 GtkTreePath *real_path;
406 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
411 (!gtk_tree_path_is_descendant (store_path, root_path)
412 || !gtk_tree_path_compare (store_path, root_path)))
414 if (!gtk_tree_path_compare (store_path, root_path))
417 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
420 GtkTreePath *store_copy;
421 GtkTreePath *filter_copy;
423 store_copy = gtk_tree_path_copy (store_path);
424 filter_copy = gtk_tree_path_copy (filter_path);
425 filter_test_append_refilter_signals_recurse (fixture,
430 gtk_tree_path_free (store_copy);
431 gtk_tree_path_free (filter_copy);
435 gtk_tree_path_next (store_path);
436 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
439 gtk_tree_path_next (filter_path);
444 real_path = strip_virtual_root (filter_path, root_path);
448 /* This row will be inserted */
449 signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
451 signal_monitor_append_signal_path (fixture->monitor,
452 ROW_HAS_CHILD_TOGGLED,
456 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
459 GtkTreePath *store_copy;
460 GtkTreePath *filter_copy;
462 store_copy = gtk_tree_path_copy (store_path);
463 filter_copy = gtk_tree_path_copy (filter_path);
464 filter_test_append_refilter_signals_recurse (fixture,
469 gtk_tree_path_free (store_copy);
470 gtk_tree_path_free (filter_copy);
473 gtk_tree_path_next (filter_path);
477 /* This row will be deleted */
479 signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
483 gtk_tree_path_free (real_path);
485 gtk_tree_path_next (store_path);
486 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
489 if (rows_deleted == LEVEL_LENGTH
490 && gtk_tree_path_get_depth (filter_path) > 1)
492 GtkTreePath *real_path;
494 gtk_tree_path_up (store_path);
495 gtk_tree_path_up (filter_path);
497 /* A row-has-child-toggled will be emitted on the parent */
500 && gtk_tree_path_is_descendant (store_path, root_path)
501 && gtk_tree_path_compare (store_path, root_path)))
503 real_path = strip_virtual_root (filter_path, root_path);
504 signal_monitor_append_signal_path (fixture->monitor,
505 ROW_HAS_CHILD_TOGGLED,
508 gtk_tree_path_free (real_path);
514 filter_test_append_refilter_signals (FilterTest *fixture,
517 /* A special function that walks the tree store like the
518 * model validation functions below.
521 GtkTreePath *filter_path;
523 path = gtk_tree_path_new ();
524 filter_path = gtk_tree_path_new ();
525 filter_test_append_refilter_signals_recurse (fixture,
530 gtk_tree_path_free (path);
531 gtk_tree_path_free (filter_path);
535 filter_test_append_refilter_signals_with_vroot (FilterTest *fixture,
537 GtkTreePath *root_path)
539 /* A special function that walks the tree store like the
540 * model validation functions below.
543 GtkTreePath *filter_path;
545 path = gtk_tree_path_new ();
546 filter_path = gtk_tree_path_new ();
547 filter_test_append_refilter_signals_recurse (fixture,
552 gtk_tree_path_free (path);
553 gtk_tree_path_free (filter_path);
557 filter_test_enable_filter (FilterTest *fixture)
559 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
560 gtk_tree_model_filter_refilter (fixture->filter);
564 filter_test_teardown (FilterTest *fixture,
565 gconstpointer test_data)
567 signal_monitor_free (fixture->monitor);
569 g_object_unref (fixture->filter);
570 g_object_unref (fixture->store);
574 * Model structure validation
578 check_filter_model_recurse (FilterTest *fixture,
579 GtkTreePath *store_parent_path,
580 GtkTreePath *filter_parent_path)
583 GtkTreeIter store_iter;
584 GtkTreeIter filter_iter;
585 gboolean store_has_next, filter_has_next;
587 gtk_tree_path_down (store_parent_path);
588 gtk_tree_path_down (filter_parent_path);
590 store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
591 &store_iter, store_parent_path);
592 filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
593 &filter_iter, filter_parent_path);
595 for (i = 0; i < LEVEL_LENGTH; i++)
599 g_return_if_fail (store_has_next == TRUE);
601 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
609 gchar *filter_str, *store_str;
611 g_return_if_fail (filter_has_next == TRUE);
614 tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
616 g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
618 /* Verify model content */
619 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
623 gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
628 g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
633 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
636 g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
638 check_filter_model_recurse (fixture,
639 gtk_tree_path_copy (store_parent_path),
643 gtk_tree_path_next (filter_parent_path);
644 filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
647 gtk_tree_path_next (store_parent_path);
648 store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
651 /* Both models should have no more content! */
652 g_return_if_fail (store_has_next == FALSE);
653 g_return_if_fail (filter_has_next == FALSE);
655 gtk_tree_path_free (store_parent_path);
656 gtk_tree_path_free (filter_parent_path);
660 check_filter_model (FilterTest *fixture)
664 if (fixture->monitor)
665 signal_monitor_assert_is_empty (fixture->monitor);
667 path = gtk_tree_path_new ();
669 check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
673 check_filter_model_with_root (FilterTest *fixture,
676 if (fixture->monitor)
677 signal_monitor_assert_is_empty (fixture->monitor);
679 check_filter_model_recurse (fixture,
680 gtk_tree_path_copy (path),
681 gtk_tree_path_new ());
687 check_level_length (GtkTreeModelFilter *filter,
693 int l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
694 g_return_if_fail (l == length);
699 gboolean retrieved_iter = FALSE;
702 retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
704 g_return_if_fail (retrieved_iter);
705 l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
706 g_return_if_fail (l == length);
711 set_path_visibility (FilterTest *fixture,
715 GtkTreeIter store_iter;
717 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
719 gtk_tree_store_set (fixture->store, &store_iter,
725 insert_path_with_visibility (FilterTest *fixture,
726 const gchar *path_string,
731 GtkTreeIter parent, iter;
733 path = gtk_tree_path_new_from_string (path_string);
734 position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
735 gtk_tree_path_up (path);
737 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
739 gtk_tree_store_insert (fixture->store, &iter, &parent, position);
740 create_tree_store_set_values (fixture->store, &iter, visible);
742 gtk_tree_path_free (path);
750 verify_test_suite (FilterTest *fixture,
751 gconstpointer user_data)
753 check_filter_model (fixture);
757 verify_test_suite_vroot (FilterTest *fixture,
758 gconstpointer user_data)
760 check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
765 filled_hide_root_level (FilterTest *fixture,
766 gconstpointer user_data)
768 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
769 set_path_visibility (fixture, "2", FALSE);
770 check_filter_model (fixture);
771 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
773 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
774 set_path_visibility (fixture, "0", FALSE);
775 check_filter_model (fixture);
776 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
778 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
779 set_path_visibility (fixture, "4", FALSE);
780 check_filter_model (fixture);
781 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
785 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
786 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
788 set_path_visibility (fixture, "1", FALSE);
789 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
791 set_path_visibility (fixture, "3", FALSE);
792 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
794 check_filter_model (fixture);
797 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
798 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
799 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
800 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
802 set_path_visibility (fixture, "1", TRUE);
803 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
805 set_path_visibility (fixture, "3", TRUE);
806 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
808 check_filter_model (fixture);
812 filled_hide_child_levels (FilterTest *fixture,
813 gconstpointer user_data)
815 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
816 set_path_visibility (fixture, "0:2", FALSE);
817 check_filter_model (fixture);
818 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
819 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
821 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
822 set_path_visibility (fixture, "0:4", FALSE);
823 check_filter_model (fixture);
824 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
825 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
827 set_path_visibility (fixture, "0:4:3", FALSE);
828 check_filter_model (fixture);
829 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
830 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
832 set_path_visibility (fixture, "0:4:0", FALSE);
833 set_path_visibility (fixture, "0:4:1", FALSE);
834 set_path_visibility (fixture, "0:4:2", FALSE);
835 set_path_visibility (fixture, "0:4:4", FALSE);
836 check_filter_model (fixture);
837 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
838 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
840 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
841 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
842 /* FIXME: Actually, the filter model should not be emitted the
843 * row-has-child-toggled signal here. *However* an extraneous emission
844 * of this signal does not hurt and is allowed.
846 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
847 set_path_visibility (fixture, "0:4", TRUE);
848 check_filter_model (fixture);
849 check_level_length (fixture->filter, "0:3", 0);
851 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
852 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
853 set_path_visibility (fixture, "0:2", TRUE);
854 check_filter_model (fixture);
855 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
856 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
857 check_level_length (fixture->filter, "0:4", 0);
859 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
860 /* Once 0:4:0 got inserted, 0:4 became a parent */
861 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
862 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:0");
863 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
864 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:1");
866 set_path_visibility (fixture, "0:4:2", TRUE);
867 set_path_visibility (fixture, "0:4:4", TRUE);
868 signal_monitor_assert_is_empty (fixture->monitor);
869 check_level_length (fixture->filter, "0:4", 2);
874 filled_vroot_hide_root_level (FilterTest *fixture,
875 gconstpointer user_data)
877 GtkTreePath *path = (GtkTreePath *)user_data;
879 /* These changes do not affect the filter's root level */
880 set_path_visibility (fixture, "0", FALSE);
881 check_filter_model_with_root (fixture, path);
882 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
883 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
885 set_path_visibility (fixture, "4", FALSE);
886 check_filter_model_with_root (fixture, path);
887 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
888 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
890 /* Even though we set the virtual root parent node to FALSE,
891 * the virtual root contents remain.
893 set_path_visibility (fixture, "2", FALSE);
894 check_filter_model_with_root (fixture, path);
895 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
896 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
899 set_path_visibility (fixture, "1", FALSE);
900 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
901 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
903 set_path_visibility (fixture, "3", FALSE);
904 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
905 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
907 check_filter_model_with_root (fixture, path);
910 set_path_visibility (fixture, "2", TRUE);
911 check_filter_model_with_root (fixture, path);
912 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
913 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
915 set_path_visibility (fixture, "1", TRUE);
916 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
917 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
919 set_path_visibility (fixture, "3", TRUE);
920 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
921 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
923 check_filter_model_with_root (fixture, path);
925 /* Now test changes in the virtual root level */
926 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
927 set_path_visibility (fixture, "2:2", FALSE);
928 check_filter_model_with_root (fixture, path);
929 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
931 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
932 set_path_visibility (fixture, "2:4", FALSE);
933 check_filter_model_with_root (fixture, path);
934 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
936 set_path_visibility (fixture, "1:4", FALSE);
937 check_filter_model_with_root (fixture, path);
938 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
940 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
941 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
942 set_path_visibility (fixture, "2:4", TRUE);
943 check_filter_model_with_root (fixture, path);
944 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
946 set_path_visibility (fixture, "2", FALSE);
947 check_filter_model_with_root (fixture, path);
948 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
950 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
951 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
952 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
953 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
954 set_path_visibility (fixture, "2:0", FALSE);
955 set_path_visibility (fixture, "2:1", FALSE);
956 set_path_visibility (fixture, "2:2", FALSE);
957 set_path_visibility (fixture, "2:3", FALSE);
958 set_path_visibility (fixture, "2:4", FALSE);
959 check_filter_model_with_root (fixture, path);
960 check_level_length (fixture->filter, NULL, 0);
962 set_path_visibility (fixture, "2", TRUE);
963 check_filter_model_with_root (fixture, path);
964 check_level_length (fixture->filter, NULL, 0);
966 set_path_visibility (fixture, "1:4", FALSE);
967 check_filter_model_with_root (fixture, path);
968 check_level_length (fixture->filter, NULL, 0);
970 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
971 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
972 set_path_visibility (fixture, "2:4", TRUE);
973 check_filter_model_with_root (fixture, path);
974 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
976 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
977 set_path_visibility (fixture, "2:4", FALSE);
978 check_filter_model_with_root (fixture, path);
979 check_level_length (fixture->filter, NULL, 0);
981 set_path_visibility (fixture, "2", FALSE);
982 check_filter_model_with_root (fixture, path);
983 check_level_length (fixture->filter, NULL, 0);
985 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
986 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
987 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
988 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
989 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
990 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
991 set_path_visibility (fixture, "2:0", TRUE);
992 set_path_visibility (fixture, "2:1", TRUE);
993 set_path_visibility (fixture, "2:2", TRUE);
994 check_filter_model_with_root (fixture, path);
995 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
997 set_path_visibility (fixture, "2", TRUE);
998 check_filter_model_with_root (fixture, path);
999 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1003 filled_vroot_hide_child_levels (FilterTest *fixture,
1004 gconstpointer user_data)
1006 GtkTreePath *path = (GtkTreePath *)user_data;
1008 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1009 set_path_visibility (fixture, "2:0:2", FALSE);
1010 check_filter_model_with_root (fixture, path);
1011 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1012 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1014 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1015 set_path_visibility (fixture, "2:0:4", FALSE);
1016 check_filter_model_with_root (fixture, path);
1017 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1018 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1020 set_path_visibility (fixture, "2:0:4:3", FALSE);
1021 check_filter_model_with_root (fixture, path);
1022 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1023 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1025 set_path_visibility (fixture, "2:0:4:0", FALSE);
1026 set_path_visibility (fixture, "2:0:4:1", FALSE);
1027 set_path_visibility (fixture, "2:0:4:2", FALSE);
1028 set_path_visibility (fixture, "2:0:4:4", FALSE);
1029 check_filter_model_with_root (fixture, path);
1030 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1031 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1033 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1034 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1035 /* FIXME: Actually, the filter model should not be emitted the
1036 * row-has-child-toggled signal here. *However* an extraneous emission
1037 * of this signal does not hurt and is allowed.
1039 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1040 set_path_visibility (fixture, "2:0:4", TRUE);
1041 check_filter_model_with_root (fixture, path);
1042 check_level_length (fixture->filter, "0:3", 0);
1044 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1045 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1046 set_path_visibility (fixture, "2:0:2", TRUE);
1047 check_filter_model_with_root (fixture, path);
1048 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1049 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1050 check_level_length (fixture->filter, "0:4", 0);
1052 /* FIXME: Inconsistency! For the non-vroot case we also receive two
1053 * row-has-child-toggled signals here.
1055 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
1056 /* Once 0:4:0 got inserted, 0:4 became a parent */
1057 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1058 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
1059 set_path_visibility (fixture, "2:0:4:2", TRUE);
1060 set_path_visibility (fixture, "2:0:4:4", TRUE);
1061 check_level_length (fixture->filter, "0:4", 2);
1066 empty_show_nodes (FilterTest *fixture,
1067 gconstpointer user_data)
1069 check_filter_model (fixture);
1070 check_level_length (fixture->filter, NULL, 0);
1072 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1073 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1074 set_path_visibility (fixture, "3", TRUE);
1075 check_filter_model (fixture);
1076 check_level_length (fixture->filter, NULL, 1);
1077 check_level_length (fixture->filter, "0", 0);
1079 set_path_visibility (fixture, "3:2:2", TRUE);
1080 check_filter_model (fixture);
1081 check_level_length (fixture->filter, NULL, 1);
1082 check_level_length (fixture->filter, "0", 0);
1084 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
1085 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1086 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
1087 set_path_visibility (fixture, "3:2", TRUE);
1088 check_filter_model (fixture);
1089 check_level_length (fixture->filter, NULL, 1);
1090 check_level_length (fixture->filter, "0", 1);
1091 check_level_length (fixture->filter, "0:0", 1);
1092 check_level_length (fixture->filter, "0:0:0", 0);
1094 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1095 set_path_visibility (fixture, "3", FALSE);
1096 check_filter_model (fixture);
1097 check_level_length (fixture->filter, NULL, 0);
1099 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1100 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1101 set_path_visibility (fixture, "3:2:1", TRUE);
1102 set_path_visibility (fixture, "3", TRUE);
1103 check_filter_model (fixture);
1104 check_level_length (fixture->filter, NULL, 1);
1105 check_level_length (fixture->filter, "0", 1);
1106 check_level_length (fixture->filter, "0:0", 2);
1107 check_level_length (fixture->filter, "0:0:0", 0);
1111 empty_vroot_show_nodes (FilterTest *fixture,
1112 gconstpointer user_data)
1114 GtkTreePath *path = (GtkTreePath *)user_data;
1116 check_filter_model_with_root (fixture, path);
1117 check_level_length (fixture->filter, NULL, 0);
1119 set_path_visibility (fixture, "2", TRUE);
1120 check_filter_model_with_root (fixture, path);
1121 check_level_length (fixture->filter, NULL, 0);
1123 set_path_visibility (fixture, "2:2:2", TRUE);
1124 check_filter_model_with_root (fixture, path);
1125 check_level_length (fixture->filter, NULL, 0);
1127 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1128 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1129 set_path_visibility (fixture, "2:2", TRUE);
1130 check_filter_model_with_root (fixture, path);
1131 check_level_length (fixture->filter, NULL, 1);
1132 check_level_length (fixture->filter, "0", 1);
1133 check_level_length (fixture->filter, "0:0", 0);
1135 set_path_visibility (fixture, "3", TRUE);
1136 check_filter_model_with_root (fixture, path);
1137 check_level_length (fixture->filter, NULL, 1);
1139 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1140 set_path_visibility (fixture, "2:2", FALSE);
1141 check_filter_model_with_root (fixture, path);
1142 check_level_length (fixture->filter, NULL, 0);
1144 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1145 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1146 set_path_visibility (fixture, "2:2:1", TRUE);
1147 set_path_visibility (fixture, "2:2", TRUE);
1148 check_filter_model_with_root (fixture, path);
1149 check_level_length (fixture->filter, NULL, 1);
1150 check_level_length (fixture->filter, "0", 2);
1151 check_level_length (fixture->filter, "0:1", 0);
1156 unfiltered_hide_single (FilterTest *fixture,
1157 gconstpointer user_data)
1160 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1161 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1162 set_path_visibility (fixture, "2", FALSE);
1164 signal_monitor_assert_is_empty (fixture->monitor);
1165 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1167 /* The view only shows the root level, so the filter model only has
1168 * the first two levels cached.
1170 filter_test_append_refilter_signals (fixture, 2);
1171 filter_test_enable_filter (fixture);
1173 check_filter_model (fixture);
1174 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1178 unfiltered_hide_single_child (FilterTest *fixture,
1179 gconstpointer user_data)
1182 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1183 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1184 set_path_visibility (fixture, "2:2", FALSE);
1186 signal_monitor_assert_is_empty (fixture->monitor);
1187 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1188 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1190 /* The view only shows the root level, so the filter model only has
1191 * the first two levels cached.
1193 filter_test_append_refilter_signals (fixture, 2);
1194 filter_test_enable_filter (fixture);
1196 check_filter_model (fixture);
1197 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1198 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1202 unfiltered_hide_single_multi_level (FilterTest *fixture,
1203 gconstpointer user_data)
1206 /* This row is not shown, so its signal is not propagated */
1207 set_path_visibility (fixture, "2:2:2", FALSE);
1209 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1210 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1211 set_path_visibility (fixture, "2:2", FALSE);
1213 signal_monitor_assert_is_empty (fixture->monitor);
1214 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1215 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1216 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1218 /* The view only shows the root level, so the filter model only has
1219 * the first two levels cached.
1221 filter_test_append_refilter_signals (fixture, 2);
1222 filter_test_enable_filter (fixture);
1224 check_filter_model (fixture);
1225 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1226 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1228 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1229 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1230 set_path_visibility (fixture, "2:2", TRUE);
1232 check_filter_model (fixture);
1233 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1234 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1235 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1240 unfiltered_vroot_hide_single (FilterTest *fixture,
1241 gconstpointer user_data)
1244 GtkTreePath *path = (GtkTreePath *)user_data;
1246 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1247 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1248 set_path_visibility (fixture, "2:2", FALSE);
1250 signal_monitor_assert_is_empty (fixture->monitor);
1251 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1253 /* The view only shows the root level, so the filter model only has
1254 * the first two levels cached. (We add an additional level to
1255 * take the virtual root into account).
1257 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1258 filter_test_enable_filter (fixture);
1260 check_filter_model_with_root (fixture, path);
1261 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1265 unfiltered_vroot_hide_single_child (FilterTest *fixture,
1266 gconstpointer user_data)
1269 GtkTreePath *path = (GtkTreePath *)user_data;
1271 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1272 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1273 set_path_visibility (fixture, "2:2:2", FALSE);
1275 signal_monitor_assert_is_empty (fixture->monitor);
1276 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1277 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1279 /* The view only shows the root level, so the filter model only has
1280 * the first two levels cached. (We add an additional level to take
1281 * the virtual root into account).
1283 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1284 filter_test_enable_filter (fixture);
1286 check_filter_model_with_root (fixture, path);
1287 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1288 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1292 unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
1293 gconstpointer user_data)
1296 GtkTreePath *path = (GtkTreePath *)user_data;
1298 /* This row is not shown, so its signal is not propagated */
1299 set_path_visibility (fixture, "2:2:2:2", FALSE);
1301 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1302 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1303 set_path_visibility (fixture, "2:2:2", FALSE);
1305 signal_monitor_assert_is_empty (fixture->monitor);
1306 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1307 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1308 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1310 /* The view only shows the root level, so the filter model only has
1311 * the first two levels cached.
1313 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1314 filter_test_enable_filter (fixture);
1316 check_filter_model_with_root (fixture, path);
1317 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1318 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1320 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1321 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1322 set_path_visibility (fixture, "2:2:2", TRUE);
1324 check_filter_model_with_root (fixture, path);
1325 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1326 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1327 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1333 unfiltered_show_single (FilterTest *fixture,
1334 gconstpointer user_data)
1337 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1338 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1339 set_path_visibility (fixture, "2", TRUE);
1341 signal_monitor_assert_is_empty (fixture->monitor);
1342 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1344 /* The view only shows the root level, so the filter model only has
1345 * the first two levels cached.
1347 filter_test_append_refilter_signals (fixture, 2);
1348 filter_test_enable_filter (fixture);
1350 check_filter_model (fixture);
1351 check_level_length (fixture->filter, NULL, 1);
1355 unfiltered_show_single_child (FilterTest *fixture,
1356 gconstpointer user_data)
1359 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1360 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1361 set_path_visibility (fixture, "2:2", TRUE);
1363 signal_monitor_assert_is_empty (fixture->monitor);
1364 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1365 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1367 /* The view only shows the root level, so the filter model only has
1368 * the first two levels cached.
1370 filter_test_append_refilter_signals (fixture, 3);
1371 filter_test_enable_filter (fixture);
1373 check_filter_model (fixture);
1374 check_level_length (fixture->filter, NULL, 0);
1376 /* From here we are filtered, "2" in the real model is "0" in the filter
1379 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1380 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1381 set_path_visibility (fixture, "2", TRUE);
1382 signal_monitor_assert_is_empty (fixture->monitor);
1383 check_level_length (fixture->filter, NULL, 1);
1384 check_level_length (fixture->filter, "0", 1);
1388 unfiltered_show_single_multi_level (FilterTest *fixture,
1389 gconstpointer user_data)
1392 /* The view is not showing this row (collapsed state), so it is not
1393 * referenced. The signal should not go through.
1395 set_path_visibility (fixture, "2:2:2", TRUE);
1397 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1398 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1399 set_path_visibility (fixture, "2:2", TRUE);
1401 signal_monitor_assert_is_empty (fixture->monitor);
1402 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1403 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1404 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1406 /* The view only shows the root level, so the filter model only has
1407 * the first two levels cached.
1409 filter_test_append_refilter_signals (fixture, 3);
1410 filter_test_enable_filter (fixture);
1412 check_filter_model (fixture);
1413 check_level_length (fixture->filter, NULL, 0);
1415 /* From here we are filtered, "2" in the real model is "0" in the filter
1418 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1419 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1420 set_path_visibility (fixture, "2", TRUE);
1421 check_filter_model (fixture);
1422 check_level_length (fixture->filter, NULL, 1);
1423 check_level_length (fixture->filter, "0", 1);
1424 check_level_length (fixture->filter, "0:0", 1);
1429 unfiltered_vroot_show_single (FilterTest *fixture,
1430 gconstpointer user_data)
1433 GtkTreePath *path = (GtkTreePath *)user_data;
1435 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1436 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1437 set_path_visibility (fixture, "2:2", TRUE);
1439 signal_monitor_assert_is_empty (fixture->monitor);
1440 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1442 /* The view only shows the root level, so the filter model only has
1443 * the first two levels cached.
1445 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1446 filter_test_enable_filter (fixture);
1448 check_filter_model_with_root (fixture, path);
1449 check_level_length (fixture->filter, NULL, 1);
1453 unfiltered_vroot_show_single_child (FilterTest *fixture,
1454 gconstpointer user_data)
1457 GtkTreePath *path = (GtkTreePath *)user_data;
1459 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1460 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1461 set_path_visibility (fixture, "2:2:2", TRUE);
1463 signal_monitor_assert_is_empty (fixture->monitor);
1464 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1465 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1467 /* The view only shows the root level, so the filter model only has
1468 * the first two levels cached.
1470 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1471 filter_test_enable_filter (fixture);
1473 check_filter_model_with_root (fixture, path);
1474 check_level_length (fixture->filter, NULL, 0);
1476 /* From here we are filtered, "2" in the real model is "0" in the filter
1479 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1480 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1481 set_path_visibility (fixture, "2:2", TRUE);
1482 signal_monitor_assert_is_empty (fixture->monitor);
1483 check_level_length (fixture->filter, NULL, 1);
1484 check_level_length (fixture->filter, "0", 1);
1488 unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
1489 gconstpointer user_data)
1492 GtkTreePath *path = (GtkTreePath *)user_data;
1494 /* The view is not showing this row (collapsed state), so it is not
1495 * referenced. The signal should not go through.
1497 set_path_visibility (fixture, "2:2:2:2", TRUE);
1499 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1500 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1501 set_path_visibility (fixture, "2:2:2", TRUE);
1503 signal_monitor_assert_is_empty (fixture->monitor);
1504 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1505 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1506 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1508 /* The view only shows the root level, so the filter model only has
1509 * the first two levels cached.
1511 filter_test_append_refilter_signals_with_vroot (fixture, 4, path);
1512 filter_test_enable_filter (fixture);
1514 check_filter_model_with_root (fixture, path);
1515 check_level_length (fixture->filter, NULL, 0);
1517 /* From here we are filtered, "2" in the real model is "0" in the filter
1520 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1521 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1522 set_path_visibility (fixture, "2:2", TRUE);
1523 check_filter_model_with_root (fixture, path);
1524 check_level_length (fixture->filter, NULL, 1);
1525 check_level_length (fixture->filter, "0", 1);
1526 check_level_length (fixture->filter, "0:0", 1);
1531 specific_path_dependent_filter_func (GtkTreeModel *model,
1537 path = gtk_tree_model_get_path (model, iter);
1538 if (gtk_tree_path_get_indices (path)[0] < 4)
1545 specific_path_dependent_filter (void)
1551 GtkTreeModel *filter;
1553 list = gtk_list_store_new (1, G_TYPE_INT);
1554 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
1555 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
1556 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
1557 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
1558 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
1559 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
1560 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
1561 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
1563 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
1564 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
1565 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1566 specific_path_dependent_filter_func,
1569 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
1570 GTK_SORT_DESCENDING);
1572 for (i = 0; i < 4; i++)
1574 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1576 gtk_list_store_remove (list, &iter);
1578 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1580 gtk_list_store_remove (list, &iter);
1586 specific_append_after_collapse_visible_func (GtkTreeModel *model,
1591 gboolean hide_negative_numbers;
1593 gtk_tree_model_get (model, iter, 1, &number, -1);
1594 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
1596 return (number >= 0 || !hide_negative_numbers);
1600 specific_append_after_collapse (void)
1602 /* This test is based on one of the test cases I found in my
1603 * old test cases directory. I unfortunately do not have a record
1604 * from who this test case originated. -Kris.
1608 * - Show tree, expand, collapse.
1613 GtkTreeIter child_iter;
1614 GtkTreeIter child_iter2;
1615 GtkTreePath *append_path;
1616 GtkTreeStore *store;
1617 GtkTreeModel *filter;
1621 GtkWidget *tree_view;
1623 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
1625 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
1626 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
1627 GINT_TO_POINTER (FALSE));
1628 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1629 specific_append_after_collapse_visible_func,
1632 sort = gtk_tree_model_sort_new_with_model (filter);
1634 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1635 tree_view = gtk_tree_view_new_with_model (sort);
1636 gtk_container_add (GTK_CONTAINER (window), tree_view);
1637 gtk_widget_realize (tree_view);
1639 while (gtk_events_pending ())
1640 gtk_main_iteration ();
1642 gtk_tree_store_prepend (store, &iter, NULL);
1643 gtk_tree_store_set (store, &iter,
1644 0, "hallo", 1, 1, -1);
1646 gtk_tree_store_append (store, &child_iter, &iter);
1647 gtk_tree_store_set (store, &child_iter,
1648 0, "toemaar", 1, 1, -1);
1650 gtk_tree_store_append (store, &child_iter2, &child_iter);
1651 gtk_tree_store_set (store, &child_iter2,
1652 0, "very deep", 1, 1, -1);
1654 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
1656 gtk_tree_store_append (store, &child_iter, &iter);
1657 gtk_tree_store_set (store, &child_iter,
1658 0, "sja", 1, 1, -1);
1660 gtk_tree_store_append (store, &child_iter, &iter);
1661 gtk_tree_store_set (store, &child_iter,
1662 0, "some word", 1, -1, -1);
1664 /* Expand and collapse the tree */
1665 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
1666 while (gtk_events_pending ())
1667 gtk_main_iteration ();
1669 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
1670 while (gtk_events_pending ())
1671 gtk_main_iteration ();
1673 /* Add another it */
1674 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
1675 GINT_TO_POINTER (TRUE));
1677 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
1679 gtk_tree_store_append (store, &child_iter, &iter);
1680 gtk_tree_store_set (store, &child_iter,
1681 0, "new new new !!", 1, 1, -1);
1683 gtk_tree_path_free (append_path);
1686 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
1687 while (gtk_events_pending ())
1688 gtk_main_iteration ();
1693 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
1702 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
1708 /* Do reference the model */
1709 gtk_tree_model_get (model, iter, 0, &item, -1);
1716 specific_sort_filter_remove_node (void)
1718 /* This test is based on one of the test cases I found in my
1719 * old test cases directory. I unfortunately do not have a record
1720 * from who this test case originated. -Kris.
1723 * - Create tree store, sort, filter models. The sort model has
1724 * a default sort func that is enabled, filter model a visible func
1725 * that defaults to returning FALSE.
1726 * - Remove a node from the tree store.
1730 GtkTreeStore *store;
1731 GtkTreeModel *filter;
1735 GtkWidget *tree_view;
1737 store = gtk_tree_store_new (1, G_TYPE_STRING);
1738 gtk_tree_store_append (store, &iter, NULL);
1739 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
1741 gtk_tree_store_append (store, &iter, NULL);
1742 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
1744 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
1745 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
1746 specific_sort_filter_remove_node_compare_func, NULL, NULL);
1748 filter = gtk_tree_model_filter_new (sort, NULL);
1749 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1750 specific_sort_filter_remove_node_visible_func,
1754 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1755 tree_view = gtk_tree_view_new_with_model (filter);
1756 gtk_container_add (GTK_CONTAINER (window), tree_view);
1757 gtk_widget_realize (tree_view);
1759 while (gtk_events_pending ())
1760 gtk_main_iteration ();
1763 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
1764 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
1765 gtk_tree_store_remove (store, &iter);
1767 while (gtk_events_pending ())
1768 gtk_main_iteration ();
1773 specific_sort_filter_remove_root (void)
1775 /* This test is based on one of the test cases I found in my
1776 * old test cases directory. I unfortunately do not have a record
1777 * from who this test case originated. -Kris.
1780 GtkTreeModel *model, *sort, *filter;
1781 GtkTreeIter root, mid, leaf;
1784 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
1785 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
1786 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
1787 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
1789 path = gtk_tree_model_get_path (model, &mid);
1791 sort = gtk_tree_model_sort_new_with_model (model);
1792 filter = gtk_tree_model_filter_new (sort, path);
1794 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
1796 g_object_unref (filter);
1797 g_object_unref (sort);
1798 g_object_unref (model);
1803 specific_root_mixed_visibility (void)
1806 GtkTreeModel *filter;
1807 /* A bit nasty, apologies */
1810 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1812 for (i = 0; i < LEVEL_LENGTH; i++)
1816 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
1818 create_tree_store_set_values (fixture.store, &iter, TRUE);
1820 create_tree_store_set_values (fixture.store, &iter, FALSE);
1823 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1824 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1825 fixture.monitor = NULL;
1827 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
1829 /* In order to trigger the potential bug, we should not access
1830 * the filter model here (so don't call the check functions).
1833 /* Change visibility of an odd row to TRUE */
1834 set_path_visibility (&fixture, "3", TRUE);
1835 check_filter_model (&fixture);
1836 check_level_length (fixture.filter, NULL, 4);
1842 specific_has_child_filter_filter_func (GtkTreeModel *model,
1846 return gtk_tree_model_iter_has_child (model, iter);
1850 specific_has_child_filter (void)
1852 GtkTreeModel *filter;
1853 GtkTreeIter iter, root;
1854 /* A bit nasty, apologies */
1857 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1858 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1859 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1860 fixture.monitor = NULL;
1862 /* We will filter on parent state using a filter function. We will
1863 * manually keep the boolean column in sync, so that we can use
1864 * check_filter_model() to check the consistency of the model.
1866 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
1867 * to be able to check the structure here. We keep the calls to
1868 * check_filter_model() commented out until then.
1870 gtk_tree_model_filter_set_visible_func (fixture.filter,
1871 specific_has_child_filter_filter_func,
1874 gtk_tree_store_append (fixture.store, &root, NULL);
1875 create_tree_store_set_values (fixture.store, &root, FALSE);
1877 /* check_filter_model (&fixture); */
1878 check_level_length (fixture.filter, NULL, 0);
1880 gtk_tree_store_append (fixture.store, &iter, &root);
1881 create_tree_store_set_values (fixture.store, &iter, TRUE);
1883 /* Parent must now be visible. Do the level length check first,
1884 * to avoid modifying the child model triggering a row-changed to
1887 check_level_length (fixture.filter, NULL, 1);
1888 check_level_length (fixture.filter, "0", 0);
1890 set_path_visibility (&fixture, "0", TRUE);
1891 /* check_filter_model (&fixture); */
1893 gtk_tree_store_append (fixture.store, &root, NULL);
1894 check_level_length (fixture.filter, NULL, 1);
1896 gtk_tree_store_append (fixture.store, &iter, &root);
1897 check_level_length (fixture.filter, NULL, 2);
1898 check_level_length (fixture.filter, "1", 0);
1900 create_tree_store_set_values (fixture.store, &root, TRUE);
1901 create_tree_store_set_values (fixture.store, &iter, TRUE);
1903 /* check_filter_model (&fixture); */
1905 gtk_tree_store_append (fixture.store, &iter, &root);
1906 create_tree_store_set_values (fixture.store, &iter, TRUE);
1907 check_level_length (fixture.filter, NULL, 2);
1908 check_level_length (fixture.filter, "0", 0);
1909 check_level_length (fixture.filter, "1", 0);
1911 /* Now remove one of the remaining child rows */
1912 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
1914 gtk_tree_store_remove (fixture.store, &iter);
1916 check_level_length (fixture.filter, NULL, 1);
1917 check_level_length (fixture.filter, "0", 0);
1919 set_path_visibility (&fixture, "0", FALSE);
1920 /* check_filter_model (&fixture); */
1925 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
1932 path = gtk_tree_model_get_path (model, iter);
1933 depth = gtk_tree_path_get_depth (path);
1934 gtk_tree_path_free (path);
1939 return gtk_tree_model_iter_has_child (model, iter);
1943 specific_root_has_child_filter (void)
1945 GtkTreeModel *filter;
1946 GtkTreeIter iter, root;
1947 /* A bit nasty, apologies */
1950 /* This is a variation on the above test case wherein the has-child
1951 * check for visibility only applies to root level nodes.
1954 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1955 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1956 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1957 fixture.monitor = NULL;
1959 /* We will filter on parent state using a filter function. We will
1960 * manually keep the boolean column in sync, so that we can use
1961 * check_filter_model() to check the consistency of the model.
1963 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
1964 * to be able to check the structure here. We keep the calls to
1965 * check_filter_model() commented out until then.
1967 gtk_tree_model_filter_set_visible_func (fixture.filter,
1968 specific_root_has_child_filter_filter_func,
1971 gtk_tree_store_append (fixture.store, &root, NULL);
1972 create_tree_store_set_values (fixture.store, &root, FALSE);
1974 /* check_filter_model (&fixture); */
1975 check_level_length (fixture.filter, NULL, 0);
1977 gtk_tree_store_append (fixture.store, &iter, &root);
1978 create_tree_store_set_values (fixture.store, &iter, TRUE);
1980 /* Parent must now be visible. Do the level length check first,
1981 * to avoid modifying the child model triggering a row-changed to
1984 check_level_length (fixture.filter, NULL, 1);
1985 check_level_length (fixture.filter, "0", 1);
1987 set_path_visibility (&fixture, "0", TRUE);
1988 /* check_filter_model (&fixture); */
1990 gtk_tree_store_append (fixture.store, &root, NULL);
1991 check_level_length (fixture.filter, NULL, 1);
1993 gtk_tree_store_append (fixture.store, &iter, &root);
1994 check_level_length (fixture.filter, NULL, 2);
1995 check_level_length (fixture.filter, "1", 1);
1997 create_tree_store_set_values (fixture.store, &root, TRUE);
1998 create_tree_store_set_values (fixture.store, &iter, TRUE);
2000 /* check_filter_model (&fixture); */
2002 gtk_tree_store_append (fixture.store, &iter, &root);
2003 create_tree_store_set_values (fixture.store, &iter, TRUE);
2004 check_level_length (fixture.filter, NULL, 2);
2005 check_level_length (fixture.filter, "0", 1);
2006 check_level_length (fixture.filter, "1", 2);
2008 /* Now remove one of the remaining child rows */
2009 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
2011 gtk_tree_store_remove (fixture.store, &iter);
2013 check_level_length (fixture.filter, NULL, 1);
2014 check_level_length (fixture.filter, "0", 2);
2016 set_path_visibility (&fixture, "0", FALSE);
2017 /* check_filter_model (&fixture); */
2022 specific_filter_add_child (void)
2024 /* This test is based on one of the test cases I found in my
2025 * old test cases directory. I unfortunately do not have a record
2026 * from who this test case originated. -Kris.
2030 GtkTreeIter iter_first;
2032 GtkTreeStore *store;
2033 GtkTreeModel *filter;
2035 store = gtk_tree_store_new (1, G_TYPE_STRING);
2037 gtk_tree_store_append (store, &iter_first, NULL);
2038 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
2040 gtk_tree_store_append (store, &iter, NULL);
2041 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2043 gtk_tree_store_append (store, &iter, NULL);
2044 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2046 gtk_tree_store_append (store, &iter, NULL);
2047 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2049 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2051 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2052 gtk_tree_store_append (store, &child, &iter_first);
2053 gtk_tree_store_set (store, &child, 0, "Hello", -1);
2058 specific_bug_300089 (void)
2060 /* Test case for GNOME Bugzilla bug 300089. Written by
2063 GtkTreeModel *sort_model, *child_model;
2065 GtkTreeIter iter, iter2, sort_iter;
2067 child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
2069 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2070 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
2071 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2072 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "B", -1);
2074 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
2075 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "D", -1);
2076 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
2077 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "E", -1);
2079 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2080 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "C", -1);
2083 sort_model = GTK_TREE_MODEL (gtk_tree_model_sort_new_with_model (child_model));
2084 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
2085 0, GTK_SORT_ASCENDING);
2087 path = gtk_tree_path_new_from_indices (1, 1, -1);
2089 /* make sure a level is constructed */
2090 gtk_tree_model_get_iter (sort_model, &sort_iter, path);
2092 /* change the "E" row in a way that causes it to change position */
2093 gtk_tree_model_get_iter (child_model, &iter, path);
2094 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
2099 specific_bug_301558_sort_func (GtkTreeModel *model,
2106 gtk_tree_model_get (model, a, 0, &i, -1);
2107 gtk_tree_model_get (model, b, 0, &j, -1);
2113 specific_bug_301558 (void)
2115 /* Test case for GNOME Bugzilla bug 301558 provided by
2119 GtkTreeModel *filter;
2121 GtkTreeIter root, iter, iter2;
2126 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
2127 gtk_tree_store_append (tree, &iter, NULL);
2128 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
2129 gtk_tree_store_append (tree, &iter2, &iter);
2130 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
2132 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
2133 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
2134 specific_bug_301558_sort_func,
2137 filter = gtk_tree_model_filter_new (sort, NULL);
2138 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
2140 view = gtk_tree_view_new_with_model (filter);
2142 while (gtk_events_pending ())
2143 gtk_main_iteration ();
2147 for (i = 0; i < 10; i++)
2149 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
2150 g_assert_not_reached ();
2154 gtk_tree_store_append (tree, &iter, &root);
2155 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
2160 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
2161 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
2163 gtk_tree_store_remove (tree, &iter);
2172 specific_bug_311955_filter_func (GtkTreeModel *model,
2178 gtk_tree_model_get (model, iter, 0, &value, -1);
2180 return (value != 0);
2184 specific_bug_311955 (void)
2186 /* This is a test case for GNOME Bugzilla bug 311955. It was written
2189 GtkTreeIter iter, child, root;
2190 GtkTreeStore *store;
2192 GtkTreeModel *filter;
2195 GtkWidget *tree_view;
2199 store = gtk_tree_store_new (1, G_TYPE_INT);
2201 gtk_tree_store_append (store, &root, NULL);
2202 gtk_tree_store_set (store, &root, 0, 33, -1);
2204 gtk_tree_store_append (store, &iter, &root);
2205 gtk_tree_store_set (store, &iter, 0, 50, -1);
2207 gtk_tree_store_append (store, &iter, NULL);
2208 gtk_tree_store_set (store, &iter, 0, 22, -1);
2210 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2211 filter = gtk_tree_model_filter_new (sort, NULL);
2213 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2214 specific_bug_311955_filter_func,
2217 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2218 tree_view = gtk_tree_view_new_with_model (filter);
2219 g_object_unref (store);
2221 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2223 while (gtk_events_pending ())
2224 gtk_main_iteration ();
2227 for (i = 0; i < 4; i++)
2229 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2231 gtk_tree_store_append (store, &iter, &root);
2234 gtk_tree_store_set (store, &iter, 0, i, -1);
2238 gtk_tree_store_append (store, &child, &iter);
2239 gtk_tree_store_set (store, &child, 0, 10, -1);
2243 while (gtk_events_pending ())
2244 gtk_main_iteration ();
2246 /* Remove bottommost child from the tree. */
2247 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2248 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
2250 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
2252 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
2253 gtk_tree_store_remove (store, &child);
2256 g_assert_not_reached ();
2260 specific_bug_346800 (void)
2262 /* This is a test case for GNOME Bugzilla bug 346800. It was written
2263 * by Jonathan Matthew.
2266 GtkTreeIter node_iters[50];
2267 GtkTreeIter child_iters[50];
2268 GtkTreeModel *model;
2269 GtkTreeModelFilter *filter;
2270 GtkTreeStore *store;
2274 columns = g_new (GType, 2);
2275 columns[0] = G_TYPE_STRING;
2276 columns[1] = G_TYPE_BOOLEAN;
2277 store = gtk_tree_store_newv (2, columns);
2278 model = GTK_TREE_MODEL (store);
2280 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
2281 gtk_tree_model_filter_set_visible_column (filter, 1);
2283 for (i=0; i<items; i++)
2285 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
2288 gtk_tree_store_append (store, &node_iters[i], NULL);
2289 gtk_tree_store_set (store, &node_iters[i],
2291 1, ((i%6) == 0) ? FALSE : TRUE,
2295 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
2296 gtk_tree_store_set (store, &child_iters[i],
2297 0, "something else",
2300 gtk_tree_model_filter_refilter (filter);
2304 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
2305 (i & 1) ? TRUE : FALSE, -1);
2306 gtk_tree_model_filter_refilter (filter);
2308 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
2309 (i & 1) ? FALSE: TRUE, -1);
2310 gtk_tree_model_filter_refilter (filter);
2317 specific_bug_364946 (void)
2319 /* This is a test case for GNOME Bugzilla bug 364946. It was written
2320 * by Andreas Koehler.
2322 GtkTreeStore *store;
2323 GtkTreeIter a, aa, aaa, aab, iter;
2324 GtkTreeModel *s_model;
2326 store = gtk_tree_store_new (1, G_TYPE_STRING);
2328 gtk_tree_store_append (store, &a, NULL);
2329 gtk_tree_store_set (store, &a, 0, "0", -1);
2331 gtk_tree_store_append (store, &aa, &a);
2332 gtk_tree_store_set (store, &aa, 0, "0:0", -1);
2334 gtk_tree_store_append (store, &aaa, &aa);
2335 gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
2337 gtk_tree_store_append (store, &aab, &aa);
2338 gtk_tree_store_set (store, &aab, 0, "0:0:1", -1);
2340 s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2341 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model), 0,
2342 GTK_SORT_ASCENDING);
2344 gtk_tree_model_get_iter_from_string (s_model, &iter, "0:0:0");
2346 gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
2347 gtk_tree_store_remove (store, &aaa);
2348 gtk_tree_store_remove (store, &aab);
2350 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model));
2355 specific_bug_464173_visible_func (GtkTreeModel *model,
2359 gboolean *visible = (gboolean *)data;
2365 specific_bug_464173 (void)
2367 /* Test case for GNOME Bugzilla bug 464173, test case written
2368 * by Andreas Koehler.
2370 GtkTreeStore *model;
2371 GtkTreeModelFilter *f_model;
2372 GtkTreeIter iter1, iter2;
2374 gboolean visible = TRUE;
2376 model = gtk_tree_store_new (1, G_TYPE_STRING);
2377 gtk_tree_store_append (model, &iter1, NULL);
2378 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
2379 gtk_tree_store_append (model, &iter2, &iter1);
2380 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
2382 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
2383 gtk_tree_model_filter_set_visible_func (f_model,
2384 specific_bug_464173_visible_func,
2387 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
2390 gtk_tree_model_filter_refilter (f_model);
2395 specific_bug_540201_filter_func (GtkTreeModel *model,
2399 gboolean has_children;
2401 has_children = gtk_tree_model_iter_has_child (model, iter);
2403 return has_children;
2407 specific_bug_540201 (void)
2409 /* Test case for GNOME Bugzilla bug 540201, steps provided by
2412 GtkTreeIter iter, root;
2413 GtkTreeStore *store;
2414 GtkTreeModel *filter;
2416 GtkWidget *tree_view;
2418 store = gtk_tree_store_new (1, G_TYPE_INT);
2420 gtk_tree_store_append (store, &root, NULL);
2421 gtk_tree_store_set (store, &root, 0, 33, -1);
2423 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2424 tree_view = gtk_tree_view_new_with_model (filter);
2426 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2427 specific_bug_540201_filter_func,
2430 gtk_tree_store_append (store, &iter, &root);
2431 gtk_tree_store_set (store, &iter, 0, 50, -1);
2433 gtk_tree_store_append (store, &iter, &root);
2434 gtk_tree_store_set (store, &iter, 0, 22, -1);
2437 gtk_tree_store_append (store, &root, NULL);
2438 gtk_tree_store_set (store, &root, 0, 33, -1);
2440 gtk_tree_store_append (store, &iter, &root);
2441 gtk_tree_store_set (store, &iter, 0, 22, -1);
2446 specific_bug_549287_visible_func (GtkTreeModel *model,
2450 gboolean result = FALSE;
2452 result = gtk_tree_model_iter_has_child (model, iter);
2458 specific_bug_549287 (void)
2460 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
2463 GtkTreeStore *store;
2464 GtkTreeModel *filtered;
2467 GtkTreeIter *swap, *parent, *child;
2469 store = gtk_tree_store_new (1, G_TYPE_STRING);
2470 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2471 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
2472 specific_bug_549287_visible_func,
2475 view = gtk_tree_view_new_with_model (filtered);
2477 for (i = 0; i < 4; i++)
2479 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
2481 parent = gtk_tree_iter_copy (&iter);
2482 child = gtk_tree_iter_copy (&iter);
2484 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
2493 gtk_tree_store_append (store, child, parent);
2494 gtk_tree_store_set (store, child,
2498 gtk_tree_iter_free (parent);
2499 gtk_tree_iter_free (child);
2503 gtk_tree_store_append (store, &iter, NULL);
2504 gtk_tree_store_set (store, &iter,
2509 /* since we inserted something, we changed the visibility conditions: */
2510 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
2520 gtk_test_init (&argc, &argv, NULL);
2522 g_test_add ("/FilterModel/self/verify-test-suite",
2526 filter_test_teardown);
2528 g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-1",
2529 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2531 verify_test_suite_vroot,
2532 filter_test_teardown);
2533 g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-2",
2534 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
2536 verify_test_suite_vroot,
2537 filter_test_teardown);
2540 g_test_add ("/FilterModel/filled/hide-root-level",
2543 filled_hide_root_level,
2544 filter_test_teardown);
2545 g_test_add ("/FilterModel/filled/hide-child-levels",
2548 filled_hide_child_levels,
2549 filter_test_teardown);
2551 g_test_add ("/FilterModel/filled/hide-root-level/vroot",
2552 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2554 filled_vroot_hide_root_level,
2555 filter_test_teardown);
2556 g_test_add ("/FilterModel/filled/hide-child-levels/vroot",
2557 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2559 filled_vroot_hide_child_levels,
2560 filter_test_teardown);
2563 g_test_add ("/FilterModel/empty/show-nodes",
2565 filter_test_setup_empty,
2567 filter_test_teardown);
2569 g_test_add ("/FilterModel/empty/show-nodes/vroot",
2570 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2571 filter_test_setup_empty,
2572 empty_vroot_show_nodes,
2573 filter_test_teardown);
2576 g_test_add ("/FilterModel/unfiltered/hide-single",
2578 filter_test_setup_unfiltered,
2579 unfiltered_hide_single,
2580 filter_test_teardown);
2581 g_test_add ("/FilterModel/unfiltered/hide-single-child",
2583 filter_test_setup_unfiltered,
2584 unfiltered_hide_single_child,
2585 filter_test_teardown);
2586 g_test_add ("/FilterModel/unfiltered/hide-single-multi-level",
2588 filter_test_setup_unfiltered,
2589 unfiltered_hide_single_multi_level,
2590 filter_test_teardown);
2592 g_test_add ("/FilterModel/unfiltered/hide-single/vroot",
2593 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2594 filter_test_setup_unfiltered,
2595 unfiltered_vroot_hide_single,
2596 filter_test_teardown);
2597 g_test_add ("/FilterModel/unfiltered/hide-single-child/vroot",
2598 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2599 filter_test_setup_unfiltered,
2600 unfiltered_vroot_hide_single_child,
2601 filter_test_teardown);
2602 g_test_add ("/FilterModel/unfiltered/hide-single-multi-level/vroot",
2603 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2604 filter_test_setup_unfiltered,
2605 unfiltered_vroot_hide_single_multi_level,
2606 filter_test_teardown);
2610 g_test_add ("/FilterModel/unfiltered/show-single",
2612 filter_test_setup_empty_unfiltered,
2613 unfiltered_show_single,
2614 filter_test_teardown);
2615 g_test_add ("/FilterModel/unfiltered/show-single-child",
2617 filter_test_setup_empty_unfiltered,
2618 unfiltered_show_single_child,
2619 filter_test_teardown);
2620 g_test_add ("/FilterModel/unfiltered/show-single-multi-level",
2622 filter_test_setup_empty_unfiltered,
2623 unfiltered_show_single_multi_level,
2624 filter_test_teardown);
2626 g_test_add ("/FilterModel/unfiltered/show-single/vroot",
2627 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2628 filter_test_setup_empty_unfiltered,
2629 unfiltered_vroot_show_single,
2630 filter_test_teardown);
2631 g_test_add ("/FilterModel/unfiltered/show-single-child/vroot",
2632 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2633 filter_test_setup_empty_unfiltered,
2634 unfiltered_vroot_show_single_child,
2635 filter_test_teardown);
2636 g_test_add ("/FilterModel/unfiltered/show-single-multi-level/vroot",
2637 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2638 filter_test_setup_empty_unfiltered,
2639 unfiltered_vroot_show_single_multi_level,
2640 filter_test_teardown);
2643 g_test_add_func ("/FilterModel/specific/path-dependent-filter",
2644 specific_path_dependent_filter);
2645 g_test_add_func ("/FilterModel/specific/append-after-collapse",
2646 specific_append_after_collapse);
2647 g_test_add_func ("/FilterModel/specific/sort-filter-remove-node",
2648 specific_sort_filter_remove_node);
2649 g_test_add_func ("/FilterModel/specific/sort-filter-remove-root",
2650 specific_sort_filter_remove_root);
2651 g_test_add_func ("/FilterModel/specific/root-mixed-visibility",
2652 specific_root_mixed_visibility);
2653 g_test_add_func ("/FilterModel/specific/has-child-filter",
2654 specific_has_child_filter);
2655 g_test_add_func ("/FilterModel/specific/root-has-child-filter",
2656 specific_root_has_child_filter);
2657 g_test_add_func ("/FilterModel/specific/filter-add-child",
2658 specific_filter_add_child);
2660 g_test_add_func ("/FilterModel/specific/bug-300089",
2661 specific_bug_300089);
2662 g_test_add_func ("/FilterModel/specific/bug-301558",
2663 specific_bug_301558);
2664 g_test_add_func ("/FilterModel/specific/bug-311955",
2665 specific_bug_311955);
2666 g_test_add_func ("/FilterModel/specific/bug-346800",
2667 specific_bug_346800);
2668 g_test_add_func ("/FilterModel/specific/bug-364946",
2669 specific_bug_364946);
2670 g_test_add_func ("/FilterModel/specific/bug-464173",
2671 specific_bug_464173);
2672 g_test_add_func ("/FilterModel/specific/bug-540201",
2673 specific_bug_540201);
2674 g_test_add_func ("/FilterModel/specific/bug-549287",
2675 specific_bug_549287);
2677 return g_test_run ();