1 /* Extensive GtkTreeModelFilter tests.
2 * Copyright (C) 2009 Kristian Rietveld <kris@gtk.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
24 * - Proper coverage checking to see if the unit tests cover
26 * - Verify if the ref counting is done properly for both the
27 * normal ref_count and the zero_ref_count. One way to test
28 * this area is by collapsing/expanding branches on the view
29 * that is connected to the filter model.
30 * - Check if the iterator stamp is incremented at the correct times.
38 #define LEVEL_LENGTH 5
41 create_tree_store_set_values (GtkTreeStore *store,
48 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
49 path_string = gtk_tree_path_to_string (path);
51 gtk_tree_store_set (store, iter,
56 gtk_tree_path_free (path);
61 create_tree_store_recurse (int depth,
68 for (i = 0; i < LEVEL_LENGTH; i++)
72 gtk_tree_store_insert (store, &iter, parent, i);
73 create_tree_store_set_values (store, &iter, visible);
76 create_tree_store_recurse (depth - 1, store, &iter, visible);
81 create_tree_store (int depth,
86 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
88 create_tree_store_recurse (depth, store, NULL, visible);
102 ROW_HAS_CHILD_TOGGLED,
117 signal_new (SignalName signal, GtkTreePath *path)
121 s = g_new0 (Signal, 1);
123 s->path = gtk_tree_path_copy (path);
129 signal_free (Signal *s)
132 gtk_tree_path_free (s->path);
141 GtkTreeModel *client;
142 guint signal_ids[LAST_SIGNAL];
148 signal_monitor_generic_handler (SignalMonitor *m,
155 g_return_if_fail (m->client == model);
156 g_return_if_fail (!g_queue_is_empty (m->queue));
159 /* For debugging: output signals that are coming in. Leaks memory. */
160 g_print ("signal=%d path=%s\n", signal, gtk_tree_path_to_string (path));
163 s = g_queue_peek_tail (m->queue);
165 g_return_if_fail (s->signal == signal);
167 s = g_queue_pop_tail (m->queue);
169 g_return_if_fail (!gtk_tree_path_compare (path, s->path));
175 signal_monitor_row_inserted (GtkTreeModel *model,
180 signal_monitor_generic_handler (data, ROW_INSERTED,
185 signal_monitor_row_deleted (GtkTreeModel *model,
189 signal_monitor_generic_handler (data, ROW_DELETED,
194 signal_monitor_row_changed (GtkTreeModel *model,
199 signal_monitor_generic_handler (data, ROW_CHANGED,
204 signal_monitor_row_has_child_toggled (GtkTreeModel *model,
209 signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
214 signal_monitor_rows_reordered (GtkTreeModel *model,
220 signal_monitor_generic_handler (data, ROWS_REORDERED,
224 static SignalMonitor *
225 signal_monitor_new (GtkTreeModel *client)
229 m = g_new0 (SignalMonitor, 1);
230 m->client = g_object_ref (client);
231 m->queue = g_queue_new ();
233 m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
235 G_CALLBACK (signal_monitor_row_inserted),
237 m->signal_ids[ROW_DELETED] = g_signal_connect (client,
239 G_CALLBACK (signal_monitor_row_deleted),
241 m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
243 G_CALLBACK (signal_monitor_row_changed),
245 m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
246 "row-has-child-toggled",
247 G_CALLBACK (signal_monitor_row_has_child_toggled),
249 m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
251 G_CALLBACK (signal_monitor_rows_reordered),
258 signal_monitor_free (SignalMonitor *m)
262 for (i = 0; i < LAST_SIGNAL; i++)
263 g_signal_handler_disconnect (m->client, m->signal_ids[i]);
265 g_object_unref (m->client);
268 g_queue_free (m->queue);
274 signal_monitor_assert_is_empty (SignalMonitor *m)
276 g_assert (g_queue_is_empty (m->queue));
280 signal_monitor_append_signal_path (SignalMonitor *m,
286 s = signal_new (signal, path);
287 g_queue_push_head (m->queue, s);
291 signal_monitor_append_signal (SignalMonitor *m,
293 const gchar *path_string)
298 path = gtk_tree_path_new_from_string (path_string);
300 s = signal_new (signal, path);
301 g_queue_push_head (m->queue, s);
303 gtk_tree_path_free (path);
312 GtkWidget *tree_view;
315 GtkTreeModelFilter *filter;
317 SignalMonitor *monitor;
321 filter_test_setup_generic (FilterTest *fixture,
322 gconstpointer test_data,
327 const GtkTreePath *vroot = test_data;
328 GtkTreeModel *filter;
330 fixture->store = create_tree_store (depth, !empty);
332 /* Please forgive me for casting const away. */
333 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
334 (GtkTreePath *)vroot);
335 fixture->filter = GTK_TREE_MODEL_FILTER (filter);
338 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
340 /* We need a tree view that's listening to get ref counting from that
343 fixture->tree_view = gtk_tree_view_new_with_model (filter);
345 fixture->monitor = signal_monitor_new (filter);
349 filter_test_setup (FilterTest *fixture,
350 gconstpointer test_data)
352 filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
356 filter_test_setup_empty (FilterTest *fixture,
357 gconstpointer test_data)
359 filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
363 filter_test_setup_unfiltered (FilterTest *fixture,
364 gconstpointer test_data)
366 filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
370 filter_test_setup_empty_unfiltered (FilterTest *fixture,
371 gconstpointer test_data)
373 filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
377 strip_virtual_root (GtkTreePath *path,
378 GtkTreePath *root_path)
380 GtkTreePath *real_path;
385 int depth = gtk_tree_path_get_depth (path);
386 int root_depth = gtk_tree_path_get_depth (root_path);
388 real_path = gtk_tree_path_new ();
390 for (j = 0; j < depth - root_depth; j++)
391 gtk_tree_path_append_index (real_path,
392 gtk_tree_path_get_indices (path)[root_depth + j]);
395 real_path = gtk_tree_path_copy (path);
401 filter_test_append_refilter_signals_recurse (FilterTest *fixture,
402 GtkTreePath *store_path,
403 GtkTreePath *filter_path,
405 GtkTreePath *root_path)
408 int rows_deleted = 0;
411 gtk_tree_path_down (store_path);
412 gtk_tree_path_down (filter_path);
414 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
417 for (i = 0; i < LEVEL_LENGTH; i++)
420 GtkTreePath *real_path;
422 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
427 (!gtk_tree_path_is_descendant (store_path, root_path)
428 || !gtk_tree_path_compare (store_path, root_path)))
430 if (!gtk_tree_path_compare (store_path, root_path))
433 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
436 GtkTreePath *store_copy;
437 GtkTreePath *filter_copy;
439 store_copy = gtk_tree_path_copy (store_path);
440 filter_copy = gtk_tree_path_copy (filter_path);
441 filter_test_append_refilter_signals_recurse (fixture,
446 gtk_tree_path_free (store_copy);
447 gtk_tree_path_free (filter_copy);
451 gtk_tree_path_next (store_path);
452 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
455 gtk_tree_path_next (filter_path);
460 real_path = strip_virtual_root (filter_path, root_path);
464 /* This row will be inserted */
465 signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
467 signal_monitor_append_signal_path (fixture->monitor,
468 ROW_HAS_CHILD_TOGGLED,
472 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
475 GtkTreePath *store_copy;
476 GtkTreePath *filter_copy;
478 store_copy = gtk_tree_path_copy (store_path);
479 filter_copy = gtk_tree_path_copy (filter_path);
480 filter_test_append_refilter_signals_recurse (fixture,
485 gtk_tree_path_free (store_copy);
486 gtk_tree_path_free (filter_copy);
489 gtk_tree_path_next (filter_path);
493 /* This row will be deleted */
495 signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
499 gtk_tree_path_free (real_path);
501 gtk_tree_path_next (store_path);
502 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
505 if (rows_deleted == LEVEL_LENGTH
506 && gtk_tree_path_get_depth (filter_path) > 1)
508 GtkTreePath *real_path;
510 gtk_tree_path_up (store_path);
511 gtk_tree_path_up (filter_path);
513 /* A row-has-child-toggled will be emitted on the parent */
516 && gtk_tree_path_is_descendant (store_path, root_path)
517 && gtk_tree_path_compare (store_path, root_path)))
519 real_path = strip_virtual_root (filter_path, root_path);
520 signal_monitor_append_signal_path (fixture->monitor,
521 ROW_HAS_CHILD_TOGGLED,
524 gtk_tree_path_free (real_path);
530 filter_test_append_refilter_signals (FilterTest *fixture,
533 /* A special function that walks the tree store like the
534 * model validation functions below.
537 GtkTreePath *filter_path;
539 path = gtk_tree_path_new ();
540 filter_path = gtk_tree_path_new ();
541 filter_test_append_refilter_signals_recurse (fixture,
546 gtk_tree_path_free (path);
547 gtk_tree_path_free (filter_path);
551 filter_test_append_refilter_signals_with_vroot (FilterTest *fixture,
553 GtkTreePath *root_path)
555 /* A special function that walks the tree store like the
556 * model validation functions below.
559 GtkTreePath *filter_path;
561 path = gtk_tree_path_new ();
562 filter_path = gtk_tree_path_new ();
563 filter_test_append_refilter_signals_recurse (fixture,
568 gtk_tree_path_free (path);
569 gtk_tree_path_free (filter_path);
573 filter_test_enable_filter (FilterTest *fixture)
575 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
576 gtk_tree_model_filter_refilter (fixture->filter);
580 filter_test_teardown (FilterTest *fixture,
581 gconstpointer test_data)
583 signal_monitor_free (fixture->monitor);
585 g_object_unref (fixture->filter);
586 g_object_unref (fixture->store);
590 * Model structure validation
594 check_filter_model_recurse (FilterTest *fixture,
595 GtkTreePath *store_parent_path,
596 GtkTreePath *filter_parent_path)
599 GtkTreeIter store_iter;
600 GtkTreeIter filter_iter;
601 gboolean store_has_next, filter_has_next;
603 gtk_tree_path_down (store_parent_path);
604 gtk_tree_path_down (filter_parent_path);
606 store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
607 &store_iter, store_parent_path);
608 filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
609 &filter_iter, filter_parent_path);
611 for (i = 0; i < LEVEL_LENGTH; i++)
615 g_return_if_fail (store_has_next == TRUE);
617 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
625 gchar *filter_str, *store_str;
627 g_return_if_fail (filter_has_next == TRUE);
630 tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
632 g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
634 /* Verify model content */
635 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
639 gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
644 g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
649 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
652 g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
654 check_filter_model_recurse (fixture,
655 gtk_tree_path_copy (store_parent_path),
659 gtk_tree_path_next (filter_parent_path);
660 filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
663 gtk_tree_path_next (store_parent_path);
664 store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
667 /* Both models should have no more content! */
668 g_return_if_fail (store_has_next == FALSE);
669 g_return_if_fail (filter_has_next == FALSE);
671 gtk_tree_path_free (store_parent_path);
672 gtk_tree_path_free (filter_parent_path);
676 check_filter_model (FilterTest *fixture)
680 if (fixture->monitor)
681 signal_monitor_assert_is_empty (fixture->monitor);
683 path = gtk_tree_path_new ();
685 check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
689 check_filter_model_with_root (FilterTest *fixture,
692 if (fixture->monitor)
693 signal_monitor_assert_is_empty (fixture->monitor);
695 check_filter_model_recurse (fixture,
696 gtk_tree_path_copy (path),
697 gtk_tree_path_new ());
703 check_level_length (GtkTreeModelFilter *filter,
709 int l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
710 g_return_if_fail (l == length);
715 gboolean retrieved_iter = FALSE;
718 retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
720 g_return_if_fail (retrieved_iter);
721 l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
722 g_return_if_fail (l == length);
727 set_path_visibility (FilterTest *fixture,
731 GtkTreeIter store_iter;
733 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
735 gtk_tree_store_set (fixture->store, &store_iter,
742 insert_path_with_visibility (FilterTest *fixture,
743 const gchar *path_string,
748 GtkTreeIter parent, iter;
750 path = gtk_tree_path_new_from_string (path_string);
751 position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
752 gtk_tree_path_up (path);
754 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
756 gtk_tree_store_insert (fixture->store, &iter, &parent, position);
757 create_tree_store_set_values (fixture->store, &iter, visible);
759 gtk_tree_path_free (path);
768 verify_test_suite (FilterTest *fixture,
769 gconstpointer user_data)
771 check_filter_model (fixture);
775 verify_test_suite_vroot (FilterTest *fixture,
776 gconstpointer user_data)
778 check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
783 filled_hide_root_level (FilterTest *fixture,
784 gconstpointer user_data)
786 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
787 set_path_visibility (fixture, "2", FALSE);
788 check_filter_model (fixture);
789 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
791 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
792 set_path_visibility (fixture, "0", FALSE);
793 check_filter_model (fixture);
794 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
796 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
797 set_path_visibility (fixture, "4", FALSE);
798 check_filter_model (fixture);
799 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
803 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
804 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
806 set_path_visibility (fixture, "1", FALSE);
807 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
809 set_path_visibility (fixture, "3", FALSE);
810 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
812 check_filter_model (fixture);
815 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
816 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
817 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
818 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
820 set_path_visibility (fixture, "1", TRUE);
821 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
823 set_path_visibility (fixture, "3", TRUE);
824 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
826 check_filter_model (fixture);
830 filled_hide_child_levels (FilterTest *fixture,
831 gconstpointer user_data)
833 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
834 set_path_visibility (fixture, "0:2", FALSE);
835 check_filter_model (fixture);
836 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
837 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
839 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
840 set_path_visibility (fixture, "0:4", FALSE);
841 check_filter_model (fixture);
842 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
843 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
845 set_path_visibility (fixture, "0:4:3", FALSE);
846 check_filter_model (fixture);
847 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
848 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
850 set_path_visibility (fixture, "0:4:0", FALSE);
851 set_path_visibility (fixture, "0:4:1", FALSE);
852 set_path_visibility (fixture, "0:4:2", FALSE);
853 set_path_visibility (fixture, "0:4:4", FALSE);
854 check_filter_model (fixture);
855 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
856 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
858 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
859 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
860 /* FIXME: Actually, the filter model should not be emitted the
861 * row-has-child-toggled signal here. *However* an extraneous emission
862 * of this signal does not hurt and is allowed.
864 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
865 set_path_visibility (fixture, "0:4", TRUE);
866 check_filter_model (fixture);
867 check_level_length (fixture->filter, "0:3", 0);
869 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
870 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
871 set_path_visibility (fixture, "0:2", TRUE);
872 check_filter_model (fixture);
873 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
874 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
875 check_level_length (fixture->filter, "0:4", 0);
877 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
878 /* Once 0:4:0 got inserted, 0:4 became a parent */
879 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
880 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:0");
881 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
882 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:1");
884 set_path_visibility (fixture, "0:4:2", TRUE);
885 set_path_visibility (fixture, "0:4:4", TRUE);
886 signal_monitor_assert_is_empty (fixture->monitor);
887 check_level_length (fixture->filter, "0:4", 2);
892 filled_vroot_hide_root_level (FilterTest *fixture,
893 gconstpointer user_data)
895 GtkTreePath *path = (GtkTreePath *)user_data;
897 /* These changes do not affect the filter's root level */
898 set_path_visibility (fixture, "0", FALSE);
899 check_filter_model_with_root (fixture, path);
900 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
901 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
903 set_path_visibility (fixture, "4", FALSE);
904 check_filter_model_with_root (fixture, path);
905 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
906 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
908 /* Even though we set the virtual root parent node to FALSE,
909 * the virtual root contents remain.
911 set_path_visibility (fixture, "2", FALSE);
912 check_filter_model_with_root (fixture, path);
913 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
914 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
917 set_path_visibility (fixture, "1", FALSE);
918 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
919 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
921 set_path_visibility (fixture, "3", FALSE);
922 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
923 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
925 check_filter_model_with_root (fixture, path);
928 set_path_visibility (fixture, "2", TRUE);
929 check_filter_model_with_root (fixture, path);
930 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
931 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
933 set_path_visibility (fixture, "1", TRUE);
934 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
935 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
937 set_path_visibility (fixture, "3", TRUE);
938 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
939 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
941 check_filter_model_with_root (fixture, path);
943 /* Now test changes in the virtual root level */
944 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
945 set_path_visibility (fixture, "2: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, "3");
950 set_path_visibility (fixture, "2:4", FALSE);
951 check_filter_model_with_root (fixture, path);
952 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
954 set_path_visibility (fixture, "1:4", FALSE);
955 check_filter_model_with_root (fixture, path);
956 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
958 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
959 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
960 set_path_visibility (fixture, "2:4", TRUE);
961 check_filter_model_with_root (fixture, path);
962 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
964 set_path_visibility (fixture, "2", FALSE);
965 check_filter_model_with_root (fixture, path);
966 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
968 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
969 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
970 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
971 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
972 set_path_visibility (fixture, "2:0", FALSE);
973 set_path_visibility (fixture, "2:1", FALSE);
974 set_path_visibility (fixture, "2:2", FALSE);
975 set_path_visibility (fixture, "2:3", FALSE);
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", TRUE);
981 check_filter_model_with_root (fixture, path);
982 check_level_length (fixture->filter, NULL, 0);
984 set_path_visibility (fixture, "1:4", FALSE);
985 check_filter_model_with_root (fixture, path);
986 check_level_length (fixture->filter, NULL, 0);
988 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
989 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
990 set_path_visibility (fixture, "2:4", TRUE);
991 check_filter_model_with_root (fixture, path);
992 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
994 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
995 set_path_visibility (fixture, "2:4", FALSE);
996 check_filter_model_with_root (fixture, path);
997 check_level_length (fixture->filter, NULL, 0);
999 set_path_visibility (fixture, "2", FALSE);
1000 check_filter_model_with_root (fixture, path);
1001 check_level_length (fixture->filter, NULL, 0);
1003 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1004 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1005 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1006 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1007 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
1008 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1009 set_path_visibility (fixture, "2:0", TRUE);
1010 set_path_visibility (fixture, "2:1", TRUE);
1011 set_path_visibility (fixture, "2:2", TRUE);
1012 check_filter_model_with_root (fixture, path);
1013 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1015 set_path_visibility (fixture, "2", TRUE);
1016 check_filter_model_with_root (fixture, path);
1017 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1021 filled_vroot_hide_child_levels (FilterTest *fixture,
1022 gconstpointer user_data)
1024 GtkTreePath *path = (GtkTreePath *)user_data;
1026 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1027 set_path_visibility (fixture, "2:0:2", 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 - 1);
1032 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1033 set_path_visibility (fixture, "2:0:4", FALSE);
1034 check_filter_model_with_root (fixture, path);
1035 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1036 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1038 set_path_visibility (fixture, "2:0:4:3", FALSE);
1039 check_filter_model_with_root (fixture, path);
1040 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1041 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1043 set_path_visibility (fixture, "2:0:4:0", FALSE);
1044 set_path_visibility (fixture, "2:0:4:1", FALSE);
1045 set_path_visibility (fixture, "2:0:4:2", FALSE);
1046 set_path_visibility (fixture, "2:0:4:4", FALSE);
1047 check_filter_model_with_root (fixture, path);
1048 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1049 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1051 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1052 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1053 /* FIXME: Actually, the filter model should not be emitted the
1054 * row-has-child-toggled signal here. *However* an extraneous emission
1055 * of this signal does not hurt and is allowed.
1057 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1058 set_path_visibility (fixture, "2:0:4", TRUE);
1059 check_filter_model_with_root (fixture, path);
1060 check_level_length (fixture->filter, "0:3", 0);
1062 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1063 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1064 set_path_visibility (fixture, "2:0:2", TRUE);
1065 check_filter_model_with_root (fixture, path);
1066 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1067 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1068 check_level_length (fixture->filter, "0:4", 0);
1070 /* FIXME: Inconsistency! For the non-vroot case we also receive two
1071 * row-has-child-toggled signals here.
1073 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
1074 /* Once 0:4:0 got inserted, 0:4 became a parent */
1075 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1076 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
1077 set_path_visibility (fixture, "2:0:4:2", TRUE);
1078 set_path_visibility (fixture, "2:0:4:4", TRUE);
1079 check_level_length (fixture->filter, "0:4", 2);
1084 empty_show_nodes (FilterTest *fixture,
1085 gconstpointer user_data)
1087 check_filter_model (fixture);
1088 check_level_length (fixture->filter, NULL, 0);
1090 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1091 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1092 set_path_visibility (fixture, "3", TRUE);
1093 check_filter_model (fixture);
1094 check_level_length (fixture->filter, NULL, 1);
1095 check_level_length (fixture->filter, "0", 0);
1097 set_path_visibility (fixture, "3:2:2", TRUE);
1098 check_filter_model (fixture);
1099 check_level_length (fixture->filter, NULL, 1);
1100 check_level_length (fixture->filter, "0", 0);
1102 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
1103 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1104 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
1105 set_path_visibility (fixture, "3:2", TRUE);
1106 check_filter_model (fixture);
1107 check_level_length (fixture->filter, NULL, 1);
1108 check_level_length (fixture->filter, "0", 1);
1109 check_level_length (fixture->filter, "0:0", 1);
1110 check_level_length (fixture->filter, "0:0:0", 0);
1112 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1113 set_path_visibility (fixture, "3", FALSE);
1114 check_filter_model (fixture);
1115 check_level_length (fixture->filter, NULL, 0);
1117 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1118 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1119 set_path_visibility (fixture, "3:2:1", TRUE);
1120 set_path_visibility (fixture, "3", TRUE);
1121 check_filter_model (fixture);
1122 check_level_length (fixture->filter, NULL, 1);
1123 check_level_length (fixture->filter, "0", 1);
1124 check_level_length (fixture->filter, "0:0", 2);
1125 check_level_length (fixture->filter, "0:0:0", 0);
1129 empty_vroot_show_nodes (FilterTest *fixture,
1130 gconstpointer user_data)
1132 GtkTreePath *path = (GtkTreePath *)user_data;
1134 check_filter_model_with_root (fixture, path);
1135 check_level_length (fixture->filter, NULL, 0);
1137 set_path_visibility (fixture, "2", TRUE);
1138 check_filter_model_with_root (fixture, path);
1139 check_level_length (fixture->filter, NULL, 0);
1141 set_path_visibility (fixture, "2:2:2", TRUE);
1142 check_filter_model_with_root (fixture, path);
1143 check_level_length (fixture->filter, NULL, 0);
1145 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1146 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
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", 1);
1151 check_level_length (fixture->filter, "0:0", 0);
1153 set_path_visibility (fixture, "3", TRUE);
1154 check_filter_model_with_root (fixture, path);
1155 check_level_length (fixture->filter, NULL, 1);
1157 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1158 set_path_visibility (fixture, "2:2", FALSE);
1159 check_filter_model_with_root (fixture, path);
1160 check_level_length (fixture->filter, NULL, 0);
1162 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1163 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1164 set_path_visibility (fixture, "2:2:1", TRUE);
1165 set_path_visibility (fixture, "2:2", TRUE);
1166 check_filter_model_with_root (fixture, path);
1167 check_level_length (fixture->filter, NULL, 1);
1168 check_level_length (fixture->filter, "0", 2);
1169 check_level_length (fixture->filter, "0:1", 0);
1174 unfiltered_hide_single (FilterTest *fixture,
1175 gconstpointer user_data)
1178 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1179 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1180 set_path_visibility (fixture, "2", FALSE);
1182 signal_monitor_assert_is_empty (fixture->monitor);
1183 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1185 /* The view only shows the root level, so the filter model only has
1186 * the first two levels cached.
1188 filter_test_append_refilter_signals (fixture, 2);
1189 filter_test_enable_filter (fixture);
1191 check_filter_model (fixture);
1192 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1196 unfiltered_hide_single_child (FilterTest *fixture,
1197 gconstpointer user_data)
1200 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1201 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1202 set_path_visibility (fixture, "2:2", FALSE);
1204 signal_monitor_assert_is_empty (fixture->monitor);
1205 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1206 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1208 /* The view only shows the root level, so the filter model only has
1209 * the first two levels cached.
1211 filter_test_append_refilter_signals (fixture, 2);
1212 filter_test_enable_filter (fixture);
1214 check_filter_model (fixture);
1215 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1216 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1220 unfiltered_hide_single_multi_level (FilterTest *fixture,
1221 gconstpointer user_data)
1224 /* This row is not shown, so its signal is not propagated */
1225 set_path_visibility (fixture, "2:2:2", FALSE);
1227 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1228 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1229 set_path_visibility (fixture, "2:2", FALSE);
1231 signal_monitor_assert_is_empty (fixture->monitor);
1232 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1233 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1234 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1236 /* The view only shows the root level, so the filter model only has
1237 * the first two levels cached.
1239 filter_test_append_refilter_signals (fixture, 2);
1240 filter_test_enable_filter (fixture);
1242 check_filter_model (fixture);
1243 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1244 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1246 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1247 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1248 set_path_visibility (fixture, "2:2", TRUE);
1250 check_filter_model (fixture);
1251 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1252 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1253 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1258 unfiltered_vroot_hide_single (FilterTest *fixture,
1259 gconstpointer user_data)
1262 GtkTreePath *path = (GtkTreePath *)user_data;
1264 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1265 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1266 set_path_visibility (fixture, "2:2", FALSE);
1268 signal_monitor_assert_is_empty (fixture->monitor);
1269 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1271 /* The view only shows the root level, so the filter model only has
1272 * the first two levels cached. (We add an additional level to
1273 * take the virtual root into account).
1275 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1276 filter_test_enable_filter (fixture);
1278 check_filter_model_with_root (fixture, path);
1279 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1283 unfiltered_vroot_hide_single_child (FilterTest *fixture,
1284 gconstpointer user_data)
1287 GtkTreePath *path = (GtkTreePath *)user_data;
1289 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1290 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1291 set_path_visibility (fixture, "2:2:2", FALSE);
1293 signal_monitor_assert_is_empty (fixture->monitor);
1294 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1295 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1297 /* The view only shows the root level, so the filter model only has
1298 * the first two levels cached. (We add an additional level to take
1299 * the virtual root into account).
1301 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1302 filter_test_enable_filter (fixture);
1304 check_filter_model_with_root (fixture, path);
1305 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1306 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1310 unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
1311 gconstpointer user_data)
1314 GtkTreePath *path = (GtkTreePath *)user_data;
1316 /* This row is not shown, so its signal is not propagated */
1317 set_path_visibility (fixture, "2:2:2:2", FALSE);
1319 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1320 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1321 set_path_visibility (fixture, "2:2:2", FALSE);
1323 signal_monitor_assert_is_empty (fixture->monitor);
1324 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1325 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1326 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1328 /* The view only shows the root level, so the filter model only has
1329 * the first two levels cached.
1331 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1332 filter_test_enable_filter (fixture);
1334 check_filter_model_with_root (fixture, path);
1335 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1336 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1338 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1339 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1340 set_path_visibility (fixture, "2:2:2", TRUE);
1342 check_filter_model_with_root (fixture, path);
1343 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1344 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1345 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1351 unfiltered_show_single (FilterTest *fixture,
1352 gconstpointer user_data)
1355 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1356 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1357 set_path_visibility (fixture, "2", TRUE);
1359 signal_monitor_assert_is_empty (fixture->monitor);
1360 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1362 /* The view only shows the root level, so the filter model only has
1363 * the first two levels cached.
1365 filter_test_append_refilter_signals (fixture, 2);
1366 filter_test_enable_filter (fixture);
1368 check_filter_model (fixture);
1369 check_level_length (fixture->filter, NULL, 1);
1373 unfiltered_show_single_child (FilterTest *fixture,
1374 gconstpointer user_data)
1377 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1378 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1379 set_path_visibility (fixture, "2:2", TRUE);
1381 signal_monitor_assert_is_empty (fixture->monitor);
1382 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1383 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1385 /* The view only shows the root level, so the filter model only has
1386 * the first two levels cached.
1388 filter_test_append_refilter_signals (fixture, 3);
1389 filter_test_enable_filter (fixture);
1391 check_filter_model (fixture);
1392 check_level_length (fixture->filter, NULL, 0);
1394 /* From here we are filtered, "2" in the real model is "0" in the filter
1397 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1398 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1399 set_path_visibility (fixture, "2", TRUE);
1400 signal_monitor_assert_is_empty (fixture->monitor);
1401 check_level_length (fixture->filter, NULL, 1);
1402 check_level_length (fixture->filter, "0", 1);
1406 unfiltered_show_single_multi_level (FilterTest *fixture,
1407 gconstpointer user_data)
1410 /* The view is not showing this row (collapsed state), so it is not
1411 * referenced. The signal should not go through.
1413 set_path_visibility (fixture, "2:2:2", TRUE);
1415 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1416 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1417 set_path_visibility (fixture, "2:2", TRUE);
1419 signal_monitor_assert_is_empty (fixture->monitor);
1420 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1421 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1422 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1424 /* The view only shows the root level, so the filter model only has
1425 * the first two levels cached.
1427 filter_test_append_refilter_signals (fixture, 3);
1428 filter_test_enable_filter (fixture);
1430 check_filter_model (fixture);
1431 check_level_length (fixture->filter, NULL, 0);
1433 /* From here we are filtered, "2" in the real model is "0" in the filter
1436 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1437 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1438 set_path_visibility (fixture, "2", TRUE);
1439 check_filter_model (fixture);
1440 check_level_length (fixture->filter, NULL, 1);
1441 check_level_length (fixture->filter, "0", 1);
1442 check_level_length (fixture->filter, "0:0", 1);
1447 unfiltered_vroot_show_single (FilterTest *fixture,
1448 gconstpointer user_data)
1451 GtkTreePath *path = (GtkTreePath *)user_data;
1453 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1454 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1455 set_path_visibility (fixture, "2:2", TRUE);
1457 signal_monitor_assert_is_empty (fixture->monitor);
1458 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1460 /* The view only shows the root level, so the filter model only has
1461 * the first two levels cached.
1463 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1464 filter_test_enable_filter (fixture);
1466 check_filter_model_with_root (fixture, path);
1467 check_level_length (fixture->filter, NULL, 1);
1471 unfiltered_vroot_show_single_child (FilterTest *fixture,
1472 gconstpointer user_data)
1475 GtkTreePath *path = (GtkTreePath *)user_data;
1477 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1478 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1479 set_path_visibility (fixture, "2:2:2", TRUE);
1481 signal_monitor_assert_is_empty (fixture->monitor);
1482 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1483 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1485 /* The view only shows the root level, so the filter model only has
1486 * the first two levels cached.
1488 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1489 filter_test_enable_filter (fixture);
1491 check_filter_model_with_root (fixture, path);
1492 check_level_length (fixture->filter, NULL, 0);
1494 /* From here we are filtered, "2" in the real model is "0" in the filter
1497 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1498 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1499 set_path_visibility (fixture, "2:2", TRUE);
1500 signal_monitor_assert_is_empty (fixture->monitor);
1501 check_level_length (fixture->filter, NULL, 1);
1502 check_level_length (fixture->filter, "0", 1);
1506 unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
1507 gconstpointer user_data)
1510 GtkTreePath *path = (GtkTreePath *)user_data;
1512 /* The view is not showing this row (collapsed state), so it is not
1513 * referenced. The signal should not go through.
1515 set_path_visibility (fixture, "2:2:2:2", TRUE);
1517 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1518 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1519 set_path_visibility (fixture, "2:2:2", TRUE);
1521 signal_monitor_assert_is_empty (fixture->monitor);
1522 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1523 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1524 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1526 /* The view only shows the root level, so the filter model only has
1527 * the first two levels cached.
1529 filter_test_append_refilter_signals_with_vroot (fixture, 4, path);
1530 filter_test_enable_filter (fixture);
1532 check_filter_model_with_root (fixture, path);
1533 check_level_length (fixture->filter, NULL, 0);
1535 /* From here we are filtered, "2" in the real model is "0" in the filter
1538 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1539 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1540 set_path_visibility (fixture, "2:2", TRUE);
1541 check_filter_model_with_root (fixture, path);
1542 check_level_length (fixture->filter, NULL, 1);
1543 check_level_length (fixture->filter, "0", 1);
1544 check_level_length (fixture->filter, "0:0", 1);
1549 specific_path_dependent_filter_func (GtkTreeModel *model,
1555 path = gtk_tree_model_get_path (model, iter);
1556 if (gtk_tree_path_get_indices (path)[0] < 4)
1563 specific_path_dependent_filter (void)
1569 GtkTreeModel *filter;
1571 list = gtk_list_store_new (1, G_TYPE_INT);
1572 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
1573 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
1574 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
1575 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
1576 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
1577 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
1578 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
1579 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
1581 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
1582 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
1583 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1584 specific_path_dependent_filter_func,
1587 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
1588 GTK_SORT_DESCENDING);
1590 for (i = 0; i < 4; i++)
1592 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1594 gtk_list_store_remove (list, &iter);
1596 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1598 gtk_list_store_remove (list, &iter);
1604 specific_append_after_collapse_visible_func (GtkTreeModel *model,
1609 gboolean hide_negative_numbers;
1611 gtk_tree_model_get (model, iter, 1, &number, -1);
1612 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
1614 return (number >= 0 || !hide_negative_numbers);
1618 specific_append_after_collapse (void)
1620 /* This test is based on one of the test cases I found in my
1621 * old test cases directory. I unfortunately do not have a record
1622 * from who this test case originated. -Kris.
1626 * - Show tree, expand, collapse.
1631 GtkTreeIter child_iter;
1632 GtkTreeIter child_iter2;
1633 GtkTreePath *append_path;
1634 GtkTreeStore *store;
1635 GtkTreeModel *filter;
1639 GtkWidget *tree_view;
1641 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
1643 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
1644 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
1645 GINT_TO_POINTER (FALSE));
1646 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1647 specific_append_after_collapse_visible_func,
1650 sort = gtk_tree_model_sort_new_with_model (filter);
1652 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1653 tree_view = gtk_tree_view_new_with_model (sort);
1654 gtk_container_add (GTK_CONTAINER (window), tree_view);
1655 gtk_widget_realize (tree_view);
1657 while (gtk_events_pending ())
1658 gtk_main_iteration ();
1660 gtk_tree_store_prepend (store, &iter, NULL);
1661 gtk_tree_store_set (store, &iter,
1662 0, "hallo", 1, 1, -1);
1664 gtk_tree_store_append (store, &child_iter, &iter);
1665 gtk_tree_store_set (store, &child_iter,
1666 0, "toemaar", 1, 1, -1);
1668 gtk_tree_store_append (store, &child_iter2, &child_iter);
1669 gtk_tree_store_set (store, &child_iter2,
1670 0, "very deep", 1, 1, -1);
1672 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
1674 gtk_tree_store_append (store, &child_iter, &iter);
1675 gtk_tree_store_set (store, &child_iter,
1676 0, "sja", 1, 1, -1);
1678 gtk_tree_store_append (store, &child_iter, &iter);
1679 gtk_tree_store_set (store, &child_iter,
1680 0, "some word", 1, -1, -1);
1682 /* Expand and collapse the tree */
1683 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
1684 while (gtk_events_pending ())
1685 gtk_main_iteration ();
1687 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
1688 while (gtk_events_pending ())
1689 gtk_main_iteration ();
1691 /* Add another it */
1692 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
1693 GINT_TO_POINTER (TRUE));
1695 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
1697 gtk_tree_store_append (store, &child_iter, &iter);
1698 gtk_tree_store_set (store, &child_iter,
1699 0, "new new new !!", 1, 1, -1);
1701 gtk_tree_path_free (append_path);
1704 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
1705 while (gtk_events_pending ())
1706 gtk_main_iteration ();
1711 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
1720 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
1726 /* Do reference the model */
1727 gtk_tree_model_get (model, iter, 0, &item, -1);
1734 specific_sort_filter_remove_node (void)
1736 /* This test is based on one of the test cases I found in my
1737 * old test cases directory. I unfortunately do not have a record
1738 * from who this test case originated. -Kris.
1741 * - Create tree store, sort, filter models. The sort model has
1742 * a default sort func that is enabled, filter model a visible func
1743 * that defaults to returning FALSE.
1744 * - Remove a node from the tree store.
1748 GtkTreeStore *store;
1749 GtkTreeModel *filter;
1753 GtkWidget *tree_view;
1755 store = gtk_tree_store_new (1, G_TYPE_STRING);
1756 gtk_tree_store_append (store, &iter, NULL);
1757 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
1759 gtk_tree_store_append (store, &iter, NULL);
1760 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
1762 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
1763 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
1764 specific_sort_filter_remove_node_compare_func, NULL, NULL);
1766 filter = gtk_tree_model_filter_new (sort, NULL);
1767 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1768 specific_sort_filter_remove_node_visible_func,
1772 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1773 tree_view = gtk_tree_view_new_with_model (filter);
1774 gtk_container_add (GTK_CONTAINER (window), tree_view);
1775 gtk_widget_realize (tree_view);
1777 while (gtk_events_pending ())
1778 gtk_main_iteration ();
1781 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
1782 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
1783 gtk_tree_store_remove (store, &iter);
1785 while (gtk_events_pending ())
1786 gtk_main_iteration ();
1791 specific_sort_filter_remove_root (void)
1793 /* This test is based on one of the test cases I found in my
1794 * old test cases directory. I unfortunately do not have a record
1795 * from who this test case originated. -Kris.
1798 GtkTreeModel *model, *sort, *filter;
1799 GtkTreeIter root, mid, leaf;
1802 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
1803 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
1804 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
1805 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
1807 path = gtk_tree_model_get_path (model, &mid);
1809 sort = gtk_tree_model_sort_new_with_model (model);
1810 filter = gtk_tree_model_filter_new (sort, path);
1812 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
1814 g_object_unref (filter);
1815 g_object_unref (sort);
1816 g_object_unref (model);
1821 specific_root_mixed_visibility (void)
1824 GtkTreeModel *filter;
1825 /* A bit nasty, apologies */
1828 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1830 for (i = 0; i < LEVEL_LENGTH; i++)
1834 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
1836 create_tree_store_set_values (fixture.store, &iter, TRUE);
1838 create_tree_store_set_values (fixture.store, &iter, FALSE);
1841 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1842 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1843 fixture.monitor = NULL;
1845 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
1847 /* In order to trigger the potential bug, we should not access
1848 * the filter model here (so don't call the check functions).
1851 /* Change visibility of an odd row to TRUE */
1852 set_path_visibility (&fixture, "3", TRUE);
1853 check_filter_model (&fixture);
1854 check_level_length (fixture.filter, NULL, 4);
1860 specific_has_child_filter_filter_func (GtkTreeModel *model,
1864 return gtk_tree_model_iter_has_child (model, iter);
1868 specific_has_child_filter (void)
1870 GtkTreeModel *filter;
1871 GtkTreeIter iter, root;
1872 /* A bit nasty, apologies */
1875 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1876 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1877 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1878 fixture.monitor = NULL;
1880 /* We will filter on parent state using a filter function. We will
1881 * manually keep the boolean column in sync, so that we can use
1882 * check_filter_model() to check the consistency of the model.
1884 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
1885 * to be able to check the structure here. We keep the calls to
1886 * check_filter_model() commented out until then.
1888 gtk_tree_model_filter_set_visible_func (fixture.filter,
1889 specific_has_child_filter_filter_func,
1892 gtk_tree_store_append (fixture.store, &root, NULL);
1893 create_tree_store_set_values (fixture.store, &root, FALSE);
1895 /* check_filter_model (&fixture); */
1896 check_level_length (fixture.filter, NULL, 0);
1898 gtk_tree_store_append (fixture.store, &iter, &root);
1899 create_tree_store_set_values (fixture.store, &iter, TRUE);
1901 /* Parent must now be visible. Do the level length check first,
1902 * to avoid modifying the child model triggering a row-changed to
1905 check_level_length (fixture.filter, NULL, 1);
1906 check_level_length (fixture.filter, "0", 0);
1908 set_path_visibility (&fixture, "0", TRUE);
1909 /* check_filter_model (&fixture); */
1911 gtk_tree_store_append (fixture.store, &root, NULL);
1912 check_level_length (fixture.filter, NULL, 1);
1914 gtk_tree_store_append (fixture.store, &iter, &root);
1915 check_level_length (fixture.filter, NULL, 2);
1916 check_level_length (fixture.filter, "1", 0);
1918 create_tree_store_set_values (fixture.store, &root, TRUE);
1919 create_tree_store_set_values (fixture.store, &iter, TRUE);
1921 /* check_filter_model (&fixture); */
1923 gtk_tree_store_append (fixture.store, &iter, &root);
1924 create_tree_store_set_values (fixture.store, &iter, TRUE);
1925 check_level_length (fixture.filter, NULL, 2);
1926 check_level_length (fixture.filter, "0", 0);
1927 check_level_length (fixture.filter, "1", 0);
1929 /* Now remove one of the remaining child rows */
1930 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
1932 gtk_tree_store_remove (fixture.store, &iter);
1934 check_level_length (fixture.filter, NULL, 1);
1935 check_level_length (fixture.filter, "0", 0);
1937 set_path_visibility (&fixture, "0", FALSE);
1938 /* check_filter_model (&fixture); */
1943 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
1950 path = gtk_tree_model_get_path (model, iter);
1951 depth = gtk_tree_path_get_depth (path);
1952 gtk_tree_path_free (path);
1957 return gtk_tree_model_iter_has_child (model, iter);
1961 specific_root_has_child_filter (void)
1963 GtkTreeModel *filter;
1964 GtkTreeIter iter, root;
1965 /* A bit nasty, apologies */
1968 /* This is a variation on the above test case wherein the has-child
1969 * check for visibility only applies to root level nodes.
1972 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1973 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
1974 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
1975 fixture.monitor = NULL;
1977 /* We will filter on parent state using a filter function. We will
1978 * manually keep the boolean column in sync, so that we can use
1979 * check_filter_model() to check the consistency of the model.
1981 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
1982 * to be able to check the structure here. We keep the calls to
1983 * check_filter_model() commented out until then.
1985 gtk_tree_model_filter_set_visible_func (fixture.filter,
1986 specific_root_has_child_filter_filter_func,
1989 gtk_tree_store_append (fixture.store, &root, NULL);
1990 create_tree_store_set_values (fixture.store, &root, FALSE);
1992 /* check_filter_model (&fixture); */
1993 check_level_length (fixture.filter, NULL, 0);
1995 gtk_tree_store_append (fixture.store, &iter, &root);
1996 create_tree_store_set_values (fixture.store, &iter, TRUE);
1998 /* Parent must now be visible. Do the level length check first,
1999 * to avoid modifying the child model triggering a row-changed to
2002 check_level_length (fixture.filter, NULL, 1);
2003 check_level_length (fixture.filter, "0", 1);
2005 set_path_visibility (&fixture, "0", TRUE);
2006 /* check_filter_model (&fixture); */
2008 gtk_tree_store_append (fixture.store, &root, NULL);
2009 check_level_length (fixture.filter, NULL, 1);
2011 gtk_tree_store_append (fixture.store, &iter, &root);
2012 check_level_length (fixture.filter, NULL, 2);
2013 check_level_length (fixture.filter, "1", 1);
2015 create_tree_store_set_values (fixture.store, &root, TRUE);
2016 create_tree_store_set_values (fixture.store, &iter, TRUE);
2018 /* check_filter_model (&fixture); */
2020 gtk_tree_store_append (fixture.store, &iter, &root);
2021 create_tree_store_set_values (fixture.store, &iter, TRUE);
2022 check_level_length (fixture.filter, NULL, 2);
2023 check_level_length (fixture.filter, "0", 1);
2024 check_level_length (fixture.filter, "1", 2);
2026 /* Now remove one of the remaining child rows */
2027 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
2029 gtk_tree_store_remove (fixture.store, &iter);
2031 check_level_length (fixture.filter, NULL, 1);
2032 check_level_length (fixture.filter, "0", 2);
2034 set_path_visibility (&fixture, "0", FALSE);
2035 /* check_filter_model (&fixture); */
2040 specific_filter_add_child (void)
2042 /* This test is based on one of the test cases I found in my
2043 * old test cases directory. I unfortunately do not have a record
2044 * from who this test case originated. -Kris.
2048 GtkTreeIter iter_first;
2050 GtkTreeStore *store;
2051 GtkTreeModel *filter;
2053 store = gtk_tree_store_new (1, G_TYPE_STRING);
2055 gtk_tree_store_append (store, &iter_first, NULL);
2056 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
2058 gtk_tree_store_append (store, &iter, NULL);
2059 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2061 gtk_tree_store_append (store, &iter, NULL);
2062 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2064 gtk_tree_store_append (store, &iter, NULL);
2065 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2067 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2069 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2070 gtk_tree_store_append (store, &child, &iter_first);
2071 gtk_tree_store_set (store, &child, 0, "Hello", -1);
2075 specific_list_store_clear (void)
2080 GtkTreeModel *filter;
2083 list = gtk_list_store_new (1, G_TYPE_INT);
2084 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
2085 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
2086 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
2087 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
2088 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
2089 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
2090 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
2091 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
2093 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
2094 view = gtk_tree_view_new_with_model (filter);
2096 gtk_list_store_clear (list);
2100 specific_bug_300089 (void)
2102 /* Test case for GNOME Bugzilla bug 300089. Written by
2105 GtkTreeModel *sort_model, *child_model;
2107 GtkTreeIter iter, iter2, sort_iter;
2109 child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
2111 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2112 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
2113 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2114 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "B", -1);
2116 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
2117 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "D", -1);
2118 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
2119 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "E", -1);
2121 gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
2122 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "C", -1);
2125 sort_model = GTK_TREE_MODEL (gtk_tree_model_sort_new_with_model (child_model));
2126 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
2127 0, GTK_SORT_ASCENDING);
2129 path = gtk_tree_path_new_from_indices (1, 1, -1);
2131 /* make sure a level is constructed */
2132 gtk_tree_model_get_iter (sort_model, &sort_iter, path);
2134 /* change the "E" row in a way that causes it to change position */
2135 gtk_tree_model_get_iter (child_model, &iter, path);
2136 gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
2141 specific_bug_301558_sort_func (GtkTreeModel *model,
2148 gtk_tree_model_get (model, a, 0, &i, -1);
2149 gtk_tree_model_get (model, b, 0, &j, -1);
2155 specific_bug_301558 (void)
2157 /* Test case for GNOME Bugzilla bug 301558 provided by
2161 GtkTreeModel *filter;
2163 GtkTreeIter root, iter, iter2;
2168 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
2169 gtk_tree_store_append (tree, &iter, NULL);
2170 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
2171 gtk_tree_store_append (tree, &iter2, &iter);
2172 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
2174 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
2175 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
2176 specific_bug_301558_sort_func,
2179 filter = gtk_tree_model_filter_new (sort, NULL);
2180 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
2182 view = gtk_tree_view_new_with_model (filter);
2184 while (gtk_events_pending ())
2185 gtk_main_iteration ();
2189 for (i = 0; i < 10; i++)
2191 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
2192 g_assert_not_reached ();
2196 gtk_tree_store_append (tree, &iter, &root);
2197 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
2202 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
2203 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
2205 gtk_tree_store_remove (tree, &iter);
2214 specific_bug_311955_filter_func (GtkTreeModel *model,
2220 gtk_tree_model_get (model, iter, 0, &value, -1);
2222 return (value != 0);
2226 specific_bug_311955 (void)
2228 /* This is a test case for GNOME Bugzilla bug 311955. It was written
2231 GtkTreeIter iter, child, root;
2232 GtkTreeStore *store;
2234 GtkTreeModel *filter;
2237 GtkWidget *tree_view;
2241 store = gtk_tree_store_new (1, G_TYPE_INT);
2243 gtk_tree_store_append (store, &root, NULL);
2244 gtk_tree_store_set (store, &root, 0, 33, -1);
2246 gtk_tree_store_append (store, &iter, &root);
2247 gtk_tree_store_set (store, &iter, 0, 50, -1);
2249 gtk_tree_store_append (store, &iter, NULL);
2250 gtk_tree_store_set (store, &iter, 0, 22, -1);
2252 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2253 filter = gtk_tree_model_filter_new (sort, NULL);
2255 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2256 specific_bug_311955_filter_func,
2259 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2260 tree_view = gtk_tree_view_new_with_model (filter);
2261 g_object_unref (store);
2263 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2265 while (gtk_events_pending ())
2266 gtk_main_iteration ();
2269 for (i = 0; i < 4; i++)
2271 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2273 gtk_tree_store_append (store, &iter, &root);
2276 gtk_tree_store_set (store, &iter, 0, i, -1);
2280 gtk_tree_store_append (store, &child, &iter);
2281 gtk_tree_store_set (store, &child, 0, 10, -1);
2285 while (gtk_events_pending ())
2286 gtk_main_iteration ();
2288 /* Remove bottommost child from the tree. */
2289 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2290 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
2292 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
2294 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
2295 gtk_tree_store_remove (store, &child);
2298 g_assert_not_reached ();
2302 specific_bug_346800 (void)
2304 /* This is a test case for GNOME Bugzilla bug 346800. It was written
2305 * by Jonathan Matthew.
2308 GtkTreeIter node_iters[50];
2309 GtkTreeIter child_iters[50];
2310 GtkTreeModel *model;
2311 GtkTreeModelFilter *filter;
2312 GtkTreeStore *store;
2316 columns = g_new (GType, 2);
2317 columns[0] = G_TYPE_STRING;
2318 columns[1] = G_TYPE_BOOLEAN;
2319 store = gtk_tree_store_newv (2, columns);
2320 model = GTK_TREE_MODEL (store);
2322 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
2323 gtk_tree_model_filter_set_visible_column (filter, 1);
2325 for (i=0; i<items; i++)
2327 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
2330 gtk_tree_store_append (store, &node_iters[i], NULL);
2331 gtk_tree_store_set (store, &node_iters[i],
2333 1, ((i%6) == 0) ? FALSE : TRUE,
2337 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
2338 gtk_tree_store_set (store, &child_iters[i],
2339 0, "something else",
2342 gtk_tree_model_filter_refilter (filter);
2346 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
2347 (i & 1) ? TRUE : FALSE, -1);
2348 gtk_tree_model_filter_refilter (filter);
2350 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
2351 (i & 1) ? FALSE: TRUE, -1);
2352 gtk_tree_model_filter_refilter (filter);
2359 specific_bug_364946 (void)
2361 /* This is a test case for GNOME Bugzilla bug 364946. It was written
2362 * by Andreas Koehler.
2364 GtkTreeStore *store;
2365 GtkTreeIter a, aa, aaa, aab, iter;
2366 GtkTreeModel *s_model;
2368 store = gtk_tree_store_new (1, G_TYPE_STRING);
2370 gtk_tree_store_append (store, &a, NULL);
2371 gtk_tree_store_set (store, &a, 0, "0", -1);
2373 gtk_tree_store_append (store, &aa, &a);
2374 gtk_tree_store_set (store, &aa, 0, "0:0", -1);
2376 gtk_tree_store_append (store, &aaa, &aa);
2377 gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
2379 gtk_tree_store_append (store, &aab, &aa);
2380 gtk_tree_store_set (store, &aab, 0, "0:0:1", -1);
2382 s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2383 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model), 0,
2384 GTK_SORT_ASCENDING);
2386 gtk_tree_model_get_iter_from_string (s_model, &iter, "0:0:0");
2388 gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
2389 gtk_tree_store_remove (store, &aaa);
2390 gtk_tree_store_remove (store, &aab);
2392 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model));
2397 specific_bug_464173_visible_func (GtkTreeModel *model,
2401 gboolean *visible = (gboolean *)data;
2407 specific_bug_464173 (void)
2409 /* Test case for GNOME Bugzilla bug 464173, test case written
2410 * by Andreas Koehler.
2412 GtkTreeStore *model;
2413 GtkTreeModelFilter *f_model;
2414 GtkTreeIter iter1, iter2;
2416 gboolean visible = TRUE;
2418 model = gtk_tree_store_new (1, G_TYPE_STRING);
2419 gtk_tree_store_append (model, &iter1, NULL);
2420 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
2421 gtk_tree_store_append (model, &iter2, &iter1);
2422 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
2424 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
2425 gtk_tree_model_filter_set_visible_func (f_model,
2426 specific_bug_464173_visible_func,
2429 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
2432 gtk_tree_model_filter_refilter (f_model);
2437 specific_bug_540201_filter_func (GtkTreeModel *model,
2441 gboolean has_children;
2443 has_children = gtk_tree_model_iter_has_child (model, iter);
2445 return has_children;
2449 specific_bug_540201 (void)
2451 /* Test case for GNOME Bugzilla bug 540201, steps provided by
2454 GtkTreeIter iter, root;
2455 GtkTreeStore *store;
2456 GtkTreeModel *filter;
2458 GtkWidget *tree_view;
2460 store = gtk_tree_store_new (1, G_TYPE_INT);
2462 gtk_tree_store_append (store, &root, NULL);
2463 gtk_tree_store_set (store, &root, 0, 33, -1);
2465 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2466 tree_view = gtk_tree_view_new_with_model (filter);
2468 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2469 specific_bug_540201_filter_func,
2472 gtk_tree_store_append (store, &iter, &root);
2473 gtk_tree_store_set (store, &iter, 0, 50, -1);
2475 gtk_tree_store_append (store, &iter, &root);
2476 gtk_tree_store_set (store, &iter, 0, 22, -1);
2479 gtk_tree_store_append (store, &root, NULL);
2480 gtk_tree_store_set (store, &root, 0, 33, -1);
2482 gtk_tree_store_append (store, &iter, &root);
2483 gtk_tree_store_set (store, &iter, 0, 22, -1);
2488 specific_bug_549287_visible_func (GtkTreeModel *model,
2492 gboolean result = FALSE;
2494 result = gtk_tree_model_iter_has_child (model, iter);
2500 specific_bug_549287 (void)
2502 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
2505 GtkTreeStore *store;
2506 GtkTreeModel *filtered;
2509 GtkTreeIter *swap, *parent, *child;
2511 store = gtk_tree_store_new (1, G_TYPE_STRING);
2512 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2513 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
2514 specific_bug_549287_visible_func,
2517 view = gtk_tree_view_new_with_model (filtered);
2519 for (i = 0; i < 4; i++)
2521 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
2523 parent = gtk_tree_iter_copy (&iter);
2524 child = gtk_tree_iter_copy (&iter);
2526 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
2535 gtk_tree_store_append (store, child, parent);
2536 gtk_tree_store_set (store, child,
2540 gtk_tree_iter_free (parent);
2541 gtk_tree_iter_free (child);
2545 gtk_tree_store_append (store, &iter, NULL);
2546 gtk_tree_store_set (store, &iter,
2551 /* since we inserted something, we changed the visibility conditions: */
2552 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
2562 gtk_test_init (&argc, &argv, NULL);
2564 g_test_add ("/FilterModel/self/verify-test-suite",
2568 filter_test_teardown);
2570 g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-1",
2571 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2573 verify_test_suite_vroot,
2574 filter_test_teardown);
2575 g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-2",
2576 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
2578 verify_test_suite_vroot,
2579 filter_test_teardown);
2582 g_test_add ("/FilterModel/filled/hide-root-level",
2585 filled_hide_root_level,
2586 filter_test_teardown);
2587 g_test_add ("/FilterModel/filled/hide-child-levels",
2590 filled_hide_child_levels,
2591 filter_test_teardown);
2593 g_test_add ("/FilterModel/filled/hide-root-level/vroot",
2594 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2596 filled_vroot_hide_root_level,
2597 filter_test_teardown);
2598 g_test_add ("/FilterModel/filled/hide-child-levels/vroot",
2599 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2601 filled_vroot_hide_child_levels,
2602 filter_test_teardown);
2605 g_test_add ("/FilterModel/empty/show-nodes",
2607 filter_test_setup_empty,
2609 filter_test_teardown);
2611 g_test_add ("/FilterModel/empty/show-nodes/vroot",
2612 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2613 filter_test_setup_empty,
2614 empty_vroot_show_nodes,
2615 filter_test_teardown);
2618 g_test_add ("/FilterModel/unfiltered/hide-single",
2620 filter_test_setup_unfiltered,
2621 unfiltered_hide_single,
2622 filter_test_teardown);
2623 g_test_add ("/FilterModel/unfiltered/hide-single-child",
2625 filter_test_setup_unfiltered,
2626 unfiltered_hide_single_child,
2627 filter_test_teardown);
2628 g_test_add ("/FilterModel/unfiltered/hide-single-multi-level",
2630 filter_test_setup_unfiltered,
2631 unfiltered_hide_single_multi_level,
2632 filter_test_teardown);
2634 g_test_add ("/FilterModel/unfiltered/hide-single/vroot",
2635 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2636 filter_test_setup_unfiltered,
2637 unfiltered_vroot_hide_single,
2638 filter_test_teardown);
2639 g_test_add ("/FilterModel/unfiltered/hide-single-child/vroot",
2640 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2641 filter_test_setup_unfiltered,
2642 unfiltered_vroot_hide_single_child,
2643 filter_test_teardown);
2644 g_test_add ("/FilterModel/unfiltered/hide-single-multi-level/vroot",
2645 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2646 filter_test_setup_unfiltered,
2647 unfiltered_vroot_hide_single_multi_level,
2648 filter_test_teardown);
2652 g_test_add ("/FilterModel/unfiltered/show-single",
2654 filter_test_setup_empty_unfiltered,
2655 unfiltered_show_single,
2656 filter_test_teardown);
2657 g_test_add ("/FilterModel/unfiltered/show-single-child",
2659 filter_test_setup_empty_unfiltered,
2660 unfiltered_show_single_child,
2661 filter_test_teardown);
2662 g_test_add ("/FilterModel/unfiltered/show-single-multi-level",
2664 filter_test_setup_empty_unfiltered,
2665 unfiltered_show_single_multi_level,
2666 filter_test_teardown);
2668 g_test_add ("/FilterModel/unfiltered/show-single/vroot",
2669 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2670 filter_test_setup_empty_unfiltered,
2671 unfiltered_vroot_show_single,
2672 filter_test_teardown);
2673 g_test_add ("/FilterModel/unfiltered/show-single-child/vroot",
2674 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2675 filter_test_setup_empty_unfiltered,
2676 unfiltered_vroot_show_single_child,
2677 filter_test_teardown);
2678 g_test_add ("/FilterModel/unfiltered/show-single-multi-level/vroot",
2679 FilterTest, gtk_tree_path_new_from_indices (2, -1),
2680 filter_test_setup_empty_unfiltered,
2681 unfiltered_vroot_show_single_multi_level,
2682 filter_test_teardown);
2685 g_test_add_func ("/FilterModel/specific/path-dependent-filter",
2686 specific_path_dependent_filter);
2687 g_test_add_func ("/FilterModel/specific/append-after-collapse",
2688 specific_append_after_collapse);
2689 g_test_add_func ("/FilterModel/specific/sort-filter-remove-node",
2690 specific_sort_filter_remove_node);
2691 g_test_add_func ("/FilterModel/specific/sort-filter-remove-root",
2692 specific_sort_filter_remove_root);
2693 g_test_add_func ("/FilterModel/specific/root-mixed-visibility",
2694 specific_root_mixed_visibility);
2695 g_test_add_func ("/FilterModel/specific/has-child-filter",
2696 specific_has_child_filter);
2697 g_test_add_func ("/FilterModel/specific/root-has-child-filter",
2698 specific_root_has_child_filter);
2699 g_test_add_func ("/FilterModel/specific/filter-add-child",
2700 specific_filter_add_child);
2701 g_test_add_func ("/FilterModel/specific/list-store-clear",
2702 specific_list_store_clear);
2704 g_test_add_func ("/FilterModel/specific/bug-300089",
2705 specific_bug_300089);
2706 g_test_add_func ("/FilterModel/specific/bug-301558",
2707 specific_bug_301558);
2708 g_test_add_func ("/FilterModel/specific/bug-311955",
2709 specific_bug_311955);
2710 g_test_add_func ("/FilterModel/specific/bug-346800",
2711 specific_bug_346800);
2712 g_test_add_func ("/FilterModel/specific/bug-364946",
2713 specific_bug_364946);
2714 g_test_add_func ("/FilterModel/specific/bug-464173",
2715 specific_bug_464173);
2716 g_test_add_func ("/FilterModel/specific/bug-540201",
2717 specific_bug_540201);
2718 g_test_add_func ("/FilterModel/specific/bug-549287",
2719 specific_bug_549287);
2721 return g_test_run ();