1 /* Extensive GtkTreeModelFilter tests.
2 * Copyright (C) 2009 Kristian Rietveld <kris@gtk.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
24 * - Proper coverage checking to see if the unit tests cover
26 * - Verify if the ref counting is done properly for both the
27 * normal ref_count and the zero_ref_count. One way to test
28 * this area is by collapsing/expanding branches on the view
29 * that is connected to the filter model.
30 * - Check if the iterator stamp is incremented at the correct times.
38 #define LEVEL_LENGTH 5
41 create_tree_store_set_values (GtkTreeStore *store,
48 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
49 path_string = gtk_tree_path_to_string (path);
51 gtk_tree_store_set (store, iter,
56 gtk_tree_path_free (path);
61 create_tree_store_recurse (int depth,
68 for (i = 0; i < LEVEL_LENGTH; i++)
72 gtk_tree_store_insert (store, &iter, parent, i);
73 create_tree_store_set_values (store, &iter, visible);
76 create_tree_store_recurse (depth - 1, store, &iter, visible);
81 create_tree_store (int depth,
86 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
88 create_tree_store_recurse (depth, store, NULL, visible);
102 ROW_HAS_CHILD_TOGGLED,
109 signal_name_to_string (SignalName signal)
114 return "row-inserted";
117 return "row-deleted";
120 return "row-changed";
122 case ROW_HAS_CHILD_TOGGLED:
123 return "row-has-child-toggled";
126 return "rows-reordered";
145 signal_new (SignalName signal, GtkTreePath *path)
149 s = g_new0 (Signal, 1);
151 s->path = gtk_tree_path_copy (path);
157 signal_free (Signal *s)
160 gtk_tree_path_free (s->path);
169 GtkTreeModel *client;
170 gulong signal_ids[LAST_SIGNAL];
176 signal_monitor_generic_handler (SignalMonitor *m,
183 if (g_queue_is_empty (m->queue))
185 g_error ("Signal queue empty\n");
186 g_assert_not_reached ();
189 if (m->client != model)
191 g_error ("Model mismatch; expected %p, got %p\n",
193 g_assert_not_reached ();
196 s = g_queue_peek_tail (m->queue);
199 /* For debugging: output signals that are coming in. Leaks memory. */
200 g_print ("signal=%d path=%s\n", signal, gtk_tree_path_to_string (path));
203 if (s->signal != signal
204 || gtk_tree_path_compare (s->path, path) != 0)
206 gchar *path_str, *s_path_str;
208 s_path_str = gtk_tree_path_to_string (s->path);
209 path_str = gtk_tree_path_to_string (path);
211 g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n",
212 signal_name_to_string (s->signal), s_path_str,
213 signal_name_to_string (signal), path_str);
218 g_assert_not_reached ();
221 s = g_queue_pop_tail (m->queue);
227 signal_monitor_row_inserted (GtkTreeModel *model,
232 signal_monitor_generic_handler (data, ROW_INSERTED,
237 signal_monitor_row_deleted (GtkTreeModel *model,
241 signal_monitor_generic_handler (data, ROW_DELETED,
246 signal_monitor_row_changed (GtkTreeModel *model,
251 signal_monitor_generic_handler (data, ROW_CHANGED,
256 signal_monitor_row_has_child_toggled (GtkTreeModel *model,
261 signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
266 signal_monitor_rows_reordered (GtkTreeModel *model,
272 signal_monitor_generic_handler (data, ROWS_REORDERED,
276 static SignalMonitor *
277 signal_monitor_new (GtkTreeModel *client)
281 m = g_new0 (SignalMonitor, 1);
282 m->client = g_object_ref (client);
283 m->queue = g_queue_new ();
285 m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
287 G_CALLBACK (signal_monitor_row_inserted),
289 m->signal_ids[ROW_DELETED] = g_signal_connect (client,
291 G_CALLBACK (signal_monitor_row_deleted),
293 m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
295 G_CALLBACK (signal_monitor_row_changed),
297 m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
298 "row-has-child-toggled",
299 G_CALLBACK (signal_monitor_row_has_child_toggled),
301 m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
303 G_CALLBACK (signal_monitor_rows_reordered),
310 signal_monitor_free (SignalMonitor *m)
314 for (i = 0; i < LAST_SIGNAL; i++)
315 g_signal_handler_disconnect (m->client, m->signal_ids[i]);
317 g_object_unref (m->client);
320 g_queue_free (m->queue);
326 signal_monitor_assert_is_empty (SignalMonitor *m)
328 g_assert (g_queue_is_empty (m->queue));
332 signal_monitor_append_signal_path (SignalMonitor *m,
338 s = signal_new (signal, path);
339 g_queue_push_head (m->queue, s);
343 signal_monitor_append_signal (SignalMonitor *m,
345 const gchar *path_string)
350 path = gtk_tree_path_new_from_string (path_string);
352 s = signal_new (signal, path);
353 g_queue_push_head (m->queue, s);
355 gtk_tree_path_free (path);
364 GtkWidget *tree_view;
367 GtkTreeModelFilter *filter;
369 SignalMonitor *monitor;
371 guint block_signals : 1;
376 filter_test_store_signal (FilterTest *fixture)
378 if (fixture->block_signals)
379 g_signal_stop_emission_by_name (fixture->store, "row-changed");
384 filter_test_setup_generic (FilterTest *fixture,
385 gconstpointer test_data,
390 const GtkTreePath *vroot = test_data;
391 GtkTreeModel *filter;
393 fixture->store = create_tree_store (depth, !empty);
395 g_signal_connect_swapped (fixture->store, "row-changed",
396 G_CALLBACK (filter_test_store_signal), fixture);
398 /* Please forgive me for casting const away. */
399 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
400 (GtkTreePath *)vroot);
401 fixture->filter = GTK_TREE_MODEL_FILTER (filter);
404 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
406 /* We need a tree view that's listening to get ref counting from that
409 fixture->tree_view = gtk_tree_view_new_with_model (filter);
411 fixture->monitor = signal_monitor_new (filter);
415 filter_test_setup (FilterTest *fixture,
416 gconstpointer test_data)
418 filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
422 filter_test_setup_empty (FilterTest *fixture,
423 gconstpointer test_data)
425 filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
429 filter_test_setup_unfiltered (FilterTest *fixture,
430 gconstpointer test_data)
432 filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
436 filter_test_setup_empty_unfiltered (FilterTest *fixture,
437 gconstpointer test_data)
439 filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
443 strip_virtual_root (GtkTreePath *path,
444 GtkTreePath *root_path)
446 GtkTreePath *real_path;
451 int depth = gtk_tree_path_get_depth (path);
452 int root_depth = gtk_tree_path_get_depth (root_path);
454 real_path = gtk_tree_path_new ();
456 for (j = 0; j < depth - root_depth; j++)
457 gtk_tree_path_append_index (real_path,
458 gtk_tree_path_get_indices (path)[root_depth + j]);
461 real_path = gtk_tree_path_copy (path);
467 filter_test_append_refilter_signals_recurse (FilterTest *fixture,
468 GtkTreePath *store_path,
469 GtkTreePath *filter_path,
471 GtkTreePath *root_path)
474 int rows_deleted = 0;
477 gtk_tree_path_down (store_path);
478 gtk_tree_path_down (filter_path);
480 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
483 for (i = 0; i < LEVEL_LENGTH; i++)
486 GtkTreePath *real_path;
488 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
493 (!gtk_tree_path_is_descendant (store_path, root_path)
494 || !gtk_tree_path_compare (store_path, root_path)))
496 if (!gtk_tree_path_compare (store_path, root_path))
499 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
502 GtkTreePath *store_copy;
503 GtkTreePath *filter_copy;
505 store_copy = gtk_tree_path_copy (store_path);
506 filter_copy = gtk_tree_path_copy (filter_path);
507 filter_test_append_refilter_signals_recurse (fixture,
512 gtk_tree_path_free (store_copy);
513 gtk_tree_path_free (filter_copy);
517 gtk_tree_path_next (store_path);
518 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
521 gtk_tree_path_next (filter_path);
526 real_path = strip_virtual_root (filter_path, root_path);
530 /* This row will be inserted */
531 signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
533 signal_monitor_append_signal_path (fixture->monitor,
534 ROW_HAS_CHILD_TOGGLED,
538 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
541 GtkTreePath *store_copy;
542 GtkTreePath *filter_copy;
544 store_copy = gtk_tree_path_copy (store_path);
545 filter_copy = gtk_tree_path_copy (filter_path);
546 filter_test_append_refilter_signals_recurse (fixture,
551 gtk_tree_path_free (store_copy);
552 gtk_tree_path_free (filter_copy);
555 gtk_tree_path_next (filter_path);
559 /* This row will be deleted */
561 signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
565 gtk_tree_path_free (real_path);
567 gtk_tree_path_next (store_path);
568 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
571 if (rows_deleted == LEVEL_LENGTH
572 && gtk_tree_path_get_depth (filter_path) > 1)
574 GtkTreePath *real_path;
576 gtk_tree_path_up (store_path);
577 gtk_tree_path_up (filter_path);
579 /* A row-has-child-toggled will be emitted on the parent */
582 && gtk_tree_path_is_descendant (store_path, root_path)
583 && gtk_tree_path_compare (store_path, root_path)))
585 real_path = strip_virtual_root (filter_path, root_path);
586 signal_monitor_append_signal_path (fixture->monitor,
587 ROW_HAS_CHILD_TOGGLED,
590 gtk_tree_path_free (real_path);
596 filter_test_append_refilter_signals (FilterTest *fixture,
599 /* A special function that walks the tree store like the
600 * model validation functions below.
603 GtkTreePath *filter_path;
605 path = gtk_tree_path_new ();
606 filter_path = gtk_tree_path_new ();
607 filter_test_append_refilter_signals_recurse (fixture,
612 gtk_tree_path_free (path);
613 gtk_tree_path_free (filter_path);
617 filter_test_append_refilter_signals_with_vroot (FilterTest *fixture,
619 GtkTreePath *root_path)
621 /* A special function that walks the tree store like the
622 * model validation functions below.
625 GtkTreePath *filter_path;
627 path = gtk_tree_path_new ();
628 filter_path = gtk_tree_path_new ();
629 filter_test_append_refilter_signals_recurse (fixture,
634 gtk_tree_path_free (path);
635 gtk_tree_path_free (filter_path);
639 filter_test_enable_filter (FilterTest *fixture)
641 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
642 gtk_tree_model_filter_refilter (fixture->filter);
646 filter_test_block_signals (FilterTest *fixture)
648 fixture->block_signals = TRUE;
652 filter_test_unblock_signals (FilterTest *fixture)
654 fixture->block_signals = FALSE;
658 filter_test_teardown (FilterTest *fixture,
659 gconstpointer test_data)
661 signal_monitor_free (fixture->monitor);
663 g_object_unref (fixture->filter);
664 g_object_unref (fixture->store);
668 * Model structure validation
672 check_filter_model_recurse (FilterTest *fixture,
673 GtkTreePath *store_parent_path,
674 GtkTreePath *filter_parent_path)
677 GtkTreeIter store_iter;
678 GtkTreeIter filter_iter;
679 gboolean store_has_next, filter_has_next;
681 gtk_tree_path_down (store_parent_path);
682 gtk_tree_path_down (filter_parent_path);
684 store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
685 &store_iter, store_parent_path);
686 filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
687 &filter_iter, filter_parent_path);
689 for (i = 0; i < LEVEL_LENGTH; i++)
693 g_return_if_fail (store_has_next == TRUE);
695 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
703 gchar *filter_str, *store_str;
705 g_return_if_fail (filter_has_next == TRUE);
708 tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
710 g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
712 /* Verify model content */
713 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
717 gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
722 g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
727 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
730 g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
732 check_filter_model_recurse (fixture,
733 gtk_tree_path_copy (store_parent_path),
737 gtk_tree_path_next (filter_parent_path);
738 filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
741 gtk_tree_path_next (store_parent_path);
742 store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
745 /* Both models should have no more content! */
746 g_return_if_fail (store_has_next == FALSE);
747 g_return_if_fail (filter_has_next == FALSE);
749 gtk_tree_path_free (store_parent_path);
750 gtk_tree_path_free (filter_parent_path);
754 check_filter_model (FilterTest *fixture)
758 if (fixture->monitor)
759 signal_monitor_assert_is_empty (fixture->monitor);
761 path = gtk_tree_path_new ();
763 check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
767 check_filter_model_with_root (FilterTest *fixture,
770 if (fixture->monitor)
771 signal_monitor_assert_is_empty (fixture->monitor);
773 check_filter_model_recurse (fixture,
774 gtk_tree_path_copy (path),
775 gtk_tree_path_new ());
781 check_level_length (GtkTreeModelFilter *filter,
787 int l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
788 g_return_if_fail (l == length);
793 gboolean retrieved_iter = FALSE;
796 retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
798 g_return_if_fail (retrieved_iter);
799 l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
800 g_return_if_fail (l == length);
805 set_path_visibility (FilterTest *fixture,
809 GtkTreeIter store_iter;
811 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
813 gtk_tree_store_set (fixture->store, &store_iter,
820 insert_path_with_visibility (FilterTest *fixture,
821 const gchar *path_string,
826 GtkTreeIter parent, iter;
828 path = gtk_tree_path_new_from_string (path_string);
829 position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
830 gtk_tree_path_up (path);
832 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
834 gtk_tree_store_insert (fixture->store, &iter, &parent, position);
835 create_tree_store_set_values (fixture->store, &iter, visible);
837 gtk_tree_path_free (path);
846 verify_test_suite (FilterTest *fixture,
847 gconstpointer user_data)
849 check_filter_model (fixture);
853 verify_test_suite_vroot (FilterTest *fixture,
854 gconstpointer user_data)
856 check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
861 filled_hide_root_level (FilterTest *fixture,
862 gconstpointer user_data)
864 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
865 set_path_visibility (fixture, "2", FALSE);
866 check_filter_model (fixture);
867 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
869 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
870 set_path_visibility (fixture, "0", FALSE);
871 check_filter_model (fixture);
872 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
874 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
875 set_path_visibility (fixture, "4", FALSE);
876 check_filter_model (fixture);
877 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
881 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
882 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
884 set_path_visibility (fixture, "1", FALSE);
885 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
887 set_path_visibility (fixture, "3", FALSE);
888 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
890 check_filter_model (fixture);
893 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
894 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
895 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
896 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
898 set_path_visibility (fixture, "1", TRUE);
899 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
901 set_path_visibility (fixture, "3", TRUE);
902 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
904 check_filter_model (fixture);
908 filled_hide_child_levels (FilterTest *fixture,
909 gconstpointer user_data)
911 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
912 set_path_visibility (fixture, "0:2", FALSE);
913 check_filter_model (fixture);
914 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
915 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
917 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
918 set_path_visibility (fixture, "0:4", FALSE);
919 check_filter_model (fixture);
920 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
921 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
923 set_path_visibility (fixture, "0:4:3", FALSE);
924 check_filter_model (fixture);
925 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
926 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
928 set_path_visibility (fixture, "0:4:0", FALSE);
929 set_path_visibility (fixture, "0:4:1", FALSE);
930 set_path_visibility (fixture, "0:4:2", FALSE);
931 set_path_visibility (fixture, "0:4:4", FALSE);
932 check_filter_model (fixture);
933 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
934 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
936 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
937 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
938 /* FIXME: Actually, the filter model should not be emitted the
939 * row-has-child-toggled signal here. *However* an extraneous emission
940 * of this signal does not hurt and is allowed.
942 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
943 set_path_visibility (fixture, "0:4", TRUE);
944 check_filter_model (fixture);
945 check_level_length (fixture->filter, "0:3", 0);
947 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
948 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
949 set_path_visibility (fixture, "0:2", TRUE);
950 check_filter_model (fixture);
951 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
952 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
953 check_level_length (fixture->filter, "0:4", 0);
955 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
956 /* Once 0:4:0 got inserted, 0:4 became a parent */
957 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
958 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:0");
959 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
960 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:1");
962 set_path_visibility (fixture, "0:4:2", TRUE);
963 set_path_visibility (fixture, "0:4:4", TRUE);
964 signal_monitor_assert_is_empty (fixture->monitor);
965 check_level_length (fixture->filter, "0:4", 2);
970 filled_vroot_hide_root_level (FilterTest *fixture,
971 gconstpointer user_data)
973 GtkTreePath *path = (GtkTreePath *)user_data;
975 /* These changes do not affect the filter's root level */
976 set_path_visibility (fixture, "0", FALSE);
977 check_filter_model_with_root (fixture, path);
978 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
979 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
981 set_path_visibility (fixture, "4", FALSE);
982 check_filter_model_with_root (fixture, path);
983 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
984 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
986 /* Even though we set the virtual root parent node to FALSE,
987 * the virtual root contents remain.
989 set_path_visibility (fixture, "2", FALSE);
990 check_filter_model_with_root (fixture, path);
991 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
992 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
995 set_path_visibility (fixture, "1", FALSE);
996 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
997 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
999 set_path_visibility (fixture, "3", FALSE);
1000 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1001 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1003 check_filter_model_with_root (fixture, path);
1006 set_path_visibility (fixture, "2", TRUE);
1007 check_filter_model_with_root (fixture, path);
1008 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1009 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1011 set_path_visibility (fixture, "1", TRUE);
1012 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1013 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1015 set_path_visibility (fixture, "3", TRUE);
1016 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1017 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
1019 check_filter_model_with_root (fixture, path);
1021 /* Now test changes in the virtual root level */
1022 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
1023 set_path_visibility (fixture, "2:2", FALSE);
1024 check_filter_model_with_root (fixture, path);
1025 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1027 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
1028 set_path_visibility (fixture, "2:4", FALSE);
1029 check_filter_model_with_root (fixture, path);
1030 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1032 set_path_visibility (fixture, "1:4", FALSE);
1033 check_filter_model_with_root (fixture, path);
1034 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1036 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
1037 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
1038 set_path_visibility (fixture, "2:4", TRUE);
1039 check_filter_model_with_root (fixture, path);
1040 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1042 set_path_visibility (fixture, "2", FALSE);
1043 check_filter_model_with_root (fixture, path);
1044 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1046 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1047 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1048 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1049 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1050 set_path_visibility (fixture, "2:0", FALSE);
1051 set_path_visibility (fixture, "2:1", FALSE);
1052 set_path_visibility (fixture, "2:2", FALSE);
1053 set_path_visibility (fixture, "2:3", FALSE);
1054 set_path_visibility (fixture, "2:4", FALSE);
1055 check_filter_model_with_root (fixture, path);
1056 check_level_length (fixture->filter, NULL, 0);
1058 set_path_visibility (fixture, "2", TRUE);
1059 check_filter_model_with_root (fixture, path);
1060 check_level_length (fixture->filter, NULL, 0);
1062 set_path_visibility (fixture, "1:4", FALSE);
1063 check_filter_model_with_root (fixture, path);
1064 check_level_length (fixture->filter, NULL, 0);
1066 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1067 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1068 set_path_visibility (fixture, "2:4", TRUE);
1069 check_filter_model_with_root (fixture, path);
1070 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
1072 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1073 set_path_visibility (fixture, "2:4", FALSE);
1074 check_filter_model_with_root (fixture, path);
1075 check_level_length (fixture->filter, NULL, 0);
1077 set_path_visibility (fixture, "2", FALSE);
1078 check_filter_model_with_root (fixture, path);
1079 check_level_length (fixture->filter, NULL, 0);
1081 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1082 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1083 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1084 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1085 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
1086 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1087 set_path_visibility (fixture, "2:0", TRUE);
1088 set_path_visibility (fixture, "2:1", TRUE);
1089 set_path_visibility (fixture, "2:2", TRUE);
1090 check_filter_model_with_root (fixture, path);
1091 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1093 set_path_visibility (fixture, "2", TRUE);
1094 check_filter_model_with_root (fixture, path);
1095 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
1099 filled_vroot_hide_child_levels (FilterTest *fixture,
1100 gconstpointer user_data)
1102 GtkTreePath *path = (GtkTreePath *)user_data;
1104 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1105 set_path_visibility (fixture, "2:0:2", FALSE);
1106 check_filter_model_with_root (fixture, path);
1107 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1108 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1110 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1111 set_path_visibility (fixture, "2:0:4", FALSE);
1112 check_filter_model_with_root (fixture, path);
1113 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1114 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1116 set_path_visibility (fixture, "2:0:4:3", FALSE);
1117 check_filter_model_with_root (fixture, path);
1118 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1119 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1121 set_path_visibility (fixture, "2:0:4:0", FALSE);
1122 set_path_visibility (fixture, "2:0:4:1", FALSE);
1123 set_path_visibility (fixture, "2:0:4:2", FALSE);
1124 set_path_visibility (fixture, "2:0:4:4", FALSE);
1125 check_filter_model_with_root (fixture, path);
1126 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1127 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1129 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1130 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1131 /* FIXME: Actually, the filter model should not be emitted the
1132 * row-has-child-toggled signal here. *However* an extraneous emission
1133 * of this signal does not hurt and is allowed.
1135 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1136 set_path_visibility (fixture, "2:0:4", TRUE);
1137 check_filter_model_with_root (fixture, path);
1138 check_level_length (fixture->filter, "0:3", 0);
1140 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1141 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1142 set_path_visibility (fixture, "2:0:2", TRUE);
1143 check_filter_model_with_root (fixture, path);
1144 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1145 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1146 check_level_length (fixture->filter, "0:4", 0);
1148 /* FIXME: Inconsistency! For the non-vroot case we also receive two
1149 * row-has-child-toggled signals here.
1151 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
1152 /* Once 0:4:0 got inserted, 0:4 became a parent */
1153 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1154 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
1155 set_path_visibility (fixture, "2:0:4:2", TRUE);
1156 set_path_visibility (fixture, "2:0:4:4", TRUE);
1157 check_level_length (fixture->filter, "0:4", 2);
1162 empty_show_nodes (FilterTest *fixture,
1163 gconstpointer user_data)
1165 check_filter_model (fixture);
1166 check_level_length (fixture->filter, NULL, 0);
1168 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1169 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1170 set_path_visibility (fixture, "3", TRUE);
1171 check_filter_model (fixture);
1172 check_level_length (fixture->filter, NULL, 1);
1173 check_level_length (fixture->filter, "0", 0);
1175 set_path_visibility (fixture, "3:2:2", TRUE);
1176 check_filter_model (fixture);
1177 check_level_length (fixture->filter, NULL, 1);
1178 check_level_length (fixture->filter, "0", 0);
1180 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
1181 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1182 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
1183 set_path_visibility (fixture, "3:2", TRUE);
1184 check_filter_model (fixture);
1185 check_level_length (fixture->filter, NULL, 1);
1186 check_level_length (fixture->filter, "0", 1);
1187 check_level_length (fixture->filter, "0:0", 1);
1188 check_level_length (fixture->filter, "0:0:0", 0);
1190 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1191 set_path_visibility (fixture, "3", FALSE);
1192 check_filter_model (fixture);
1193 check_level_length (fixture->filter, NULL, 0);
1195 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1196 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1197 set_path_visibility (fixture, "3:2:1", TRUE);
1198 set_path_visibility (fixture, "3", TRUE);
1199 check_filter_model (fixture);
1200 check_level_length (fixture->filter, NULL, 1);
1201 check_level_length (fixture->filter, "0", 1);
1202 check_level_length (fixture->filter, "0:0", 2);
1203 check_level_length (fixture->filter, "0:0:0", 0);
1207 empty_show_multiple_nodes (FilterTest *fixture,
1208 gconstpointer user_data)
1211 GtkTreePath *changed_path;
1213 check_filter_model (fixture);
1214 check_level_length (fixture->filter, NULL, 0);
1216 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1217 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1218 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1219 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1220 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "1");
1221 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1223 /* We simulate a change in visible func condition with this. The
1224 * visibility state of multiple nodes changes at once, we emit row-changed
1225 * for these nodes (and others) after that.
1227 filter_test_block_signals (fixture);
1228 set_path_visibility (fixture, "3", TRUE);
1229 set_path_visibility (fixture, "4", TRUE);
1230 filter_test_unblock_signals (fixture);
1232 changed_path = gtk_tree_path_new ();
1233 gtk_tree_path_append_index (changed_path, 2);
1234 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1235 &iter, changed_path);
1236 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1237 changed_path, &iter);
1239 gtk_tree_path_next (changed_path);
1240 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1241 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1242 changed_path, &iter);
1244 gtk_tree_path_next (changed_path);
1245 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1246 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1247 changed_path, &iter);
1249 gtk_tree_path_free (changed_path);
1251 check_filter_model (fixture);
1252 check_level_length (fixture->filter, NULL, 2);
1253 check_level_length (fixture->filter, "0", 0);
1255 set_path_visibility (fixture, "3:2:2", TRUE);
1256 check_filter_model (fixture);
1257 check_level_length (fixture->filter, NULL, 2);
1258 check_level_length (fixture->filter, "0", 0);
1260 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
1261 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1262 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
1263 set_path_visibility (fixture, "3:2", TRUE);
1264 check_filter_model (fixture);
1265 check_level_length (fixture->filter, NULL, 2);
1266 check_level_length (fixture->filter, "0", 1);
1267 check_level_length (fixture->filter, "0:0", 1);
1268 check_level_length (fixture->filter, "0:0:0", 0);
1270 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1271 set_path_visibility (fixture, "3", FALSE);
1272 check_filter_model (fixture);
1273 check_level_length (fixture->filter, NULL, 1);
1275 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1276 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1277 set_path_visibility (fixture, "3:2:1", TRUE);
1278 set_path_visibility (fixture, "3", TRUE);
1279 check_filter_model (fixture);
1280 check_level_length (fixture->filter, NULL, 2);
1281 check_level_length (fixture->filter, "0", 1);
1282 check_level_length (fixture->filter, "0:0", 2);
1283 check_level_length (fixture->filter, "0:0:0", 0);
1287 empty_vroot_show_nodes (FilterTest *fixture,
1288 gconstpointer user_data)
1290 GtkTreePath *path = (GtkTreePath *)user_data;
1292 check_filter_model_with_root (fixture, path);
1293 check_level_length (fixture->filter, NULL, 0);
1295 set_path_visibility (fixture, "2", TRUE);
1296 check_filter_model_with_root (fixture, path);
1297 check_level_length (fixture->filter, NULL, 0);
1299 set_path_visibility (fixture, "2:2:2", TRUE);
1300 check_filter_model_with_root (fixture, path);
1301 check_level_length (fixture->filter, NULL, 0);
1303 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1304 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1305 set_path_visibility (fixture, "2:2", TRUE);
1306 check_filter_model_with_root (fixture, path);
1307 check_level_length (fixture->filter, NULL, 1);
1308 check_level_length (fixture->filter, "0", 1);
1309 check_level_length (fixture->filter, "0:0", 0);
1311 set_path_visibility (fixture, "3", TRUE);
1312 check_filter_model_with_root (fixture, path);
1313 check_level_length (fixture->filter, NULL, 1);
1315 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1316 set_path_visibility (fixture, "2:2", FALSE);
1317 check_filter_model_with_root (fixture, path);
1318 check_level_length (fixture->filter, NULL, 0);
1320 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1321 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1322 set_path_visibility (fixture, "2:2:1", TRUE);
1323 set_path_visibility (fixture, "2:2", TRUE);
1324 check_filter_model_with_root (fixture, path);
1325 check_level_length (fixture->filter, NULL, 1);
1326 check_level_length (fixture->filter, "0", 2);
1327 check_level_length (fixture->filter, "0:1", 0);
1331 empty_vroot_show_multiple_nodes (FilterTest *fixture,
1332 gconstpointer user_data)
1335 GtkTreePath *changed_path;
1336 GtkTreePath *path = (GtkTreePath *)user_data;
1338 check_filter_model_with_root (fixture, path);
1339 check_level_length (fixture->filter, NULL, 0);
1341 /* We simulate a change in visible func condition with this. The
1342 * visibility state of multiple nodes changes at once, we emit row-changed
1343 * for these nodes (and others) after that.
1345 filter_test_block_signals (fixture);
1346 set_path_visibility (fixture, "2", TRUE);
1347 set_path_visibility (fixture, "3", TRUE);
1348 filter_test_unblock_signals (fixture);
1350 changed_path = gtk_tree_path_new ();
1351 gtk_tree_path_append_index (changed_path, 1);
1352 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1353 &iter, changed_path);
1354 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1355 changed_path, &iter);
1357 gtk_tree_path_next (changed_path);
1358 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1359 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1360 changed_path, &iter);
1362 gtk_tree_path_next (changed_path);
1363 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1364 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1365 changed_path, &iter);
1367 gtk_tree_path_next (changed_path);
1368 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1369 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1370 changed_path, &iter);
1372 gtk_tree_path_free (changed_path);
1374 check_filter_model_with_root (fixture, path);
1375 check_level_length (fixture->filter, NULL, 0);
1377 set_path_visibility (fixture, "2:2:2", TRUE);
1378 check_filter_model_with_root (fixture, path);
1379 check_level_length (fixture->filter, NULL, 0);
1381 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1382 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1383 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1384 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1386 /* Again, we simulate a call to refilter */
1387 filter_test_block_signals (fixture);
1388 set_path_visibility (fixture, "2:2", TRUE);
1389 set_path_visibility (fixture, "2:3", TRUE);
1390 filter_test_unblock_signals (fixture);
1392 changed_path = gtk_tree_path_new ();
1393 gtk_tree_path_append_index (changed_path, 2);
1394 gtk_tree_path_append_index (changed_path, 1);
1395 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1396 &iter, changed_path);
1397 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1398 changed_path, &iter);
1400 gtk_tree_path_next (changed_path);
1401 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1402 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1403 changed_path, &iter);
1405 gtk_tree_path_next (changed_path);
1406 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1407 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1408 changed_path, &iter);
1410 gtk_tree_path_next (changed_path);
1411 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1412 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1413 changed_path, &iter);
1415 gtk_tree_path_free (changed_path);
1417 check_filter_model_with_root (fixture, path);
1418 check_level_length (fixture->filter, NULL, 2);
1419 check_level_length (fixture->filter, "0", 1);
1420 check_level_length (fixture->filter, "0:0", 0);
1422 set_path_visibility (fixture, "3", TRUE);
1423 check_filter_model_with_root (fixture, path);
1424 check_level_length (fixture->filter, NULL, 2);
1426 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1427 set_path_visibility (fixture, "2:2", FALSE);
1428 check_filter_model_with_root (fixture, path);
1429 check_level_length (fixture->filter, NULL, 1);
1431 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1432 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1433 set_path_visibility (fixture, "2:2:1", TRUE);
1434 set_path_visibility (fixture, "2:2", TRUE);
1435 check_filter_model_with_root (fixture, path);
1436 check_level_length (fixture->filter, NULL, 2);
1437 check_level_length (fixture->filter, "0", 2);
1438 check_level_length (fixture->filter, "0:1", 0);
1443 unfiltered_hide_single (FilterTest *fixture,
1444 gconstpointer user_data)
1447 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1448 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1449 set_path_visibility (fixture, "2", FALSE);
1451 signal_monitor_assert_is_empty (fixture->monitor);
1452 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1454 /* The view only shows the root level, so the filter model only has
1455 * the first two levels cached.
1457 filter_test_append_refilter_signals (fixture, 2);
1458 filter_test_enable_filter (fixture);
1460 check_filter_model (fixture);
1461 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1465 unfiltered_hide_single_child (FilterTest *fixture,
1466 gconstpointer user_data)
1469 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1470 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1471 set_path_visibility (fixture, "2:2", FALSE);
1473 signal_monitor_assert_is_empty (fixture->monitor);
1474 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1475 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1477 /* The view only shows the root level, so the filter model only has
1478 * the first two levels cached.
1480 filter_test_append_refilter_signals (fixture, 2);
1481 filter_test_enable_filter (fixture);
1483 check_filter_model (fixture);
1484 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1485 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1489 unfiltered_hide_single_multi_level (FilterTest *fixture,
1490 gconstpointer user_data)
1493 /* This row is not shown, so its signal is not propagated */
1494 set_path_visibility (fixture, "2:2:2", FALSE);
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", FALSE);
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 (fixture, 2);
1509 filter_test_enable_filter (fixture);
1511 check_filter_model (fixture);
1512 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1513 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1515 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1516 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1517 set_path_visibility (fixture, "2:2", TRUE);
1519 check_filter_model (fixture);
1520 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1521 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1522 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1527 unfiltered_vroot_hide_single (FilterTest *fixture,
1528 gconstpointer user_data)
1531 GtkTreePath *path = (GtkTreePath *)user_data;
1533 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1534 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1535 set_path_visibility (fixture, "2:2", FALSE);
1537 signal_monitor_assert_is_empty (fixture->monitor);
1538 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1540 /* The view only shows the root level, so the filter model only has
1541 * the first two levels cached. (We add an additional level to
1542 * take the virtual root into account).
1544 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1545 filter_test_enable_filter (fixture);
1547 check_filter_model_with_root (fixture, path);
1548 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1552 unfiltered_vroot_hide_single_child (FilterTest *fixture,
1553 gconstpointer user_data)
1556 GtkTreePath *path = (GtkTreePath *)user_data;
1558 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1559 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1560 set_path_visibility (fixture, "2:2:2", FALSE);
1562 signal_monitor_assert_is_empty (fixture->monitor);
1563 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1564 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1566 /* The view only shows the root level, so the filter model only has
1567 * the first two levels cached. (We add an additional level to take
1568 * the virtual root into account).
1570 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1571 filter_test_enable_filter (fixture);
1573 check_filter_model_with_root (fixture, path);
1574 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1575 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1579 unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
1580 gconstpointer user_data)
1583 GtkTreePath *path = (GtkTreePath *)user_data;
1585 /* This row is not shown, so its signal is not propagated */
1586 set_path_visibility (fixture, "2:2:2:2", FALSE);
1588 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1589 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1590 set_path_visibility (fixture, "2:2:2", FALSE);
1592 signal_monitor_assert_is_empty (fixture->monitor);
1593 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1594 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1595 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1597 /* The view only shows the root level, so the filter model only has
1598 * the first two levels cached.
1600 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1601 filter_test_enable_filter (fixture);
1603 check_filter_model_with_root (fixture, path);
1604 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1605 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1607 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1608 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1609 set_path_visibility (fixture, "2:2:2", TRUE);
1611 check_filter_model_with_root (fixture, path);
1612 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1613 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1614 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1620 unfiltered_show_single (FilterTest *fixture,
1621 gconstpointer user_data)
1624 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1625 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1626 set_path_visibility (fixture, "2", TRUE);
1628 signal_monitor_assert_is_empty (fixture->monitor);
1629 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1631 /* The view only shows the root level, so the filter model only has
1632 * the first two levels cached.
1634 filter_test_append_refilter_signals (fixture, 2);
1635 filter_test_enable_filter (fixture);
1637 check_filter_model (fixture);
1638 check_level_length (fixture->filter, NULL, 1);
1642 unfiltered_show_single_child (FilterTest *fixture,
1643 gconstpointer user_data)
1646 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1647 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1648 set_path_visibility (fixture, "2:2", TRUE);
1650 signal_monitor_assert_is_empty (fixture->monitor);
1651 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1652 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1654 /* The view only shows the root level, so the filter model only has
1655 * the first two levels cached.
1657 filter_test_append_refilter_signals (fixture, 3);
1658 filter_test_enable_filter (fixture);
1660 check_filter_model (fixture);
1661 check_level_length (fixture->filter, NULL, 0);
1663 /* From here we are filtered, "2" in the real model is "0" in the filter
1666 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1667 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1668 set_path_visibility (fixture, "2", TRUE);
1669 signal_monitor_assert_is_empty (fixture->monitor);
1670 check_level_length (fixture->filter, NULL, 1);
1671 check_level_length (fixture->filter, "0", 1);
1675 unfiltered_show_single_multi_level (FilterTest *fixture,
1676 gconstpointer user_data)
1679 /* The view is not showing this row (collapsed state), so it is not
1680 * referenced. The signal should not go through.
1682 set_path_visibility (fixture, "2:2:2", TRUE);
1684 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1685 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1686 set_path_visibility (fixture, "2:2", TRUE);
1688 signal_monitor_assert_is_empty (fixture->monitor);
1689 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1690 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1691 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1693 /* The view only shows the root level, so the filter model only has
1694 * the first two levels cached.
1696 filter_test_append_refilter_signals (fixture, 3);
1697 filter_test_enable_filter (fixture);
1699 check_filter_model (fixture);
1700 check_level_length (fixture->filter, NULL, 0);
1702 /* From here we are filtered, "2" in the real model is "0" in the filter
1705 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1706 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1707 set_path_visibility (fixture, "2", TRUE);
1708 check_filter_model (fixture);
1709 check_level_length (fixture->filter, NULL, 1);
1710 check_level_length (fixture->filter, "0", 1);
1711 check_level_length (fixture->filter, "0:0", 1);
1716 unfiltered_vroot_show_single (FilterTest *fixture,
1717 gconstpointer user_data)
1720 GtkTreePath *path = (GtkTreePath *)user_data;
1722 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1723 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1724 set_path_visibility (fixture, "2:2", TRUE);
1726 signal_monitor_assert_is_empty (fixture->monitor);
1727 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1729 /* The view only shows the root level, so the filter model only has
1730 * the first two levels cached.
1732 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1733 filter_test_enable_filter (fixture);
1735 check_filter_model_with_root (fixture, path);
1736 check_level_length (fixture->filter, NULL, 1);
1740 unfiltered_vroot_show_single_child (FilterTest *fixture,
1741 gconstpointer user_data)
1744 GtkTreePath *path = (GtkTreePath *)user_data;
1746 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1747 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1748 set_path_visibility (fixture, "2:2:2", TRUE);
1750 signal_monitor_assert_is_empty (fixture->monitor);
1751 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1752 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1754 /* The view only shows the root level, so the filter model only has
1755 * the first two levels cached.
1757 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1758 filter_test_enable_filter (fixture);
1760 check_filter_model_with_root (fixture, path);
1761 check_level_length (fixture->filter, NULL, 0);
1763 /* From here we are filtered, "2" in the real model is "0" in the filter
1766 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1767 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1768 set_path_visibility (fixture, "2:2", TRUE);
1769 signal_monitor_assert_is_empty (fixture->monitor);
1770 check_level_length (fixture->filter, NULL, 1);
1771 check_level_length (fixture->filter, "0", 1);
1775 unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
1776 gconstpointer user_data)
1779 GtkTreePath *path = (GtkTreePath *)user_data;
1781 /* The view is not showing this row (collapsed state), so it is not
1782 * referenced. The signal should not go through.
1784 set_path_visibility (fixture, "2:2:2:2", TRUE);
1786 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1787 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1788 set_path_visibility (fixture, "2:2:2", TRUE);
1790 signal_monitor_assert_is_empty (fixture->monitor);
1791 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1792 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1793 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1795 /* The view only shows the root level, so the filter model only has
1796 * the first two levels cached.
1798 filter_test_append_refilter_signals_with_vroot (fixture, 4, path);
1799 filter_test_enable_filter (fixture);
1801 check_filter_model_with_root (fixture, path);
1802 check_level_length (fixture->filter, NULL, 0);
1804 /* From here we are filtered, "2" in the real model is "0" in the filter
1807 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1808 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1809 set_path_visibility (fixture, "2:2", TRUE);
1810 check_filter_model_with_root (fixture, path);
1811 check_level_length (fixture->filter, NULL, 1);
1812 check_level_length (fixture->filter, "0", 1);
1813 check_level_length (fixture->filter, "0:0", 1);
1818 specific_remove_node (void)
1820 GtkTreeIter iter, iter1, iter2, iter3;
1822 GtkTreeModel *filter;
1823 GtkWidget *view G_GNUC_UNUSED;
1825 list = gtk_list_store_new (1, G_TYPE_INT);
1826 gtk_list_store_insert_with_values (list, &iter1, 0, 0, 1, -1);
1827 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
1828 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
1829 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
1830 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
1831 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
1832 gtk_list_store_insert_with_values (list, &iter2, 6, 0, 7, -1);
1833 gtk_list_store_insert_with_values (list, &iter3, 7, 0, 8, -1);
1835 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
1836 view = gtk_tree_view_new_with_model (filter);
1838 gtk_list_store_remove (list, &iter1);
1839 gtk_list_store_remove (list, &iter3);
1840 gtk_list_store_remove (list, &iter2);
1844 specific_remove_node_vroot (void)
1846 GtkTreeIter parent, root;
1847 GtkTreeIter iter, iter1, iter2, iter3;
1849 GtkTreeModel *filter;
1851 GtkWidget *view G_GNUC_UNUSED;
1853 tree = gtk_tree_store_new (1, G_TYPE_INT);
1854 gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
1855 gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
1857 gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
1858 gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
1859 gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
1860 gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
1861 gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
1862 gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
1863 gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
1864 gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
1866 path = gtk_tree_path_new_from_indices (0, 0, -1);
1867 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
1868 gtk_tree_path_free (path);
1870 view = gtk_tree_view_new_with_model (filter);
1872 gtk_tree_store_remove (tree, &iter1);
1873 gtk_tree_store_remove (tree, &iter3);
1874 gtk_tree_store_remove (tree, &iter2);
1878 specific_remove_vroot_ancestor (void)
1880 GtkTreeIter parent, root;
1881 GtkTreeIter iter, iter1, iter2, iter3;
1883 GtkTreeModel *filter;
1885 GtkWidget *view G_GNUC_UNUSED;
1887 tree = gtk_tree_store_new (1, G_TYPE_INT);
1888 gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
1889 gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
1891 gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
1892 gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
1893 gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
1894 gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
1895 gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
1896 gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
1897 gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
1898 gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
1900 path = gtk_tree_path_new_from_indices (0, 0, -1);
1901 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
1902 gtk_tree_path_free (path);
1904 view = gtk_tree_view_new_with_model (filter);
1906 gtk_tree_store_remove (tree, &parent);
1911 specific_path_dependent_filter_func (GtkTreeModel *model,
1917 path = gtk_tree_model_get_path (model, iter);
1918 if (gtk_tree_path_get_indices (path)[0] < 4)
1925 specific_path_dependent_filter (void)
1931 GtkTreeModel *filter;
1933 list = gtk_list_store_new (1, G_TYPE_INT);
1934 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
1935 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
1936 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
1937 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
1938 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
1939 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
1940 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
1941 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
1943 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
1944 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
1945 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
1946 specific_path_dependent_filter_func,
1949 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
1950 GTK_SORT_DESCENDING);
1952 for (i = 0; i < 4; i++)
1954 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1956 gtk_list_store_remove (list, &iter);
1958 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
1960 gtk_list_store_remove (list, &iter);
1966 specific_append_after_collapse_visible_func (GtkTreeModel *model,
1971 gboolean hide_negative_numbers;
1973 gtk_tree_model_get (model, iter, 1, &number, -1);
1974 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
1976 return (number >= 0 || !hide_negative_numbers);
1980 specific_append_after_collapse (void)
1982 /* This test is based on one of the test cases I found in my
1983 * old test cases directory. I unfortunately do not have a record
1984 * from who this test case originated. -Kris.
1988 * - Show tree, expand, collapse.
1993 GtkTreeIter child_iter;
1994 GtkTreeIter child_iter2;
1995 GtkTreePath *append_path;
1996 GtkTreeStore *store;
1997 GtkTreeModel *filter;
2001 GtkWidget *tree_view;
2003 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
2005 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2006 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
2007 GINT_TO_POINTER (FALSE));
2008 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2009 specific_append_after_collapse_visible_func,
2012 sort = gtk_tree_model_sort_new_with_model (filter);
2014 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2015 tree_view = gtk_tree_view_new_with_model (sort);
2016 gtk_container_add (GTK_CONTAINER (window), tree_view);
2017 gtk_widget_realize (tree_view);
2019 while (gtk_events_pending ())
2020 gtk_main_iteration ();
2022 gtk_tree_store_prepend (store, &iter, NULL);
2023 gtk_tree_store_set (store, &iter,
2024 0, "hallo", 1, 1, -1);
2026 gtk_tree_store_append (store, &child_iter, &iter);
2027 gtk_tree_store_set (store, &child_iter,
2028 0, "toemaar", 1, 1, -1);
2030 gtk_tree_store_append (store, &child_iter2, &child_iter);
2031 gtk_tree_store_set (store, &child_iter2,
2032 0, "very deep", 1, 1, -1);
2034 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
2036 gtk_tree_store_append (store, &child_iter, &iter);
2037 gtk_tree_store_set (store, &child_iter,
2038 0, "sja", 1, 1, -1);
2040 gtk_tree_store_append (store, &child_iter, &iter);
2041 gtk_tree_store_set (store, &child_iter,
2042 0, "some word", 1, -1, -1);
2044 /* Expand and collapse the tree */
2045 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2046 while (gtk_events_pending ())
2047 gtk_main_iteration ();
2049 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
2050 while (gtk_events_pending ())
2051 gtk_main_iteration ();
2053 /* Add another it */
2054 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
2055 GINT_TO_POINTER (TRUE));
2057 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
2059 gtk_tree_store_append (store, &child_iter, &iter);
2060 gtk_tree_store_set (store, &child_iter,
2061 0, "new new new !!", 1, 1, -1);
2063 gtk_tree_path_free (append_path);
2066 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2067 while (gtk_events_pending ())
2068 gtk_main_iteration ();
2073 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
2082 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
2088 /* Do reference the model */
2089 gtk_tree_model_get (model, iter, 0, &item, -1);
2096 specific_sort_filter_remove_node (void)
2098 /* This test is based on one of the test cases I found in my
2099 * old test cases directory. I unfortunately do not have a record
2100 * from who this test case originated. -Kris.
2103 * - Create tree store, sort, filter models. The sort model has
2104 * a default sort func that is enabled, filter model a visible func
2105 * that defaults to returning FALSE.
2106 * - Remove a node from the tree store.
2110 GtkTreeStore *store;
2111 GtkTreeModel *filter;
2115 GtkWidget *tree_view;
2117 store = gtk_tree_store_new (1, G_TYPE_STRING);
2118 gtk_tree_store_append (store, &iter, NULL);
2119 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
2121 gtk_tree_store_append (store, &iter, NULL);
2122 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
2124 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2125 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
2126 specific_sort_filter_remove_node_compare_func, NULL, NULL);
2128 filter = gtk_tree_model_filter_new (sort, NULL);
2129 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2130 specific_sort_filter_remove_node_visible_func,
2134 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2135 tree_view = gtk_tree_view_new_with_model (filter);
2136 gtk_container_add (GTK_CONTAINER (window), tree_view);
2137 gtk_widget_realize (tree_view);
2139 while (gtk_events_pending ())
2140 gtk_main_iteration ();
2143 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
2144 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
2145 gtk_tree_store_remove (store, &iter);
2147 while (gtk_events_pending ())
2148 gtk_main_iteration ();
2153 specific_sort_filter_remove_root (void)
2155 /* This test is based on one of the test cases I found in my
2156 * old test cases directory. I unfortunately do not have a record
2157 * from who this test case originated. -Kris.
2160 GtkTreeModel *model, *sort, *filter;
2161 GtkTreeIter root, mid, leaf;
2164 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
2165 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
2166 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
2167 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
2169 path = gtk_tree_model_get_path (model, &mid);
2171 sort = gtk_tree_model_sort_new_with_model (model);
2172 filter = gtk_tree_model_filter_new (sort, path);
2174 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
2176 g_object_unref (filter);
2177 g_object_unref (sort);
2178 g_object_unref (model);
2183 specific_root_mixed_visibility (void)
2186 GtkTreeModel *filter;
2187 /* A bit nasty, apologies */
2190 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2192 for (i = 0; i < LEVEL_LENGTH; i++)
2196 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
2198 create_tree_store_set_values (fixture.store, &iter, TRUE);
2200 create_tree_store_set_values (fixture.store, &iter, FALSE);
2203 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
2204 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
2205 fixture.monitor = NULL;
2207 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
2209 /* In order to trigger the potential bug, we should not access
2210 * the filter model here (so don't call the check functions).
2213 /* Change visibility of an odd row to TRUE */
2214 set_path_visibility (&fixture, "3", TRUE);
2215 check_filter_model (&fixture);
2216 check_level_length (fixture.filter, NULL, 4);
2222 specific_has_child_filter_filter_func (GtkTreeModel *model,
2226 return gtk_tree_model_iter_has_child (model, iter);
2230 specific_has_child_filter (void)
2232 GtkTreeModel *filter;
2233 GtkTreeIter iter, root;
2234 /* A bit nasty, apologies */
2237 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2238 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
2239 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
2240 fixture.monitor = NULL;
2242 /* We will filter on parent state using a filter function. We will
2243 * manually keep the boolean column in sync, so that we can use
2244 * check_filter_model() to check the consistency of the model.
2246 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
2247 * to be able to check the structure here. We keep the calls to
2248 * check_filter_model() commented out until then.
2250 gtk_tree_model_filter_set_visible_func (fixture.filter,
2251 specific_has_child_filter_filter_func,
2254 gtk_tree_store_append (fixture.store, &root, NULL);
2255 create_tree_store_set_values (fixture.store, &root, FALSE);
2257 /* check_filter_model (&fixture); */
2258 check_level_length (fixture.filter, NULL, 0);
2260 gtk_tree_store_append (fixture.store, &iter, &root);
2261 create_tree_store_set_values (fixture.store, &iter, TRUE);
2263 /* Parent must now be visible. Do the level length check first,
2264 * to avoid modifying the child model triggering a row-changed to
2267 check_level_length (fixture.filter, NULL, 1);
2268 check_level_length (fixture.filter, "0", 0);
2270 set_path_visibility (&fixture, "0", TRUE);
2271 /* check_filter_model (&fixture); */
2273 gtk_tree_store_append (fixture.store, &root, NULL);
2274 check_level_length (fixture.filter, NULL, 1);
2276 gtk_tree_store_append (fixture.store, &iter, &root);
2277 check_level_length (fixture.filter, NULL, 2);
2278 check_level_length (fixture.filter, "1", 0);
2280 create_tree_store_set_values (fixture.store, &root, TRUE);
2281 create_tree_store_set_values (fixture.store, &iter, TRUE);
2283 /* check_filter_model (&fixture); */
2285 gtk_tree_store_append (fixture.store, &iter, &root);
2286 create_tree_store_set_values (fixture.store, &iter, TRUE);
2287 check_level_length (fixture.filter, NULL, 2);
2288 check_level_length (fixture.filter, "0", 0);
2289 check_level_length (fixture.filter, "1", 0);
2291 /* Now remove one of the remaining child rows */
2292 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
2294 gtk_tree_store_remove (fixture.store, &iter);
2296 check_level_length (fixture.filter, NULL, 1);
2297 check_level_length (fixture.filter, "0", 0);
2299 set_path_visibility (&fixture, "0", FALSE);
2300 /* check_filter_model (&fixture); */
2305 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
2312 path = gtk_tree_model_get_path (model, iter);
2313 depth = gtk_tree_path_get_depth (path);
2314 gtk_tree_path_free (path);
2319 return gtk_tree_model_iter_has_child (model, iter);
2323 specific_root_has_child_filter (void)
2325 GtkTreeModel *filter;
2326 GtkTreeIter iter, root;
2327 /* A bit nasty, apologies */
2330 /* This is a variation on the above test case wherein the has-child
2331 * check for visibility only applies to root level nodes.
2334 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2335 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
2336 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
2337 fixture.monitor = NULL;
2339 /* We will filter on parent state using a filter function. We will
2340 * manually keep the boolean column in sync, so that we can use
2341 * check_filter_model() to check the consistency of the model.
2343 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
2344 * to be able to check the structure here. We keep the calls to
2345 * check_filter_model() commented out until then.
2347 gtk_tree_model_filter_set_visible_func (fixture.filter,
2348 specific_root_has_child_filter_filter_func,
2351 gtk_tree_store_append (fixture.store, &root, NULL);
2352 create_tree_store_set_values (fixture.store, &root, FALSE);
2354 /* check_filter_model (&fixture); */
2355 check_level_length (fixture.filter, NULL, 0);
2357 gtk_tree_store_append (fixture.store, &iter, &root);
2358 create_tree_store_set_values (fixture.store, &iter, TRUE);
2360 /* Parent must now be visible. Do the level length check first,
2361 * to avoid modifying the child model triggering a row-changed to
2364 check_level_length (fixture.filter, NULL, 1);
2365 check_level_length (fixture.filter, "0", 1);
2367 set_path_visibility (&fixture, "0", TRUE);
2368 /* check_filter_model (&fixture); */
2370 gtk_tree_store_append (fixture.store, &root, NULL);
2371 check_level_length (fixture.filter, NULL, 1);
2373 gtk_tree_store_append (fixture.store, &iter, &root);
2374 check_level_length (fixture.filter, NULL, 2);
2375 check_level_length (fixture.filter, "1", 1);
2377 create_tree_store_set_values (fixture.store, &root, TRUE);
2378 create_tree_store_set_values (fixture.store, &iter, TRUE);
2380 /* check_filter_model (&fixture); */
2382 gtk_tree_store_append (fixture.store, &iter, &root);
2383 create_tree_store_set_values (fixture.store, &iter, TRUE);
2384 check_level_length (fixture.filter, NULL, 2);
2385 check_level_length (fixture.filter, "0", 1);
2386 check_level_length (fixture.filter, "1", 2);
2388 /* Now remove one of the remaining child rows */
2389 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
2391 gtk_tree_store_remove (fixture.store, &iter);
2393 check_level_length (fixture.filter, NULL, 1);
2394 check_level_length (fixture.filter, "0", 2);
2396 set_path_visibility (&fixture, "0", FALSE);
2397 /* check_filter_model (&fixture); */
2402 specific_filter_add_child (void)
2404 /* This test is based on one of the test cases I found in my
2405 * old test cases directory. I unfortunately do not have a record
2406 * from who this test case originated. -Kris.
2410 GtkTreeIter iter_first;
2412 GtkTreeStore *store;
2413 GtkTreeModel *filter G_GNUC_UNUSED;
2415 store = gtk_tree_store_new (1, G_TYPE_STRING);
2417 gtk_tree_store_append (store, &iter_first, NULL);
2418 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
2420 gtk_tree_store_append (store, &iter, NULL);
2421 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2423 gtk_tree_store_append (store, &iter, NULL);
2424 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2426 gtk_tree_store_append (store, &iter, NULL);
2427 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2429 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2431 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
2432 gtk_tree_store_append (store, &child, &iter_first);
2433 gtk_tree_store_set (store, &child, 0, "Hello", -1);
2437 specific_list_store_clear (void)
2441 GtkTreeModel *filter;
2442 GtkWidget *view G_GNUC_UNUSED;
2444 list = gtk_list_store_new (1, G_TYPE_INT);
2445 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
2446 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
2447 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
2448 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
2449 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
2450 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
2451 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
2452 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
2454 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
2455 view = gtk_tree_view_new_with_model (filter);
2457 gtk_list_store_clear (list);
2461 specific_sort_ref_leaf_and_remove_ancestor (void)
2463 GtkTreeIter iter, child, child2, child3;
2467 GtkTreeRowReference *rowref;
2468 GtkWidget *view G_GNUC_UNUSED;
2470 tree = gtk_tree_store_new (1, G_TYPE_INT);
2471 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
2472 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
2473 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
2474 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
2476 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
2477 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
2478 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
2480 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
2481 view = gtk_tree_view_new_with_model (sort);
2482 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
2484 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
2485 rowref = gtk_tree_row_reference_new (sort, path);
2486 gtk_tree_path_free (path);
2488 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
2489 rowref = gtk_tree_row_reference_new (sort, path);
2490 gtk_tree_path_free (path);
2492 path = gtk_tree_path_new_from_indices (3, 0, -1);
2493 rowref = gtk_tree_row_reference_new (sort, path);
2494 gtk_tree_path_free (path);
2496 path = gtk_tree_path_new_from_indices (3, -1);
2497 rowref = gtk_tree_row_reference_new (sort, path);
2498 gtk_tree_path_free (path);
2500 /* Deleting a parent */
2501 path = gtk_tree_path_new_from_indices (3, 0, -1);
2502 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
2503 gtk_tree_store_remove (tree, &iter);
2504 gtk_tree_path_free (path);
2506 gtk_tree_row_reference_free (rowref);
2510 specific_ref_leaf_and_remove_ancestor (void)
2512 GtkTreeIter iter, child, child2, child3;
2514 GtkTreeModel *filter;
2516 GtkTreeRowReference *rowref;
2517 GtkWidget *view G_GNUC_UNUSED;
2519 tree = gtk_tree_store_new (1, G_TYPE_INT);
2520 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
2521 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
2522 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
2523 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
2525 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
2526 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
2527 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
2529 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), NULL);
2530 view = gtk_tree_view_new_with_model (filter);
2531 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
2533 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
2534 rowref = gtk_tree_row_reference_new (filter, path);
2535 gtk_tree_path_free (path);
2537 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
2538 rowref = gtk_tree_row_reference_new (filter, path);
2539 gtk_tree_path_free (path);
2541 path = gtk_tree_path_new_from_indices (3, 0, -1);
2542 rowref = gtk_tree_row_reference_new (filter, path);
2543 gtk_tree_path_free (path);
2545 path = gtk_tree_path_new_from_indices (3, -1);
2546 rowref = gtk_tree_row_reference_new (filter, path);
2547 gtk_tree_path_free (path);
2549 /* Deleting a parent */
2550 path = gtk_tree_path_new_from_indices (3, 0, -1);
2551 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
2552 gtk_tree_store_remove (tree, &iter);
2553 gtk_tree_path_free (path);
2555 gtk_tree_row_reference_free (rowref);
2559 specific_virtual_ref_leaf_and_remove_ancestor (void)
2561 GtkTreeIter iter, child, child2, child3;
2563 GtkTreeModel *filter;
2565 GtkTreeRowReference *rowref;
2566 GtkWidget *view G_GNUC_UNUSED;
2568 tree = gtk_tree_store_new (1, G_TYPE_INT);
2569 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
2570 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
2571 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
2572 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
2574 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
2575 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
2576 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
2578 /* Set a virtual root of 3:0 */
2579 path = gtk_tree_path_new_from_indices (3, 0, -1);
2580 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
2581 gtk_tree_path_free (path);
2583 view = gtk_tree_view_new_with_model (filter);
2584 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
2586 path = gtk_tree_path_new_from_indices (0, 0, -1);
2587 rowref = gtk_tree_row_reference_new (filter, path);
2588 gtk_tree_path_free (path);
2590 path = gtk_tree_path_new_from_indices (0, 0, -1);
2591 rowref = gtk_tree_row_reference_new (filter, path);
2592 gtk_tree_path_free (path);
2594 path = gtk_tree_path_new_from_indices (0, -1);
2595 rowref = gtk_tree_row_reference_new (filter, path);
2596 gtk_tree_path_free (path);
2598 /* Deleting the virtual root */
2599 path = gtk_tree_path_new_from_indices (3, 0, -1);
2600 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
2601 gtk_tree_store_remove (tree, &iter);
2602 gtk_tree_path_free (path);
2604 gtk_tree_row_reference_free (rowref);
2609 specific_bug_301558_sort_func (GtkTreeModel *model,
2616 gtk_tree_model_get (model, a, 0, &i, -1);
2617 gtk_tree_model_get (model, b, 0, &j, -1);
2623 specific_bug_301558 (void)
2625 /* Test case for GNOME Bugzilla bug 301558 provided by
2629 GtkTreeModel *filter;
2631 GtkTreeIter root, iter, iter2;
2632 GtkWidget *view G_GNUC_UNUSED;
2636 g_test_bug ("301558");
2638 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
2639 gtk_tree_store_append (tree, &iter, NULL);
2640 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
2641 gtk_tree_store_append (tree, &iter2, &iter);
2642 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
2644 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
2645 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
2646 specific_bug_301558_sort_func,
2649 filter = gtk_tree_model_filter_new (sort, NULL);
2650 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
2652 view = gtk_tree_view_new_with_model (filter);
2654 while (gtk_events_pending ())
2655 gtk_main_iteration ();
2659 for (i = 0; i < 10; i++)
2661 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
2662 g_assert_not_reached ();
2666 gtk_tree_store_append (tree, &iter, &root);
2667 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
2672 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
2673 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
2675 gtk_tree_store_remove (tree, &iter);
2684 specific_bug_311955_filter_func (GtkTreeModel *model,
2690 gtk_tree_model_get (model, iter, 0, &value, -1);
2692 return (value != 0);
2696 specific_bug_311955 (void)
2698 /* This is a test case for GNOME Bugzilla bug 311955. It was written
2701 GtkTreeIter iter, child, root;
2702 GtkTreeStore *store;
2704 GtkTreeModel *filter;
2706 GtkWidget *window G_GNUC_UNUSED;
2707 GtkWidget *tree_view;
2711 g_test_bug ("311955");
2713 store = gtk_tree_store_new (1, G_TYPE_INT);
2715 gtk_tree_store_append (store, &root, NULL);
2716 gtk_tree_store_set (store, &root, 0, 33, -1);
2718 gtk_tree_store_append (store, &iter, &root);
2719 gtk_tree_store_set (store, &iter, 0, 50, -1);
2721 gtk_tree_store_append (store, &iter, NULL);
2722 gtk_tree_store_set (store, &iter, 0, 22, -1);
2724 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
2725 filter = gtk_tree_model_filter_new (sort, NULL);
2727 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2728 specific_bug_311955_filter_func,
2731 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2732 tree_view = gtk_tree_view_new_with_model (filter);
2733 g_object_unref (store);
2735 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2737 while (gtk_events_pending ())
2738 gtk_main_iteration ();
2741 for (i = 0; i < 4; i++)
2743 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2745 gtk_tree_store_append (store, &iter, &root);
2748 gtk_tree_store_set (store, &iter, 0, i, -1);
2752 gtk_tree_store_append (store, &child, &iter);
2753 gtk_tree_store_set (store, &child, 0, 10, -1);
2757 while (gtk_events_pending ())
2758 gtk_main_iteration ();
2760 /* Remove bottommost child from the tree. */
2761 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
2762 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
2764 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
2766 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
2767 gtk_tree_store_remove (store, &child);
2770 g_assert_not_reached ();
2774 specific_bug_346800 (void)
2776 /* This is a test case for GNOME Bugzilla bug 346800. It was written
2777 * by Jonathan Matthew.
2780 GtkTreeIter node_iters[50];
2781 GtkTreeIter child_iters[50];
2782 GtkTreeModel *model;
2783 GtkTreeModelFilter *filter;
2784 GtkTreeStore *store;
2788 columns = g_new (GType, 2);
2789 columns[0] = G_TYPE_STRING;
2790 columns[1] = G_TYPE_BOOLEAN;
2791 store = gtk_tree_store_newv (2, columns);
2792 model = GTK_TREE_MODEL (store);
2794 g_test_bug ("346800");
2796 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
2797 gtk_tree_model_filter_set_visible_column (filter, 1);
2799 for (i=0; i<items; i++)
2801 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
2804 gtk_tree_store_append (store, &node_iters[i], NULL);
2805 gtk_tree_store_set (store, &node_iters[i],
2807 1, ((i%6) == 0) ? FALSE : TRUE,
2811 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
2812 gtk_tree_store_set (store, &child_iters[i],
2813 0, "something else",
2816 gtk_tree_model_filter_refilter (filter);
2820 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
2821 (i & 1) ? TRUE : FALSE, -1);
2822 gtk_tree_model_filter_refilter (filter);
2824 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
2825 (i & 1) ? FALSE: TRUE, -1);
2826 gtk_tree_model_filter_refilter (filter);
2832 specific_bug_464173_visible_func (GtkTreeModel *model,
2836 gboolean *visible = (gboolean *)data;
2842 specific_bug_464173 (void)
2844 /* Test case for GNOME Bugzilla bug 464173, test case written
2845 * by Andreas Koehler.
2847 GtkTreeStore *model;
2848 GtkTreeModelFilter *f_model;
2849 GtkTreeIter iter1, iter2;
2850 GtkWidget *view G_GNUC_UNUSED;
2851 gboolean visible = TRUE;
2853 g_test_bug ("464173");
2855 model = gtk_tree_store_new (1, G_TYPE_STRING);
2856 gtk_tree_store_append (model, &iter1, NULL);
2857 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
2858 gtk_tree_store_append (model, &iter2, &iter1);
2859 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
2861 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
2862 gtk_tree_model_filter_set_visible_func (f_model,
2863 specific_bug_464173_visible_func,
2866 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
2869 gtk_tree_model_filter_refilter (f_model);
2874 specific_bug_540201_filter_func (GtkTreeModel *model,
2878 gboolean has_children;
2880 has_children = gtk_tree_model_iter_has_child (model, iter);
2882 return has_children;
2886 specific_bug_540201 (void)
2888 /* Test case for GNOME Bugzilla bug 540201, steps provided by
2891 GtkTreeIter iter, root;
2892 GtkTreeStore *store;
2893 GtkTreeModel *filter;
2895 GtkWidget *tree_view G_GNUC_UNUSED;
2897 g_test_bug ("540201");
2899 store = gtk_tree_store_new (1, G_TYPE_INT);
2901 gtk_tree_store_append (store, &root, NULL);
2902 gtk_tree_store_set (store, &root, 0, 33, -1);
2904 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2905 tree_view = gtk_tree_view_new_with_model (filter);
2907 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
2908 specific_bug_540201_filter_func,
2911 gtk_tree_store_append (store, &iter, &root);
2912 gtk_tree_store_set (store, &iter, 0, 50, -1);
2914 gtk_tree_store_append (store, &iter, &root);
2915 gtk_tree_store_set (store, &iter, 0, 22, -1);
2918 gtk_tree_store_append (store, &root, NULL);
2919 gtk_tree_store_set (store, &root, 0, 33, -1);
2921 gtk_tree_store_append (store, &iter, &root);
2922 gtk_tree_store_set (store, &iter, 0, 22, -1);
2927 specific_bug_549287_visible_func (GtkTreeModel *model,
2931 gboolean result = FALSE;
2933 result = gtk_tree_model_iter_has_child (model, iter);
2939 specific_bug_549287 (void)
2941 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
2944 GtkTreeStore *store;
2945 GtkTreeModel *filtered;
2946 GtkWidget *view G_GNUC_UNUSED;
2948 GtkTreeIter *swap, *parent, *child;
2950 g_test_bug ("529287");
2952 store = gtk_tree_store_new (1, G_TYPE_STRING);
2953 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2954 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
2955 specific_bug_549287_visible_func,
2958 view = gtk_tree_view_new_with_model (filtered);
2960 for (i = 0; i < 4; i++)
2962 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
2964 parent = gtk_tree_iter_copy (&iter);
2965 child = gtk_tree_iter_copy (&iter);
2967 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
2976 gtk_tree_store_append (store, child, parent);
2977 gtk_tree_store_set (store, child,
2981 gtk_tree_iter_free (parent);
2982 gtk_tree_iter_free (child);
2986 gtk_tree_store_append (store, &iter, NULL);
2987 gtk_tree_store_set (store, &iter,
2992 /* since we inserted something, we changed the visibility conditions: */
2993 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
3000 register_filter_model_tests (void)
3002 g_test_add ("/TreeModelFilter/self/verify-test-suite",
3006 filter_test_teardown);
3008 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-1",
3009 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3011 verify_test_suite_vroot,
3012 filter_test_teardown);
3013 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-2",
3014 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
3016 verify_test_suite_vroot,
3017 filter_test_teardown);
3020 g_test_add ("/TreeModelFilter/filled/hide-root-level",
3023 filled_hide_root_level,
3024 filter_test_teardown);
3025 g_test_add ("/TreeModelFilter/filled/hide-child-levels",
3028 filled_hide_child_levels,
3029 filter_test_teardown);
3031 g_test_add ("/TreeModelFilter/filled/hide-root-level/vroot",
3032 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3034 filled_vroot_hide_root_level,
3035 filter_test_teardown);
3036 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot",
3037 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3039 filled_vroot_hide_child_levels,
3040 filter_test_teardown);
3043 g_test_add ("/TreeModelFilter/empty/show-nodes",
3045 filter_test_setup_empty,
3047 filter_test_teardown);
3048 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes",
3050 filter_test_setup_empty,
3051 empty_show_multiple_nodes,
3052 filter_test_teardown);
3054 g_test_add ("/TreeModelFilter/empty/show-nodes/vroot",
3055 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3056 filter_test_setup_empty,
3057 empty_vroot_show_nodes,
3058 filter_test_teardown);
3059 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes/vroot",
3060 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3061 filter_test_setup_empty,
3062 empty_vroot_show_multiple_nodes,
3063 filter_test_teardown);
3066 g_test_add ("/TreeModelFilter/unfiltered/hide-single",
3068 filter_test_setup_unfiltered,
3069 unfiltered_hide_single,
3070 filter_test_teardown);
3071 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child",
3073 filter_test_setup_unfiltered,
3074 unfiltered_hide_single_child,
3075 filter_test_teardown);
3076 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level",
3078 filter_test_setup_unfiltered,
3079 unfiltered_hide_single_multi_level,
3080 filter_test_teardown);
3082 g_test_add ("/TreeModelFilter/unfiltered/hide-single/vroot",
3083 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3084 filter_test_setup_unfiltered,
3085 unfiltered_vroot_hide_single,
3086 filter_test_teardown);
3087 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot",
3088 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3089 filter_test_setup_unfiltered,
3090 unfiltered_vroot_hide_single_child,
3091 filter_test_teardown);
3092 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot",
3093 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3094 filter_test_setup_unfiltered,
3095 unfiltered_vroot_hide_single_multi_level,
3096 filter_test_teardown);
3100 g_test_add ("/TreeModelFilter/unfiltered/show-single",
3102 filter_test_setup_empty_unfiltered,
3103 unfiltered_show_single,
3104 filter_test_teardown);
3105 g_test_add ("/TreeModelFilter/unfiltered/show-single-child",
3107 filter_test_setup_empty_unfiltered,
3108 unfiltered_show_single_child,
3109 filter_test_teardown);
3110 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level",
3112 filter_test_setup_empty_unfiltered,
3113 unfiltered_show_single_multi_level,
3114 filter_test_teardown);
3116 g_test_add ("/TreeModelFilter/unfiltered/show-single/vroot",
3117 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3118 filter_test_setup_empty_unfiltered,
3119 unfiltered_vroot_show_single,
3120 filter_test_teardown);
3121 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot",
3122 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3123 filter_test_setup_empty_unfiltered,
3124 unfiltered_vroot_show_single_child,
3125 filter_test_teardown);
3126 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot",
3127 FilterTest, gtk_tree_path_new_from_indices (2, -1),
3128 filter_test_setup_empty_unfiltered,
3129 unfiltered_vroot_show_single_multi_level,
3130 filter_test_teardown);
3132 g_test_add_func ("/TreeModelFilter/specific/remove-node",
3133 specific_remove_node);
3134 g_test_add_func ("/TreeModelFilter/specific/remove-node-vroot",
3135 specific_remove_node_vroot);
3136 g_test_add_func ("/TreeModelFilter/specific/remove-vroot-ancestor",
3137 specific_remove_vroot_ancestor);
3139 g_test_add_func ("/TreeModelFilter/specific/path-dependent-filter",
3140 specific_path_dependent_filter);
3141 g_test_add_func ("/TreeModelFilter/specific/append-after-collapse",
3142 specific_append_after_collapse);
3143 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-node",
3144 specific_sort_filter_remove_node);
3145 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-root",
3146 specific_sort_filter_remove_root);
3147 g_test_add_func ("/TreeModelFilter/specific/root-mixed-visibility",
3148 specific_root_mixed_visibility);
3149 g_test_add_func ("/TreeModelFilter/specific/has-child-filter",
3150 specific_has_child_filter);
3151 g_test_add_func ("/TreeModelFilter/specific/root-has-child-filter",
3152 specific_root_has_child_filter);
3153 g_test_add_func ("/TreeModelFilter/specific/filter-add-child",
3154 specific_filter_add_child);
3155 g_test_add_func ("/TreeModelFilter/specific/list-store-clear",
3156 specific_list_store_clear);
3157 g_test_add_func ("/TreeModelFilter/specific/sort-ref-leaf-and-remove-ancestor",
3158 specific_sort_ref_leaf_and_remove_ancestor);
3159 g_test_add_func ("/TreeModelFilter/specific/ref-leaf-and-remove-ancestor",
3160 specific_ref_leaf_and_remove_ancestor);
3161 g_test_add_func ("/TreeModelFilter/specific/virtual-ref-leaf-and-remove-ancestor",
3162 specific_virtual_ref_leaf_and_remove_ancestor);
3164 g_test_add_func ("/TreeModelFilter/specific/bug-301558",
3165 specific_bug_301558);
3166 g_test_add_func ("/TreeModelFilter/specific/bug-311955",
3167 specific_bug_311955);
3168 g_test_add_func ("/TreeModelFilter/specific/bug-346800",
3169 specific_bug_346800);
3170 g_test_add_func ("/TreeModelFilter/specific/bug-464173",
3171 specific_bug_464173);
3172 g_test_add_func ("/TreeModelFilter/specific/bug-540201",
3173 specific_bug_540201);
3174 g_test_add_func ("/TreeModelFilter/specific/bug-549287",
3175 specific_bug_549287);