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 /* FIXME: We are missing a row-has-child-toggled signal for path "0:4" */
860 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
861 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:0");
862 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
863 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:1");
865 set_path_visibility (fixture, "0:4:2", TRUE);
866 set_path_visibility (fixture, "0:4:4", TRUE);
867 signal_monitor_assert_is_empty (fixture->monitor);
868 check_level_length (fixture->filter, "0:4", 2);
873 filled_vroot_hide_root_level (FilterTest *fixture,
874 gconstpointer user_data)
876 GtkTreePath *path = (GtkTreePath *)user_data;
878 /* These changes do not affect the filter's root level */
879 set_path_visibility (fixture, "0", FALSE);
880 check_filter_model_with_root (fixture, path);
881 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
882 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
884 set_path_visibility (fixture, "4", FALSE);
885 check_filter_model_with_root (fixture, path);
886 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
887 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
889 /* Even though we set the virtual root parent node to FALSE,
890 * the virtual root contents remain.
892 set_path_visibility (fixture, "2", FALSE);
893 check_filter_model_with_root (fixture, path);
894 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
895 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
898 set_path_visibility (fixture, "1", FALSE);
899 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
900 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
902 set_path_visibility (fixture, "3", FALSE);
903 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
904 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
906 check_filter_model_with_root (fixture, path);
909 set_path_visibility (fixture, "2", TRUE);
910 check_filter_model_with_root (fixture, path);
911 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
912 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
914 set_path_visibility (fixture, "1", TRUE);
915 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
916 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
918 set_path_visibility (fixture, "3", TRUE);
919 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
920 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
922 check_filter_model_with_root (fixture, path);
924 /* Now test changes in the virtual root level */
925 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
926 set_path_visibility (fixture, "2:2", FALSE);
927 check_filter_model_with_root (fixture, path);
928 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
930 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
931 set_path_visibility (fixture, "2:4", FALSE);
932 check_filter_model_with_root (fixture, path);
933 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
935 set_path_visibility (fixture, "1:4", FALSE);
936 check_filter_model_with_root (fixture, path);
937 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
939 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
940 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
941 set_path_visibility (fixture, "2:4", TRUE);
942 check_filter_model_with_root (fixture, path);
943 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
945 set_path_visibility (fixture, "2", FALSE);
946 check_filter_model_with_root (fixture, path);
947 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
949 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
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 set_path_visibility (fixture, "2:0", FALSE);
954 set_path_visibility (fixture, "2:1", FALSE);
955 set_path_visibility (fixture, "2:2", FALSE);
956 set_path_visibility (fixture, "2:3", FALSE);
957 set_path_visibility (fixture, "2:4", FALSE);
958 check_filter_model_with_root (fixture, path);
959 check_level_length (fixture->filter, NULL, 0);
961 set_path_visibility (fixture, "2", TRUE);
962 check_filter_model_with_root (fixture, path);
963 check_level_length (fixture->filter, NULL, 0);
965 set_path_visibility (fixture, "1:4", FALSE);
966 check_filter_model_with_root (fixture, path);
967 check_level_length (fixture->filter, NULL, 0);
969 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
970 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
971 set_path_visibility (fixture, "2:4", TRUE);
972 check_filter_model_with_root (fixture, path);
973 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
975 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
976 set_path_visibility (fixture, "2:4", FALSE);
977 check_filter_model_with_root (fixture, path);
978 check_level_length (fixture->filter, NULL, 0);
980 set_path_visibility (fixture, "2", FALSE);
981 check_filter_model_with_root (fixture, path);
982 check_level_length (fixture->filter, NULL, 0);
984 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
985 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
986 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
987 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
988 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
989 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
990 set_path_visibility (fixture, "2:0", TRUE);
991 set_path_visibility (fixture, "2:1", TRUE);
992 set_path_visibility (fixture, "2:2", TRUE);
993 check_filter_model_with_root (fixture, path);
994 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
996 set_path_visibility (fixture, "2", TRUE);
997 check_filter_model_with_root (fixture, path);
998 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1002 filled_vroot_hide_child_levels (FilterTest *fixture,
1003 gconstpointer user_data)
1005 GtkTreePath *path = (GtkTreePath *)user_data;
1007 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1008 set_path_visibility (fixture, "2:0:2", FALSE);
1009 check_filter_model_with_root (fixture, path);
1010 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1011 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1013 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1014 set_path_visibility (fixture, "2:0:4", FALSE);
1015 check_filter_model_with_root (fixture, path);
1016 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1017 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1019 set_path_visibility (fixture, "2:0:4:3", FALSE);
1020 check_filter_model_with_root (fixture, path);
1021 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1022 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1024 set_path_visibility (fixture, "2:0:4:0", FALSE);
1025 set_path_visibility (fixture, "2:0:4:1", FALSE);
1026 set_path_visibility (fixture, "2:0:4:2", FALSE);
1027 set_path_visibility (fixture, "2:0:4:4", FALSE);
1028 check_filter_model_with_root (fixture, path);
1029 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1030 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1032 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1033 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1034 /* FIXME: Actually, the filter model should not be emitted the
1035 * row-has-child-toggled signal here. *However* an extraneous emission
1036 * of this signal does not hurt and is allowed.
1038 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1039 set_path_visibility (fixture, "2:0:4", TRUE);
1040 check_filter_model_with_root (fixture, path);
1041 check_level_length (fixture->filter, "0:3", 0);
1043 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1044 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1045 set_path_visibility (fixture, "2:0:2", TRUE);
1046 check_filter_model_with_root (fixture, path);
1047 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1048 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1049 check_level_length (fixture->filter, "0:4", 0);
1051 /* FIXME: We are missing a row-has-child-toggled signal for path "0:4" */
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 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
1057 set_path_visibility (fixture, "2:0:4:2", TRUE);
1058 set_path_visibility (fixture, "2:0:4:4", TRUE);
1059 check_level_length (fixture->filter, "0:4", 2);
1064 empty_show_nodes (FilterTest *fixture,
1065 gconstpointer user_data)
1067 check_filter_model (fixture);
1068 check_level_length (fixture->filter, NULL, 0);
1070 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1071 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1072 set_path_visibility (fixture, "3", TRUE);
1073 check_filter_model (fixture);
1074 check_level_length (fixture->filter, NULL, 1);
1075 check_level_length (fixture->filter, "0", 0);
1077 set_path_visibility (fixture, "3:2:2", TRUE);
1078 check_filter_model (fixture);
1079 check_level_length (fixture->filter, NULL, 1);
1080 check_level_length (fixture->filter, "0", 0);
1082 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
1083 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
1084 set_path_visibility (fixture, "3:2", TRUE);
1085 check_filter_model (fixture);
1086 check_level_length (fixture->filter, NULL, 1);
1087 check_level_length (fixture->filter, "0", 1);
1088 check_level_length (fixture->filter, "0:0", 1);
1089 check_level_length (fixture->filter, "0:0:0", 0);
1091 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1092 set_path_visibility (fixture, "3", FALSE);
1093 check_filter_model (fixture);
1094 check_level_length (fixture->filter, NULL, 0);
1096 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1097 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1098 set_path_visibility (fixture, "3:2:1", TRUE);
1099 set_path_visibility (fixture, "3", TRUE);
1100 check_filter_model (fixture);
1101 check_level_length (fixture->filter, NULL, 1);
1102 check_level_length (fixture->filter, "0", 1);
1103 check_level_length (fixture->filter, "0:0", 2);
1104 check_level_length (fixture->filter, "0:0:0", 0);
1108 empty_vroot_show_nodes (FilterTest *fixture,
1109 gconstpointer user_data)
1111 GtkTreePath *path = (GtkTreePath *)user_data;
1113 check_filter_model_with_root (fixture, path);
1114 check_level_length (fixture->filter, NULL, 0);
1116 set_path_visibility (fixture, "2", TRUE);
1117 check_filter_model_with_root (fixture, path);
1118 check_level_length (fixture->filter, NULL, 0);
1120 set_path_visibility (fixture, "2:2:2", TRUE);
1121 check_filter_model_with_root (fixture, path);
1122 check_level_length (fixture->filter, NULL, 0);
1124 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1125 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1126 set_path_visibility (fixture, "2:2", TRUE);
1127 check_filter_model_with_root (fixture, path);
1128 check_level_length (fixture->filter, NULL, 1);
1129 check_level_length (fixture->filter, "0", 1);
1130 check_level_length (fixture->filter, "0:0", 0);
1132 set_path_visibility (fixture, "3", TRUE);
1133 check_filter_model_with_root (fixture, path);
1134 check_level_length (fixture->filter, NULL, 1);
1136 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1137 set_path_visibility (fixture, "2:2", FALSE);
1138 check_filter_model_with_root (fixture, path);
1139 check_level_length (fixture->filter, NULL, 0);
1141 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1142 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1143 set_path_visibility (fixture, "2:2:1", TRUE);
1144 set_path_visibility (fixture, "2:2", TRUE);
1145 check_filter_model_with_root (fixture, path);
1146 check_level_length (fixture->filter, NULL, 1);
1147 check_level_length (fixture->filter, "0", 2);
1148 check_level_length (fixture->filter, "0:1", 0);
1153 unfiltered_hide_single (FilterTest *fixture,
1154 gconstpointer user_data)
1157 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1158 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1159 set_path_visibility (fixture, "2", FALSE);
1161 signal_monitor_assert_is_empty (fixture->monitor);
1162 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1164 /* The view only shows the root level, so the filter model only has
1165 * the first two levels cached.
1167 filter_test_append_refilter_signals (fixture, 2);
1168 filter_test_enable_filter (fixture);
1170 check_filter_model (fixture);
1171 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1175 unfiltered_hide_single_child (FilterTest *fixture,
1176 gconstpointer user_data)
1179 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1180 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1181 set_path_visibility (fixture, "2:2", FALSE);
1183 signal_monitor_assert_is_empty (fixture->monitor);
1184 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1185 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1187 /* The view only shows the root level, so the filter model only has
1188 * the first two levels cached.
1190 filter_test_append_refilter_signals (fixture, 2);
1191 filter_test_enable_filter (fixture);
1193 check_filter_model (fixture);
1194 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1195 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1199 unfiltered_hide_single_multi_level (FilterTest *fixture,
1200 gconstpointer user_data)
1203 /* This row is not shown, so its signal is not propagated */
1204 set_path_visibility (fixture, "2:2:2", FALSE);
1206 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1207 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1208 set_path_visibility (fixture, "2:2", FALSE);
1210 signal_monitor_assert_is_empty (fixture->monitor);
1211 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1212 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1213 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1215 /* The view only shows the root level, so the filter model only has
1216 * the first two levels cached.
1218 filter_test_append_refilter_signals (fixture, 2);
1219 filter_test_enable_filter (fixture);
1221 check_filter_model (fixture);
1222 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1223 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1225 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1226 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1227 set_path_visibility (fixture, "2:2", TRUE);
1229 check_filter_model (fixture);
1230 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1231 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1232 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1237 unfiltered_vroot_hide_single (FilterTest *fixture,
1238 gconstpointer user_data)
1241 GtkTreePath *path = (GtkTreePath *)user_data;
1243 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1244 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1245 set_path_visibility (fixture, "2:2", FALSE);
1247 signal_monitor_assert_is_empty (fixture->monitor);
1248 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1250 /* The view only shows the root level, so the filter model only has
1251 * the first two levels cached. (We add an additional level to
1252 * take the virtual root into account).
1254 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1255 filter_test_enable_filter (fixture);
1257 check_filter_model_with_root (fixture, path);
1258 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1262 unfiltered_vroot_hide_single_child (FilterTest *fixture,
1263 gconstpointer user_data)
1266 GtkTreePath *path = (GtkTreePath *)user_data;
1268 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1269 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1270 set_path_visibility (fixture, "2:2:2", FALSE);
1272 signal_monitor_assert_is_empty (fixture->monitor);
1273 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1274 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1276 /* The view only shows the root level, so the filter model only has
1277 * the first two levels cached. (We add an additional level to take
1278 * the virtual root into account).
1280 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1281 filter_test_enable_filter (fixture);
1283 check_filter_model_with_root (fixture, path);
1284 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1285 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1289 unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
1290 gconstpointer user_data)
1293 GtkTreePath *path = (GtkTreePath *)user_data;
1295 /* This row is not shown, so its signal is not propagated */
1296 set_path_visibility (fixture, "2:2:2:2", FALSE);
1298 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1299 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1300 set_path_visibility (fixture, "2:2:2", FALSE);
1302 signal_monitor_assert_is_empty (fixture->monitor);
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);
1307 /* The view only shows the root level, so the filter model only has
1308 * the first two levels cached.
1310 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1311 filter_test_enable_filter (fixture);
1313 check_filter_model_with_root (fixture, path);
1314 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1315 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1317 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1318 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1319 set_path_visibility (fixture, "2:2:2", TRUE);
1321 check_filter_model_with_root (fixture, path);
1322 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1323 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1324 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1330 unfiltered_show_single (FilterTest *fixture,
1331 gconstpointer user_data)
1334 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1335 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1336 set_path_visibility (fixture, "2", TRUE);
1338 signal_monitor_assert_is_empty (fixture->monitor);
1339 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1341 /* The view only shows the root level, so the filter model only has
1342 * the first two levels cached.
1344 filter_test_append_refilter_signals (fixture, 2);
1345 filter_test_enable_filter (fixture);
1347 check_filter_model (fixture);
1348 check_level_length (fixture->filter, NULL, 1);
1352 unfiltered_show_single_child (FilterTest *fixture,
1353 gconstpointer user_data)
1356 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1357 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1358 set_path_visibility (fixture, "2:2", TRUE);
1360 signal_monitor_assert_is_empty (fixture->monitor);
1361 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1362 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1364 /* The view only shows the root level, so the filter model only has
1365 * the first two levels cached.
1367 filter_test_append_refilter_signals (fixture, 3);
1368 filter_test_enable_filter (fixture);
1370 check_filter_model (fixture);
1371 check_level_length (fixture->filter, NULL, 0);
1373 /* From here we are filtered, "2" in the real model is "0" in the filter
1376 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1377 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1378 set_path_visibility (fixture, "2", TRUE);
1379 signal_monitor_assert_is_empty (fixture->monitor);
1380 check_level_length (fixture->filter, NULL, 1);
1381 check_level_length (fixture->filter, "0", 1);
1385 unfiltered_show_single_multi_level (FilterTest *fixture,
1386 gconstpointer user_data)
1389 /* The view is not showing this row (collapsed state), so it is not
1390 * referenced. The signal should not go through.
1392 set_path_visibility (fixture, "2:2:2", TRUE);
1394 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1395 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1396 set_path_visibility (fixture, "2:2", TRUE);
1398 signal_monitor_assert_is_empty (fixture->monitor);
1399 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1400 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1401 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1403 /* The view only shows the root level, so the filter model only has
1404 * the first two levels cached.
1406 filter_test_append_refilter_signals (fixture, 3);
1407 filter_test_enable_filter (fixture);
1409 check_filter_model (fixture);
1410 check_level_length (fixture->filter, NULL, 0);
1412 /* From here we are filtered, "2" in the real model is "0" in the filter
1415 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1416 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1417 set_path_visibility (fixture, "2", TRUE);
1418 check_filter_model (fixture);
1419 check_level_length (fixture->filter, NULL, 1);
1420 check_level_length (fixture->filter, "0", 1);
1421 check_level_length (fixture->filter, "0:0", 1);
1426 unfiltered_vroot_show_single (FilterTest *fixture,
1427 gconstpointer user_data)
1430 GtkTreePath *path = (GtkTreePath *)user_data;
1432 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1433 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1434 set_path_visibility (fixture, "2:2", TRUE);
1436 signal_monitor_assert_is_empty (fixture->monitor);
1437 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1439 /* The view only shows the root level, so the filter model only has
1440 * the first two levels cached.
1442 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1443 filter_test_enable_filter (fixture);
1445 check_filter_model_with_root (fixture, path);
1446 check_level_length (fixture->filter, NULL, 1);
1450 unfiltered_vroot_show_single_child (FilterTest *fixture,
1451 gconstpointer user_data)
1454 GtkTreePath *path = (GtkTreePath *)user_data;
1456 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1457 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1458 set_path_visibility (fixture, "2:2:2", TRUE);
1460 signal_monitor_assert_is_empty (fixture->monitor);
1461 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1462 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1464 /* The view only shows the root level, so the filter model only has
1465 * the first two levels cached.
1467 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1468 filter_test_enable_filter (fixture);
1470 check_filter_model_with_root (fixture, path);
1471 check_level_length (fixture->filter, NULL, 0);
1473 /* From here we are filtered, "2" in the real model is "0" in the filter
1476 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1477 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1478 set_path_visibility (fixture, "2:2", TRUE);
1479 signal_monitor_assert_is_empty (fixture->monitor);
1480 check_level_length (fixture->filter, NULL, 1);
1481 check_level_length (fixture->filter, "0", 1);
1485 unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
1486 gconstpointer user_data)
1489 GtkTreePath *path = (GtkTreePath *)user_data;
1491 /* The view is not showing this row (collapsed state), so it is not
1492 * referenced. The signal should not go through.
1494 set_path_visibility (fixture, "2:2:2:2", TRUE);
1496 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1497 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1498 set_path_visibility (fixture, "2:2:2", TRUE);
1500 signal_monitor_assert_is_empty (fixture->monitor);
1501 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1502 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1503 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1505 /* The view only shows the root level, so the filter model only has
1506 * the first two levels cached.
1508 filter_test_append_refilter_signals_with_vroot (fixture, 4, path);
1509 filter_test_enable_filter (fixture);
1511 check_filter_model_with_root (fixture, path);
1512 check_level_length (fixture->filter, NULL, 0);
1514 /* From here we are filtered, "2" in the real model is "0" in the filter
1517 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1518 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1519 set_path_visibility (fixture, "2:2", TRUE);
1520 check_filter_model_with_root (fixture, path);
1521 check_level_length (fixture->filter, NULL, 1);
1522 check_level_length (fixture->filter, "0", 1);
1523 check_level_length (fixture->filter, "0:0", 1);
1528 specific_path_dependent_filter_func (GtkTreeModel *model,
1534 path = gtk_tree_model_get_path (model, iter);
1535 if (gtk_tree_path_get_indices (path)[0] < 4)
1542 specific_path_dependent_filter (void)
1548 GtkTreeModel *filter;
1550 list = gtk_list_store_new (1, G_TYPE_INT);
1551 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
1552 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
1553 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
1554 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
1555 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
1556 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
1557 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
1558 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
1560 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
1561 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
1562 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1563 specific_path_dependent_filter_func,
1566 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
1567 GTK_SORT_DESCENDING);
1569 for (i = 0; i < 4; i++)
1571 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1573 gtk_list_store_remove (list, &iter);
1575 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1577 gtk_list_store_remove (list, &iter);
1583 specific_append_after_collapse_visible_func (GtkTreeModel *model,
1588 gboolean hide_negative_numbers;
1590 gtk_tree_model_get (model, iter, 1, &number, -1);
1591 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
1593 return (number >= 0 || !hide_negative_numbers);
1597 specific_append_after_collapse (void)
1599 /* This test is based on one of the test cases I found in my
1600 * old test cases directory. I unfortunately do not have a record
1601 * from who this test case originated. -Kris.
1605 * - Show tree, expand, collapse.
1610 GtkTreeIter child_iter;
1611 GtkTreeIter child_iter2;
1612 GtkTreePath *append_path;
1613 GtkTreeStore *store;
1614 GtkTreeModel *filter;
1618 GtkWidget *tree_view;
1620 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
1622 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
1623 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
1624 GINT_TO_POINTER (FALSE));
1625 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1626 specific_append_after_collapse_visible_func,
1629 sort = gtk_tree_model_sort_new_with_model (filter);
1631 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1632 tree_view = gtk_tree_view_new_with_model (sort);
1633 gtk_container_add (GTK_CONTAINER (window), tree_view);
1634 gtk_widget_realize (tree_view);
1636 while (gtk_events_pending ())
1637 gtk_main_iteration ();
1639 gtk_tree_store_prepend (store, &iter, NULL);
1640 gtk_tree_store_set (store, &iter,
1641 0, "hallo", 1, 1, -1);
1643 gtk_tree_store_append (store, &child_iter, &iter);
1644 gtk_tree_store_set (store, &child_iter,
1645 0, "toemaar", 1, 1, -1);
1647 gtk_tree_store_append (store, &child_iter2, &child_iter);
1648 gtk_tree_store_set (store, &child_iter2,
1649 0, "very deep", 1, 1, -1);
1651 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
1653 gtk_tree_store_append (store, &child_iter, &iter);
1654 gtk_tree_store_set (store, &child_iter,
1655 0, "sja", 1, 1, -1);
1657 gtk_tree_store_append (store, &child_iter, &iter);
1658 gtk_tree_store_set (store, &child_iter,
1659 0, "some word", 1, -1, -1);
1661 /* Expand and collapse the tree */
1662 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
1663 while (gtk_events_pending ())
1664 gtk_main_iteration ();
1666 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
1667 while (gtk_events_pending ())
1668 gtk_main_iteration ();
1670 /* Add another it */
1671 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
1672 GINT_TO_POINTER (TRUE));
1674 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
1676 gtk_tree_store_append (store, &child_iter, &iter);
1677 gtk_tree_store_set (store, &child_iter,
1678 0, "new new new !!", 1, 1, -1);
1680 gtk_tree_path_free (append_path);
1683 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
1684 while (gtk_events_pending ())
1685 gtk_main_iteration ();
1690 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
1699 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
1705 /* Do reference the model */
1706 gtk_tree_model_get (model, iter, 0, &item, -1);
1713 specific_sort_filter_remove_node (void)
1715 /* This test is based on one of the test cases I found in my
1716 * old test cases directory. I unfortunately do not have a record
1717 * from who this test case originated. -Kris.
1720 * - Create tree store, sort, filter models. The sort model has
1721 * a default sort func that is enabled, filter model a visible func
1722 * that defaults to returning FALSE.
1723 * - Remove a node from the tree store.
1727 GtkTreeStore *store;
1728 GtkTreeModel *filter;
1732 GtkWidget *tree_view;
1734 store = gtk_tree_store_new (1, G_TYPE_STRING);
1735 gtk_tree_store_append (store, &iter, NULL);
1736 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
1738 gtk_tree_store_append (store, &iter, NULL);
1739 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
1741 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
1742 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
1743 specific_sort_filter_remove_node_compare_func, NULL, NULL);
1745 filter = gtk_tree_model_filter_new (sort, NULL);
1746 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1747 specific_sort_filter_remove_node_visible_func,
1751 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1752 tree_view = gtk_tree_view_new_with_model (filter);
1753 gtk_container_add (GTK_CONTAINER (window), tree_view);
1754 gtk_widget_realize (tree_view);
1756 while (gtk_events_pending ())
1757 gtk_main_iteration ();
1760 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
1761 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
1762 gtk_tree_store_remove (store, &iter);
1764 while (gtk_events_pending ())
1765 gtk_main_iteration ();
1770 specific_sort_filter_remove_root (void)
1772 /* This test is based on one of the test cases I found in my
1773 * old test cases directory. I unfortunately do not have a record
1774 * from who this test case originated. -Kris.
1777 GtkTreeModel *model, *sort, *filter;
1778 GtkTreeIter root, mid, leaf;
1781 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
1782 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
1783 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
1784 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
1786 path = gtk_tree_model_get_path (model, &mid);
1788 sort = gtk_tree_model_sort_new_with_model (model);
1789 filter = gtk_tree_model_filter_new (sort, path);
1791 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
1793 g_object_unref (filter);
1794 g_object_unref (sort);
1795 g_object_unref (model);
1800 specific_root_mixed_visibility (void)
1803 GtkTreeModel *filter;
1804 /* A bit nasty, apologies */
1807 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1809 for (i = 0; i < LEVEL_LENGTH; i++)
1813 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
1815 create_tree_store_set_values (fixture.store, &iter, TRUE);
1817 create_tree_store_set_values (fixture.store, &iter, FALSE);
1820 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1821 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1822 fixture.monitor = NULL;
1824 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
1826 /* In order to trigger the potential bug, we should not access
1827 * the filter model here (so don't call the check functions).
1830 /* Change visibility of an odd row to TRUE */
1831 set_path_visibility (&fixture, "3", TRUE);
1832 check_filter_model (&fixture);
1833 check_level_length (fixture.filter, NULL, 4);
1839 specific_has_child_filter_filter_func (GtkTreeModel *model,
1843 return gtk_tree_model_iter_has_child (model, iter);
1847 specific_has_child_filter (void)
1849 GtkTreeModel *filter;
1850 GtkTreeIter iter, root;
1851 /* A bit nasty, apologies */
1854 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1855 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1856 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1857 fixture.monitor = NULL;
1859 /* We will filter on parent state using a filter function. We will
1860 * manually keep the boolean column in sync, so that we can use
1861 * check_filter_model() to check the consistency of the model.
1863 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
1864 * to be able to check the structure here. We keep the calls to
1865 * check_filter_model() commented out until then.
1867 gtk_tree_model_filter_set_visible_func (fixture.filter,
1868 specific_has_child_filter_filter_func,
1871 gtk_tree_store_append (fixture.store, &root, NULL);
1872 create_tree_store_set_values (fixture.store, &root, FALSE);
1874 /* check_filter_model (&fixture); */
1875 check_level_length (fixture.filter, NULL, 0);
1877 gtk_tree_store_append (fixture.store, &iter, &root);
1878 create_tree_store_set_values (fixture.store, &iter, TRUE);
1880 /* Parent must now be visible. Do the level length check first,
1881 * to avoid modifying the child model triggering a row-changed to
1884 check_level_length (fixture.filter, NULL, 1);
1885 check_level_length (fixture.filter, "0", 0);
1887 set_path_visibility (&fixture, "0", TRUE);
1888 /* check_filter_model (&fixture); */
1890 gtk_tree_store_append (fixture.store, &root, NULL);
1891 check_level_length (fixture.filter, NULL, 1);
1893 gtk_tree_store_append (fixture.store, &iter, &root);
1894 check_level_length (fixture.filter, NULL, 2);
1895 check_level_length (fixture.filter, "1", 0);
1897 create_tree_store_set_values (fixture.store, &root, TRUE);
1898 create_tree_store_set_values (fixture.store, &iter, TRUE);
1900 /* check_filter_model (&fixture); */
1902 gtk_tree_store_append (fixture.store, &iter, &root);
1903 create_tree_store_set_values (fixture.store, &iter, TRUE);
1904 check_level_length (fixture.filter, NULL, 2);
1905 check_level_length (fixture.filter, "0", 0);
1906 check_level_length (fixture.filter, "1", 0);
1908 /* Now remove one of the remaining child rows */
1909 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
1911 gtk_tree_store_remove (fixture.store, &iter);
1913 check_level_length (fixture.filter, NULL, 1);
1914 check_level_length (fixture.filter, "0", 0);
1916 set_path_visibility (&fixture, "0", FALSE);
1917 /* check_filter_model (&fixture); */
1922 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
1929 path = gtk_tree_model_get_path (model, iter);
1930 depth = gtk_tree_path_get_depth (path);
1931 gtk_tree_path_free (path);
1936 return gtk_tree_model_iter_has_child (model, iter);
1940 specific_root_has_child_filter (void)
1942 GtkTreeModel *filter;
1943 GtkTreeIter iter, root;
1944 /* A bit nasty, apologies */
1947 /* This is a variation on the above test case wherein the has-child
1948 * check for visibility only applies to root level nodes.
1951 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1952 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1953 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1954 fixture.monitor = NULL;
1956 /* We will filter on parent state using a filter function. We will
1957 * manually keep the boolean column in sync, so that we can use
1958 * check_filter_model() to check the consistency of the model.
1960 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
1961 * to be able to check the structure here. We keep the calls to
1962 * check_filter_model() commented out until then.
1964 gtk_tree_model_filter_set_visible_func (fixture.filter,
1965 specific_root_has_child_filter_filter_func,
1968 gtk_tree_store_append (fixture.store, &root, NULL);
1969 create_tree_store_set_values (fixture.store, &root, FALSE);
1971 /* check_filter_model (&fixture); */
1972 check_level_length (fixture.filter, NULL, 0);
1974 gtk_tree_store_append (fixture.store, &iter, &root);
1975 create_tree_store_set_values (fixture.store, &iter, TRUE);
1977 /* Parent must now be visible. Do the level length check first,
1978 * to avoid modifying the child model triggering a row-changed to
1981 check_level_length (fixture.filter, NULL, 1);
1982 check_level_length (fixture.filter, "0", 1);
1984 set_path_visibility (&fixture, "0", TRUE);
1985 /* check_filter_model (&fixture); */
1987 gtk_tree_store_append (fixture.store, &root, NULL);
1988 check_level_length (fixture.filter, NULL, 1);
1990 gtk_tree_store_append (fixture.store, &iter, &root);
1991 check_level_length (fixture.filter, NULL, 2);
1992 check_level_length (fixture.filter, "1", 1);
1994 create_tree_store_set_values (fixture.store, &root, TRUE);
1995 create_tree_store_set_values (fixture.store, &iter, TRUE);
1997 /* check_filter_model (&fixture); */
1999 gtk_tree_store_append (fixture.store, &iter, &root);
2000 create_tree_store_set_values (fixture.store, &iter, TRUE);
2001 check_level_length (fixture.filter, NULL, 2);
2002 check_level_length (fixture.filter, "0", 1);
2003 check_level_length (fixture.filter, "1", 2);
2005 /* Now remove one of the remaining child rows */
2006 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
2008 gtk_tree_store_remove (fixture.store, &iter);
2010 check_level_length (fixture.filter, NULL, 1);
2011 check_level_length (fixture.filter, "0", 2);
2013 set_path_visibility (&fixture, "0", FALSE);
2014 /* check_filter_model (&fixture); */
2019 specific_filter_add_child (void)
2021 /* This test is based on one of the test cases I found in my
2022 * old test cases directory. I unfortunately do not have a record
2023 * from who this test case originated. -Kris.
2027 GtkTreeIter iter_first;
2029 GtkTreeStore *store;
2030 GtkTreeModel *filter;
2032 store = gtk_tree_store_new (1, G_TYPE_STRING);
2034 gtk_tree_store_append (store, &iter_first, NULL);
2035 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
2037 gtk_tree_store_append (store, &iter, NULL);
2038 gtk_tree_store_set (store, &iter, 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 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2048 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2049 gtk_tree_store_append (store, &child, &iter_first);
2050 gtk_tree_store_set (store, &child, 0, "Hello", -1);
2055 specific_bug_300089 (void)
2057 /* Test case for GNOME Bugzilla bug 300089. Written by
2060 GtkTreeModel *sort_model, *child_model;
2062 GtkTreeIter iter, iter2, sort_iter;
2064 child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
2066 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2067 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
2068 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2069 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "B", -1);
2071 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
2072 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "D", -1);
2073 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
2074 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "E", -1);
2076 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2077 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "C", -1);
2080 sort_model = GTK_TREE_MODEL (gtk_tree_model_sort_new_with_model (child_model));
2081 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
2082 0, GTK_SORT_ASCENDING);
2084 path = gtk_tree_path_new_from_indices (1, 1, -1);
2086 /* make sure a level is constructed */
2087 gtk_tree_model_get_iter (sort_model, &sort_iter, path);
2089 /* change the "E" row in a way that causes it to change position */
2090 gtk_tree_model_get_iter (child_model, &iter, path);
2091 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
2096 specific_bug_301558_sort_func (GtkTreeModel *model,
2103 gtk_tree_model_get (model, a, 0, &i, -1);
2104 gtk_tree_model_get (model, b, 0, &j, -1);
2110 specific_bug_301558 (void)
2112 /* Test case for GNOME Bugzilla bug 301558 provided by
2116 GtkTreeModel *filter;
2118 GtkTreeIter root, iter, iter2;
2123 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
2124 gtk_tree_store_append (tree, &iter, NULL);
2125 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
2126 gtk_tree_store_append (tree, &iter2, &iter);
2127 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
2129 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
2130 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
2131 specific_bug_301558_sort_func,
2134 filter = gtk_tree_model_filter_new (sort, NULL);
2135 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
2137 view = gtk_tree_view_new_with_model (filter);
2139 while (gtk_events_pending ())
2140 gtk_main_iteration ();
2144 for (i = 0; i < 10; i++)
2146 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
2147 g_assert_not_reached ();
2151 gtk_tree_store_append (tree, &iter, &root);
2152 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
2157 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
2158 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
2160 gtk_tree_store_remove (tree, &iter);
2169 specific_bug_311955_filter_func (GtkTreeModel *model,
2175 gtk_tree_model_get (model, iter, 0, &value, -1);
2177 return (value != 0);
2181 specific_bug_311955 (void)
2183 /* This is a test case for GNOME Bugzilla bug 311955. It was written
2186 GtkTreeIter iter, child, root;
2187 GtkTreeStore *store;
2189 GtkTreeModel *filter;
2192 GtkWidget *tree_view;
2196 store = gtk_tree_store_new (1, G_TYPE_INT);
2198 gtk_tree_store_append (store, &root, NULL);
2199 gtk_tree_store_set (store, &root, 0, 33, -1);
2201 gtk_tree_store_append (store, &iter, &root);
2202 gtk_tree_store_set (store, &iter, 0, 50, -1);
2204 gtk_tree_store_append (store, &iter, NULL);
2205 gtk_tree_store_set (store, &iter, 0, 22, -1);
2207 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2208 filter = gtk_tree_model_filter_new (sort, NULL);
2210 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2211 specific_bug_311955_filter_func,
2214 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2215 tree_view = gtk_tree_view_new_with_model (filter);
2216 g_object_unref (store);
2218 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2220 while (gtk_events_pending ())
2221 gtk_main_iteration ();
2224 for (i = 0; i < 4; i++)
2226 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2228 gtk_tree_store_append (store, &iter, &root);
2231 gtk_tree_store_set (store, &iter, 0, i, -1);
2235 gtk_tree_store_append (store, &child, &iter);
2236 gtk_tree_store_set (store, &child, 0, 10, -1);
2240 while (gtk_events_pending ())
2241 gtk_main_iteration ();
2243 /* Remove bottommost child from the tree. */
2244 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2245 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
2247 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
2249 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
2250 gtk_tree_store_remove (store, &child);
2253 g_assert_not_reached ();
2257 specific_bug_346800 (void)
2259 /* This is a test case for GNOME Bugzilla bug 346800. It was written
2260 * by Jonathan Matthew.
2263 GtkTreeIter node_iters[50];
2264 GtkTreeIter child_iters[50];
2265 GtkTreeModel *model;
2266 GtkTreeModelFilter *filter;
2267 GtkTreeStore *store;
2271 columns = g_new (GType, 2);
2272 columns[0] = G_TYPE_STRING;
2273 columns[1] = G_TYPE_BOOLEAN;
2274 store = gtk_tree_store_newv (2, columns);
2275 model = GTK_TREE_MODEL (store);
2277 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
2278 gtk_tree_model_filter_set_visible_column (filter, 1);
2280 for (i=0; i<items; i++)
2282 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
2285 gtk_tree_store_append (store, &node_iters[i], NULL);
2286 gtk_tree_store_set (store, &node_iters[i],
2288 1, ((i%6) == 0) ? FALSE : TRUE,
2292 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
2293 gtk_tree_store_set (store, &child_iters[i],
2294 0, "something else",
2297 gtk_tree_model_filter_refilter (filter);
2301 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
2302 (i & 1) ? TRUE : FALSE, -1);
2303 gtk_tree_model_filter_refilter (filter);
2305 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
2306 (i & 1) ? FALSE: TRUE, -1);
2307 gtk_tree_model_filter_refilter (filter);
2314 specific_bug_364946 (void)
2316 /* This is a test case for GNOME Bugzilla bug 364946. It was written
2317 * by Andreas Koehler.
2319 GtkTreeStore *store;
2320 GtkTreeIter a, aa, aaa, aab, iter;
2321 GtkTreeModel *s_model;
2323 store = gtk_tree_store_new (1, G_TYPE_STRING);
2325 gtk_tree_store_append (store, &a, NULL);
2326 gtk_tree_store_set (store, &a, 0, "0", -1);
2328 gtk_tree_store_append (store, &aa, &a);
2329 gtk_tree_store_set (store, &aa, 0, "0:0", -1);
2331 gtk_tree_store_append (store, &aaa, &aa);
2332 gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
2334 gtk_tree_store_append (store, &aab, &aa);
2335 gtk_tree_store_set (store, &aab, 0, "0:0:1", -1);
2337 s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2338 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model), 0,
2339 GTK_SORT_ASCENDING);
2341 gtk_tree_model_get_iter_from_string (s_model, &iter, "0:0:0");
2343 gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
2344 gtk_tree_store_remove (store, &aaa);
2345 gtk_tree_store_remove (store, &aab);
2347 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model));
2352 specific_bug_464173_visible_func (GtkTreeModel *model,
2356 gboolean *visible = (gboolean *)data;
2362 specific_bug_464173 (void)
2364 /* Test case for GNOME Bugzilla bug 464173, test case written
2365 * by Andreas Koehler.
2367 GtkTreeStore *model;
2368 GtkTreeModelFilter *f_model;
2369 GtkTreeIter iter1, iter2;
2371 gboolean visible = TRUE;
2373 model = gtk_tree_store_new (1, G_TYPE_STRING);
2374 gtk_tree_store_append (model, &iter1, NULL);
2375 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
2376 gtk_tree_store_append (model, &iter2, &iter1);
2377 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
2379 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
2380 gtk_tree_model_filter_set_visible_func (f_model,
2381 specific_bug_464173_visible_func,
2384 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
2387 gtk_tree_model_filter_refilter (f_model);
2392 specific_bug_540201_filter_func (GtkTreeModel *model,
2396 gboolean has_children;
2398 has_children = gtk_tree_model_iter_has_child (model, iter);
2400 return has_children;
2404 specific_bug_540201 (void)
2406 /* Test case for GNOME Bugzilla bug 540201, steps provided by
2409 GtkTreeIter iter, root;
2410 GtkTreeStore *store;
2411 GtkTreeModel *filter;
2413 GtkWidget *tree_view;
2415 store = gtk_tree_store_new (1, G_TYPE_INT);
2417 gtk_tree_store_append (store, &root, NULL);
2418 gtk_tree_store_set (store, &root, 0, 33, -1);
2420 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2421 tree_view = gtk_tree_view_new_with_model (filter);
2423 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2424 specific_bug_540201_filter_func,
2427 gtk_tree_store_append (store, &iter, &root);
2428 gtk_tree_store_set (store, &iter, 0, 50, -1);
2430 gtk_tree_store_append (store, &iter, &root);
2431 gtk_tree_store_set (store, &iter, 0, 22, -1);
2434 gtk_tree_store_append (store, &root, NULL);
2435 gtk_tree_store_set (store, &root, 0, 33, -1);
2437 gtk_tree_store_append (store, &iter, &root);
2438 gtk_tree_store_set (store, &iter, 0, 22, -1);
2443 specific_bug_549287_visible_func (GtkTreeModel *model,
2447 gboolean result = FALSE;
2449 result = gtk_tree_model_iter_has_child (model, iter);
2455 specific_bug_549287 (void)
2457 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
2460 GtkTreeStore *store;
2461 GtkTreeModel *filtered;
2464 GtkTreeIter *swap, *parent, *child;
2466 store = gtk_tree_store_new (1, G_TYPE_STRING);
2467 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2468 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
2469 specific_bug_549287_visible_func,
2472 view = gtk_tree_view_new_with_model (filtered);
2474 for (i = 0; i < 4; i++)
2476 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
2478 parent = gtk_tree_iter_copy (&iter);
2479 child = gtk_tree_iter_copy (&iter);
2481 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
2490 gtk_tree_store_append (store, child, parent);
2491 gtk_tree_store_set (store, child,
2495 gtk_tree_iter_free (parent);
2496 gtk_tree_iter_free (child);
2500 gtk_tree_store_append (store, &iter, NULL);
2501 gtk_tree_store_set (store, &iter,
2506 /* since we inserted something, we changed the visibility conditions: */
2507 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
2517 gtk_test_init (&argc, &argv, NULL);
2519 g_test_add ("/FilterModel/self/verify-test-suite",
2523 filter_test_teardown);
2525 g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-1",
2526 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2528 verify_test_suite_vroot,
2529 filter_test_teardown);
2530 g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-2",
2531 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
2533 verify_test_suite_vroot,
2534 filter_test_teardown);
2537 g_test_add ("/FilterModel/filled/hide-root-level",
2540 filled_hide_root_level,
2541 filter_test_teardown);
2542 g_test_add ("/FilterModel/filled/hide-child-levels",
2545 filled_hide_child_levels,
2546 filter_test_teardown);
2548 g_test_add ("/FilterModel/filled/hide-root-level/vroot",
2549 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2551 filled_vroot_hide_root_level,
2552 filter_test_teardown);
2553 g_test_add ("/FilterModel/filled/hide-child-levels/vroot",
2554 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2556 filled_vroot_hide_child_levels,
2557 filter_test_teardown);
2560 g_test_add ("/FilterModel/empty/show-nodes",
2562 filter_test_setup_empty,
2564 filter_test_teardown);
2566 g_test_add ("/FilterModel/empty/show-nodes/vroot",
2567 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2568 filter_test_setup_empty,
2569 empty_vroot_show_nodes,
2570 filter_test_teardown);
2573 g_test_add ("/FilterModel/unfiltered/hide-single",
2575 filter_test_setup_unfiltered,
2576 unfiltered_hide_single,
2577 filter_test_teardown);
2578 g_test_add ("/FilterModel/unfiltered/hide-single-child",
2580 filter_test_setup_unfiltered,
2581 unfiltered_hide_single_child,
2582 filter_test_teardown);
2583 g_test_add ("/FilterModel/unfiltered/hide-single-multi-level",
2585 filter_test_setup_unfiltered,
2586 unfiltered_hide_single_multi_level,
2587 filter_test_teardown);
2589 g_test_add ("/FilterModel/unfiltered/hide-single/vroot",
2590 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2591 filter_test_setup_unfiltered,
2592 unfiltered_vroot_hide_single,
2593 filter_test_teardown);
2594 g_test_add ("/FilterModel/unfiltered/hide-single-child/vroot",
2595 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2596 filter_test_setup_unfiltered,
2597 unfiltered_vroot_hide_single_child,
2598 filter_test_teardown);
2599 g_test_add ("/FilterModel/unfiltered/hide-single-multi-level/vroot",
2600 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2601 filter_test_setup_unfiltered,
2602 unfiltered_vroot_hide_single_multi_level,
2603 filter_test_teardown);
2607 g_test_add ("/FilterModel/unfiltered/show-single",
2609 filter_test_setup_empty_unfiltered,
2610 unfiltered_show_single,
2611 filter_test_teardown);
2612 g_test_add ("/FilterModel/unfiltered/show-single-child",
2614 filter_test_setup_empty_unfiltered,
2615 unfiltered_show_single_child,
2616 filter_test_teardown);
2617 g_test_add ("/FilterModel/unfiltered/show-single-multi-level",
2619 filter_test_setup_empty_unfiltered,
2620 unfiltered_show_single_multi_level,
2621 filter_test_teardown);
2623 g_test_add ("/FilterModel/unfiltered/show-single/vroot",
2624 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2625 filter_test_setup_empty_unfiltered,
2626 unfiltered_vroot_show_single,
2627 filter_test_teardown);
2628 g_test_add ("/FilterModel/unfiltered/show-single-child/vroot",
2629 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2630 filter_test_setup_empty_unfiltered,
2631 unfiltered_vroot_show_single_child,
2632 filter_test_teardown);
2633 g_test_add ("/FilterModel/unfiltered/show-single-multi-level/vroot",
2634 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2635 filter_test_setup_empty_unfiltered,
2636 unfiltered_vroot_show_single_multi_level,
2637 filter_test_teardown);
2640 g_test_add_func ("/FilterModel/specific/path-dependent-filter",
2641 specific_path_dependent_filter);
2642 g_test_add_func ("/FilterModel/specific/append-after-collapse",
2643 specific_append_after_collapse);
2644 g_test_add_func ("/FilterModel/specific/sort-filter-remove-node",
2645 specific_sort_filter_remove_node);
2646 g_test_add_func ("/FilterModel/specific/sort-filter-remove-root",
2647 specific_sort_filter_remove_root);
2648 g_test_add_func ("/FilterModel/specific/root-mixed-visibility",
2649 specific_root_mixed_visibility);
2650 g_test_add_func ("/FilterModel/specific/has-child-filter",
2651 specific_has_child_filter);
2652 g_test_add_func ("/FilterModel/specific/root-has-child-filter",
2653 specific_root_has_child_filter);
2654 g_test_add_func ("/FilterModel/specific/filter-add-child",
2655 specific_filter_add_child);
2657 g_test_add_func ("/FilterModel/specific/bug-300089",
2658 specific_bug_300089);
2659 g_test_add_func ("/FilterModel/specific/bug-301558",
2660 specific_bug_301558);
2661 g_test_add_func ("/FilterModel/specific/bug-311955",
2662 specific_bug_311955);
2663 g_test_add_func ("/FilterModel/specific/bug-346800",
2664 specific_bug_346800);
2665 g_test_add_func ("/FilterModel/specific/bug-364946",
2666 specific_bug_364946);
2667 g_test_add_func ("/FilterModel/specific/bug-464173",
2668 specific_bug_464173);
2669 g_test_add_func ("/FilterModel/specific/bug-540201",
2670 specific_bug_540201);
2671 g_test_add_func ("/FilterModel/specific/bug-549287",
2672 specific_bug_549287);
2674 return g_test_run ();