1 /* Extensive GtkTreeModelFilter tests.
2 * Copyright (C) 2009,2011 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.
22 #include "treemodel.h"
23 #include "gtktreemodelrefcount.h"
26 * - Proper coverage checking to see if the unit tests cover
28 * - Check if the iterator stamp is incremented at the correct times.
30 * For more thorough testing:
31 * - Test with randomized models.
32 * - Extensively test a filter model wrapping a sort model,
33 * or a sort model wrapping a filter model by:
34 * # Checking structure.
35 * # Checking for correct signals emissions.
36 * # Checking correct reference counting.
37 * # Tests should be done with the sort and filter model
38 * in various filtering and sorting states.
46 #define LEVEL_LENGTH 5
49 create_tree_store_set_values (GtkTreeStore *store,
56 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
57 path_string = gtk_tree_path_to_string (path);
59 gtk_tree_store_set (store, iter,
64 gtk_tree_path_free (path);
69 create_tree_store_recurse (int depth,
76 for (i = 0; i < LEVEL_LENGTH; i++)
80 gtk_tree_store_insert (store, &iter, parent, i);
81 create_tree_store_set_values (store, &iter, visible);
84 create_tree_store_recurse (depth - 1, store, &iter, visible);
89 create_tree_store (int depth,
94 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
96 create_tree_store_recurse (depth, store, NULL, visible);
107 GtkWidget *tree_view;
110 GtkTreeModelFilter *filter;
112 SignalMonitor *monitor;
114 guint block_signals : 1;
119 filter_test_store_signal (FilterTest *fixture)
121 if (fixture->block_signals)
122 g_signal_stop_emission_by_name (fixture->store, "row-changed");
127 filter_test_setup_generic (FilterTest *fixture,
128 gconstpointer test_data,
133 const GtkTreePath *vroot = test_data;
134 GtkTreeModel *filter;
136 fixture->store = create_tree_store (depth, !empty);
138 g_signal_connect_swapped (fixture->store, "row-changed",
139 G_CALLBACK (filter_test_store_signal), fixture);
141 /* Please forgive me for casting const away. */
142 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store),
143 (GtkTreePath *)vroot);
144 fixture->filter = GTK_TREE_MODEL_FILTER (filter);
147 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
149 /* We need a tree view that's listening to get ref counting from that
152 fixture->tree_view = gtk_tree_view_new_with_model (filter);
154 fixture->monitor = signal_monitor_new (filter);
158 filter_test_setup_expand_root (FilterTest *fixture)
163 path = gtk_tree_path_new_from_indices (0, -1);
165 for (i = 0; i < LEVEL_LENGTH; i++)
167 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view),
169 gtk_tree_path_next (path);
171 gtk_tree_path_free (path);
175 filter_test_setup (FilterTest *fixture,
176 gconstpointer test_data)
178 filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE);
182 filter_test_setup_empty (FilterTest *fixture,
183 gconstpointer test_data)
185 filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE);
189 filter_test_setup_unfiltered (FilterTest *fixture,
190 gconstpointer test_data)
192 filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE);
196 filter_test_setup_unfiltered_root_expanded (FilterTest *fixture,
197 gconstpointer test_data)
199 filter_test_setup_unfiltered (fixture, test_data);
200 filter_test_setup_expand_root (fixture);
204 filter_test_setup_empty_unfiltered (FilterTest *fixture,
205 gconstpointer test_data)
207 filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
211 filter_test_setup_empty_unfiltered_root_expanded (FilterTest *fixture,
212 gconstpointer test_data)
214 filter_test_setup_empty_unfiltered (fixture, test_data);
215 filter_test_setup_expand_root (fixture);
219 strip_virtual_root (GtkTreePath *path,
220 GtkTreePath *root_path)
222 GtkTreePath *real_path;
227 int depth = gtk_tree_path_get_depth (path);
228 int root_depth = gtk_tree_path_get_depth (root_path);
230 real_path = gtk_tree_path_new ();
232 for (j = 0; j < depth - root_depth; j++)
233 gtk_tree_path_append_index (real_path,
234 gtk_tree_path_get_indices (path)[root_depth + j]);
237 real_path = gtk_tree_path_copy (path);
243 count_visible (FilterTest *fixture,
244 GtkTreePath *store_path)
250 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
253 for (i = 0; i < LEVEL_LENGTH; i++)
257 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
269 filter_test_append_refilter_signals_recurse (FilterTest *fixture,
270 GtkTreePath *store_path,
271 GtkTreePath *filter_path,
273 GtkTreePath *root_path)
276 int rows_deleted = 0;
279 gtk_tree_path_down (store_path);
280 gtk_tree_path_down (filter_path);
282 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
285 for (i = 0; i < LEVEL_LENGTH; i++)
288 GtkTreePath *real_path;
290 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
295 (!gtk_tree_path_is_descendant (store_path, root_path)
296 || !gtk_tree_path_compare (store_path, root_path)))
298 if (!gtk_tree_path_compare (store_path, root_path))
301 && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
304 GtkTreePath *store_copy;
305 GtkTreePath *filter_copy;
307 store_copy = gtk_tree_path_copy (store_path);
308 filter_copy = gtk_tree_path_copy (filter_path);
309 filter_test_append_refilter_signals_recurse (fixture,
314 gtk_tree_path_free (store_copy);
315 gtk_tree_path_free (filter_copy);
319 gtk_tree_path_next (store_path);
320 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
323 gtk_tree_path_next (filter_path);
328 real_path = strip_virtual_root (filter_path, root_path);
332 /* This row will be inserted */
333 signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
336 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
339 signal_monitor_append_signal_path (fixture->monitor,
340 ROW_HAS_CHILD_TOGGLED,
345 GtkTreePath *store_copy;
346 GtkTreePath *filter_copy;
348 store_copy = gtk_tree_path_copy (store_path);
349 filter_copy = gtk_tree_path_copy (filter_path);
350 filter_test_append_refilter_signals_recurse (fixture,
355 gtk_tree_path_free (store_copy);
356 gtk_tree_path_free (filter_copy);
360 GtkTreePath *tmp_path;
362 /* If all child rows are invisible, then the last row to
363 * become invisible will emit row-has-child-toggled on the
367 tmp_path = gtk_tree_path_copy (store_path);
368 gtk_tree_path_append_index (tmp_path, 0);
370 if (count_visible (fixture, tmp_path) == 0)
371 signal_monitor_append_signal_path (fixture->monitor,
372 ROW_HAS_CHILD_TOGGLED,
375 gtk_tree_path_free (tmp_path);
379 gtk_tree_path_next (filter_path);
383 /* This row will be deleted */
385 signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
389 gtk_tree_path_free (real_path);
391 gtk_tree_path_next (store_path);
392 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
395 if (rows_deleted == LEVEL_LENGTH
396 && gtk_tree_path_get_depth (filter_path) > 1)
398 GtkTreePath *real_path;
400 gtk_tree_path_up (store_path);
401 gtk_tree_path_up (filter_path);
403 /* A row-has-child-toggled will be emitted on the parent */
406 && gtk_tree_path_is_descendant (store_path, root_path)
407 && gtk_tree_path_compare (store_path, root_path)))
409 real_path = strip_virtual_root (filter_path, root_path);
410 signal_monitor_append_signal_path (fixture->monitor,
411 ROW_HAS_CHILD_TOGGLED,
414 gtk_tree_path_free (real_path);
420 filter_test_append_refilter_signals (FilterTest *fixture,
423 /* A special function that walks the tree store like the
424 * model validation functions below.
427 GtkTreePath *filter_path;
429 path = gtk_tree_path_new ();
430 filter_path = gtk_tree_path_new ();
431 filter_test_append_refilter_signals_recurse (fixture,
436 gtk_tree_path_free (path);
437 gtk_tree_path_free (filter_path);
441 filter_test_append_refilter_signals_with_vroot (FilterTest *fixture,
443 GtkTreePath *root_path)
445 /* A special function that walks the tree store like the
446 * model validation functions below.
449 GtkTreePath *filter_path;
451 path = gtk_tree_path_new ();
452 filter_path = gtk_tree_path_new ();
453 filter_test_append_refilter_signals_recurse (fixture,
458 gtk_tree_path_free (path);
459 gtk_tree_path_free (filter_path);
463 filter_test_enable_filter (FilterTest *fixture)
465 gtk_tree_model_filter_set_visible_column (fixture->filter, 1);
466 gtk_tree_model_filter_refilter (fixture->filter);
470 filter_test_block_signals (FilterTest *fixture)
472 fixture->block_signals = TRUE;
476 filter_test_unblock_signals (FilterTest *fixture)
478 fixture->block_signals = FALSE;
482 filter_test_teardown (FilterTest *fixture,
483 gconstpointer test_data)
485 signal_monitor_free (fixture->monitor);
487 gtk_widget_destroy (fixture->tree_view);
489 g_object_unref (fixture->filter);
490 g_object_unref (fixture->store);
494 * Model structure validation
498 check_filter_model_recurse (FilterTest *fixture,
499 GtkTreePath *store_parent_path,
500 GtkTreePath *filter_parent_path)
503 GtkTreeIter store_iter;
504 GtkTreeIter filter_iter;
505 gboolean store_has_next, filter_has_next;
507 gtk_tree_path_down (store_parent_path);
508 gtk_tree_path_down (filter_parent_path);
510 store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
511 &store_iter, store_parent_path);
512 filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter),
513 &filter_iter, filter_parent_path);
515 for (i = 0; i < LEVEL_LENGTH; i++)
519 g_return_if_fail (store_has_next == TRUE);
521 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
529 gchar *filter_str, *store_str;
531 g_return_if_fail (filter_has_next == TRUE);
534 tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter),
536 g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0);
538 /* Verify model content */
539 gtk_tree_model_get (GTK_TREE_MODEL (fixture->store),
543 gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter),
548 g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0);
553 if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter),
556 g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter));
558 check_filter_model_recurse (fixture,
559 gtk_tree_path_copy (store_parent_path),
563 /* Only when we do not recurse we need to free tmp */
564 gtk_tree_path_free (tmp);
566 gtk_tree_path_next (filter_parent_path);
567 filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter);
570 gtk_tree_path_next (store_parent_path);
571 store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter);
574 /* Both models should have no more content! */
575 g_return_if_fail (store_has_next == FALSE);
576 g_return_if_fail (filter_has_next == FALSE);
578 gtk_tree_path_free (store_parent_path);
579 gtk_tree_path_free (filter_parent_path);
583 check_filter_model (FilterTest *fixture)
587 if (fixture->monitor)
588 signal_monitor_assert_is_empty (fixture->monitor);
590 path = gtk_tree_path_new ();
592 check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
596 check_filter_model_with_root (FilterTest *fixture,
599 if (fixture->monitor)
600 signal_monitor_assert_is_empty (fixture->monitor);
602 check_filter_model_recurse (fixture,
603 gtk_tree_path_copy (path),
604 gtk_tree_path_new ());
610 check_level_length (GtkTreeModelFilter *filter,
612 const int expected_length)
618 model_length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL);
619 g_assert_cmpint (model_length, ==, expected_length);
624 gboolean retrieved_iter = FALSE;
627 retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter),
629 g_return_if_fail (retrieved_iter);
630 model_length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter);
631 g_assert_cmpint (model_length, ==, expected_length);
636 set_path_visibility (FilterTest *fixture,
640 GtkTreeIter store_iter;
642 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
644 gtk_tree_store_set (fixture->store, &store_iter,
651 insert_path_with_visibility (FilterTest *fixture,
652 const gchar *path_string,
657 GtkTreeIter parent, iter;
659 path = gtk_tree_path_new_from_string (path_string);
660 position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)];
661 gtk_tree_path_up (path);
663 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path))
665 gtk_tree_store_insert (fixture->store, &iter, &parent, position);
666 create_tree_store_set_values (fixture->store, &iter, visible);
668 gtk_tree_path_free (path);
677 verify_test_suite (FilterTest *fixture,
678 gconstpointer user_data)
680 check_filter_model (fixture);
684 verify_test_suite_vroot (FilterTest *fixture,
685 gconstpointer user_data)
687 check_filter_model_with_root (fixture, (GtkTreePath *)user_data);
692 filled_hide_root_level (FilterTest *fixture,
693 gconstpointer user_data)
695 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
696 set_path_visibility (fixture, "2", FALSE);
697 check_filter_model (fixture);
698 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
700 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
701 set_path_visibility (fixture, "0", FALSE);
702 check_filter_model (fixture);
703 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
705 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
706 set_path_visibility (fixture, "4", FALSE);
707 check_filter_model (fixture);
708 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
712 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
713 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
715 set_path_visibility (fixture, "1", FALSE);
716 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
718 set_path_visibility (fixture, "3", FALSE);
719 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5);
721 check_filter_model (fixture);
724 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
725 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
726 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
727 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
729 set_path_visibility (fixture, "1", TRUE);
730 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
732 set_path_visibility (fixture, "3", TRUE);
733 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
735 check_filter_model (fixture);
739 filled_hide_child_levels (FilterTest *fixture,
740 gconstpointer user_data)
742 set_path_visibility (fixture, "0:2", FALSE);
743 check_filter_model (fixture);
744 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
745 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
747 set_path_visibility (fixture, "0:4", FALSE);
748 check_filter_model (fixture);
749 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
750 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
752 set_path_visibility (fixture, "0:4:3", FALSE);
753 check_filter_model (fixture);
754 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
755 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
757 set_path_visibility (fixture, "0:4:0", FALSE);
758 set_path_visibility (fixture, "0:4:1", FALSE);
759 set_path_visibility (fixture, "0:4:2", FALSE);
760 set_path_visibility (fixture, "0:4:4", FALSE);
761 check_filter_model (fixture);
762 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
763 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
765 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
766 set_path_visibility (fixture, "0:4", TRUE);
767 check_filter_model (fixture);
768 check_level_length (fixture->filter, "0:3", 0);
770 set_path_visibility (fixture, "0:2", TRUE);
771 check_filter_model (fixture);
772 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
773 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
774 check_level_length (fixture->filter, "0:4", 0);
776 /* Once 0:4:0 got inserted, 0:4 became a parent. Because 0:4 is
777 * not visible, not signals are emitted.
779 set_path_visibility (fixture, "0:4:2", TRUE);
780 set_path_visibility (fixture, "0:4:4", TRUE);
781 signal_monitor_assert_is_empty (fixture->monitor);
782 check_level_length (fixture->filter, "0:4", 2);
786 filled_hide_child_levels_root_expanded (FilterTest *fixture,
787 gconstpointer user_data)
791 path = gtk_tree_path_new_from_indices (0, -1);
792 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
793 gtk_tree_path_free (path);
795 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
796 set_path_visibility (fixture, "0:2", FALSE);
797 check_filter_model (fixture);
798 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
799 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
801 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
802 set_path_visibility (fixture, "0:4", FALSE);
803 check_filter_model (fixture);
804 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
805 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
807 set_path_visibility (fixture, "0:4:3", FALSE);
808 check_filter_model (fixture);
809 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
810 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
812 set_path_visibility (fixture, "0:4:0", FALSE);
813 set_path_visibility (fixture, "0:4:1", FALSE);
814 set_path_visibility (fixture, "0:4:2", FALSE);
815 set_path_visibility (fixture, "0:4:4", FALSE);
816 check_filter_model (fixture);
817 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
818 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
820 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
821 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
822 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
823 set_path_visibility (fixture, "0:4", TRUE);
824 check_filter_model (fixture);
825 check_level_length (fixture->filter, "0:3", 0);
827 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
828 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
829 set_path_visibility (fixture, "0:2", TRUE);
830 check_filter_model (fixture);
831 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
832 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
833 check_level_length (fixture->filter, "0:4", 0);
835 /* has-child-toggled for 0:4 is required. */
836 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
837 set_path_visibility (fixture, "0:4:2", TRUE);
838 set_path_visibility (fixture, "0:4:4", TRUE);
839 signal_monitor_assert_is_empty (fixture->monitor);
840 check_level_length (fixture->filter, "0:4", 2);
845 filled_vroot_hide_root_level (FilterTest *fixture,
846 gconstpointer user_data)
848 GtkTreePath *path = (GtkTreePath *)user_data;
850 /* These changes do not affect the filter's root level */
851 set_path_visibility (fixture, "0", FALSE);
852 check_filter_model_with_root (fixture, path);
853 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
854 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
856 set_path_visibility (fixture, "4", FALSE);
857 check_filter_model_with_root (fixture, path);
858 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
859 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
861 /* Even though we set the virtual root parent node to FALSE,
862 * the virtual root contents remain.
864 set_path_visibility (fixture, "2", FALSE);
865 check_filter_model_with_root (fixture, path);
866 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
867 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
870 set_path_visibility (fixture, "1", FALSE);
871 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
872 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
874 set_path_visibility (fixture, "3", FALSE);
875 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
876 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
878 check_filter_model_with_root (fixture, path);
881 set_path_visibility (fixture, "2", TRUE);
882 check_filter_model_with_root (fixture, path);
883 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
884 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
886 set_path_visibility (fixture, "1", TRUE);
887 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
888 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
890 set_path_visibility (fixture, "3", TRUE);
891 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
892 check_level_length (fixture->filter, "0", LEVEL_LENGTH);
894 check_filter_model_with_root (fixture, path);
896 /* Now test changes in the virtual root level */
897 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
898 set_path_visibility (fixture, "2:2", FALSE);
899 check_filter_model_with_root (fixture, path);
900 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
902 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
903 set_path_visibility (fixture, "2:4", FALSE);
904 check_filter_model_with_root (fixture, path);
905 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
907 set_path_visibility (fixture, "1:4", FALSE);
908 check_filter_model_with_root (fixture, path);
909 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
911 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
912 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
913 set_path_visibility (fixture, "2:4", TRUE);
914 check_filter_model_with_root (fixture, path);
915 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
917 set_path_visibility (fixture, "2", FALSE);
918 check_filter_model_with_root (fixture, path);
919 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
921 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
922 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
923 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
924 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
925 set_path_visibility (fixture, "2:0", FALSE);
926 set_path_visibility (fixture, "2:1", FALSE);
927 set_path_visibility (fixture, "2:2", FALSE);
928 set_path_visibility (fixture, "2:3", FALSE);
929 set_path_visibility (fixture, "2:4", FALSE);
930 check_filter_model_with_root (fixture, path);
931 check_level_length (fixture->filter, NULL, 0);
933 set_path_visibility (fixture, "2", TRUE);
934 check_filter_model_with_root (fixture, path);
935 check_level_length (fixture->filter, NULL, 0);
937 set_path_visibility (fixture, "1:4", FALSE);
938 check_filter_model_with_root (fixture, path);
939 check_level_length (fixture->filter, NULL, 0);
941 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
942 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
943 set_path_visibility (fixture, "2:4", TRUE);
944 check_filter_model_with_root (fixture, path);
945 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
947 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
948 set_path_visibility (fixture, "2:4", FALSE);
949 check_filter_model_with_root (fixture, path);
950 check_level_length (fixture->filter, NULL, 0);
952 set_path_visibility (fixture, "2", FALSE);
953 check_filter_model_with_root (fixture, path);
954 check_level_length (fixture->filter, NULL, 0);
956 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
957 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
958 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
959 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
960 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
961 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
962 set_path_visibility (fixture, "2:0", TRUE);
963 set_path_visibility (fixture, "2:1", TRUE);
964 set_path_visibility (fixture, "2:2", TRUE);
965 check_filter_model_with_root (fixture, path);
966 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
968 set_path_visibility (fixture, "2", TRUE);
969 check_filter_model_with_root (fixture, path);
970 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
974 filled_vroot_hide_child_levels (FilterTest *fixture,
975 gconstpointer user_data)
977 GtkTreePath *path = (GtkTreePath *)user_data;
979 set_path_visibility (fixture, "2:0:2", FALSE);
980 check_filter_model_with_root (fixture, path);
981 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
982 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
984 set_path_visibility (fixture, "2:0:4", FALSE);
985 check_filter_model_with_root (fixture, path);
986 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
987 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
989 set_path_visibility (fixture, "2:0:4:3", 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 - 2);
994 set_path_visibility (fixture, "2:0:4:0", FALSE);
995 set_path_visibility (fixture, "2:0:4:1", FALSE);
996 set_path_visibility (fixture, "2:0:4:2", FALSE);
997 set_path_visibility (fixture, "2:0:4:4", FALSE);
998 check_filter_model_with_root (fixture, path);
999 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1000 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1002 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1003 set_path_visibility (fixture, "2:0:4", TRUE);
1004 check_filter_model_with_root (fixture, path);
1005 check_level_length (fixture->filter, "0:3", 0);
1007 set_path_visibility (fixture, "2:0:2", TRUE);
1008 check_filter_model_with_root (fixture, path);
1009 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1010 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1011 check_level_length (fixture->filter, "0:4", 0);
1013 /* Once 0:4:0 got inserted, 0:4 became a parent */
1014 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1015 set_path_visibility (fixture, "2:0:4:2", TRUE);
1016 set_path_visibility (fixture, "2:0:4:4", TRUE);
1017 check_level_length (fixture->filter, "0:4", 2);
1021 filled_vroot_hide_child_levels_root_expanded (FilterTest *fixture,
1022 gconstpointer user_data)
1024 GtkTreePath *path = (GtkTreePath *)user_data;
1025 GtkTreePath *tmp_path;
1027 tmp_path = gtk_tree_path_new_from_indices (0, -1);
1028 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), tmp_path, FALSE);
1029 gtk_tree_path_free (tmp_path);
1031 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
1032 set_path_visibility (fixture, "2:0:2", FALSE);
1033 check_filter_model_with_root (fixture, path);
1034 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1035 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
1037 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
1038 set_path_visibility (fixture, "2:0:4", FALSE);
1039 check_filter_model_with_root (fixture, path);
1040 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1041 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1043 set_path_visibility (fixture, "2:0:4:3", FALSE);
1044 check_filter_model_with_root (fixture, path);
1045 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1046 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1048 set_path_visibility (fixture, "2:0:4:0", FALSE);
1049 set_path_visibility (fixture, "2:0:4:1", FALSE);
1050 set_path_visibility (fixture, "2:0:4:2", FALSE);
1051 set_path_visibility (fixture, "2:0:4:4", FALSE);
1052 check_filter_model_with_root (fixture, path);
1053 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1054 check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
1056 /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
1057 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
1058 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
1059 set_path_visibility (fixture, "2:0:4", TRUE);
1060 check_filter_model_with_root (fixture, path);
1061 check_level_length (fixture->filter, "0:3", 0);
1063 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
1064 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
1065 set_path_visibility (fixture, "2:0:2", TRUE);
1066 check_filter_model_with_root (fixture, path);
1067 check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
1068 check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
1069 check_level_length (fixture->filter, "0:4", 0);
1071 /* Once 0:4:0 got inserted, 0:4 became a parent */
1072 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4");
1073 set_path_visibility (fixture, "2:0:4:2", TRUE);
1074 set_path_visibility (fixture, "2:0:4:4", TRUE);
1075 check_level_length (fixture->filter, "0:4", 2);
1079 empty_show_nodes (FilterTest *fixture,
1080 gconstpointer user_data)
1082 check_filter_model (fixture);
1083 check_level_length (fixture->filter, NULL, 0);
1085 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1086 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1087 set_path_visibility (fixture, "3", TRUE);
1088 check_filter_model (fixture);
1089 check_level_length (fixture->filter, NULL, 1);
1090 check_level_length (fixture->filter, "0", 0);
1092 set_path_visibility (fixture, "3:2:2", TRUE);
1093 check_filter_model (fixture);
1094 check_level_length (fixture->filter, NULL, 1);
1095 check_level_length (fixture->filter, "0", 0);
1097 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1098 set_path_visibility (fixture, "3:2", TRUE);
1099 check_filter_model (fixture);
1100 check_level_length (fixture->filter, NULL, 1);
1101 check_level_length (fixture->filter, "0", 1);
1102 check_level_length (fixture->filter, "0:0", 1);
1103 check_level_length (fixture->filter, "0:0:0", 0);
1105 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1106 set_path_visibility (fixture, "3", FALSE);
1107 check_filter_model (fixture);
1108 check_level_length (fixture->filter, NULL, 0);
1110 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1111 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1112 set_path_visibility (fixture, "3:2:1", TRUE);
1113 set_path_visibility (fixture, "3", TRUE);
1114 check_filter_model (fixture);
1115 check_level_length (fixture->filter, NULL, 1);
1116 check_level_length (fixture->filter, "0", 1);
1117 check_level_length (fixture->filter, "0:0", 2);
1118 check_level_length (fixture->filter, "0:0:0", 0);
1122 empty_show_multiple_nodes (FilterTest *fixture,
1123 gconstpointer user_data)
1126 GtkTreePath *changed_path;
1128 check_filter_model (fixture);
1129 check_level_length (fixture->filter, NULL, 0);
1131 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1132 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1133 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1134 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1136 /* We simulate a change in visible func condition with this. The
1137 * visibility state of multiple nodes changes at once, we emit row-changed
1138 * for these nodes (and others) after that.
1140 filter_test_block_signals (fixture);
1141 set_path_visibility (fixture, "3", TRUE);
1142 set_path_visibility (fixture, "4", TRUE);
1143 filter_test_unblock_signals (fixture);
1145 changed_path = gtk_tree_path_new ();
1146 gtk_tree_path_append_index (changed_path, 2);
1147 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1148 &iter, changed_path);
1149 /* Invisible node - so no signals expected */
1150 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1151 changed_path, &iter);
1153 gtk_tree_path_next (changed_path);
1154 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1155 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1156 changed_path, &iter);
1158 gtk_tree_path_next (changed_path);
1159 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1160 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1161 changed_path, &iter);
1163 gtk_tree_path_free (changed_path);
1165 check_filter_model (fixture);
1166 check_level_length (fixture->filter, NULL, 2);
1167 check_level_length (fixture->filter, "0", 0);
1169 set_path_visibility (fixture, "3:2:2", TRUE);
1170 check_filter_model (fixture);
1171 check_level_length (fixture->filter, NULL, 2);
1172 check_level_length (fixture->filter, "0", 0);
1174 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1175 set_path_visibility (fixture, "3:2", TRUE);
1176 check_filter_model (fixture);
1177 check_level_length (fixture->filter, NULL, 2);
1178 check_level_length (fixture->filter, "0", 1);
1179 check_level_length (fixture->filter, "0:0", 1);
1180 check_level_length (fixture->filter, "0:0:0", 0);
1182 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1183 set_path_visibility (fixture, "3", FALSE);
1184 check_filter_model (fixture);
1185 check_level_length (fixture->filter, NULL, 1);
1187 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1188 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1189 set_path_visibility (fixture, "3:2:1", TRUE);
1190 set_path_visibility (fixture, "3", TRUE);
1191 check_filter_model (fixture);
1192 check_level_length (fixture->filter, NULL, 2);
1193 check_level_length (fixture->filter, "0", 1);
1194 check_level_length (fixture->filter, "0:0", 2);
1195 check_level_length (fixture->filter, "0:0:0", 0);
1199 empty_vroot_show_nodes (FilterTest *fixture,
1200 gconstpointer user_data)
1202 GtkTreePath *path = (GtkTreePath *)user_data;
1204 check_filter_model_with_root (fixture, path);
1205 check_level_length (fixture->filter, NULL, 0);
1207 set_path_visibility (fixture, "2", TRUE);
1208 check_filter_model_with_root (fixture, path);
1209 check_level_length (fixture->filter, NULL, 0);
1211 set_path_visibility (fixture, "2:2:2", TRUE);
1212 check_filter_model_with_root (fixture, path);
1213 check_level_length (fixture->filter, NULL, 0);
1215 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1216 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1217 set_path_visibility (fixture, "2:2", TRUE);
1218 check_filter_model_with_root (fixture, path);
1219 check_level_length (fixture->filter, NULL, 1);
1220 check_level_length (fixture->filter, "0", 1);
1221 check_level_length (fixture->filter, "0:0", 0);
1223 set_path_visibility (fixture, "3", TRUE);
1224 check_filter_model_with_root (fixture, path);
1225 check_level_length (fixture->filter, NULL, 1);
1227 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1228 set_path_visibility (fixture, "2:2", FALSE);
1229 check_filter_model_with_root (fixture, path);
1230 check_level_length (fixture->filter, NULL, 0);
1232 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1233 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1234 set_path_visibility (fixture, "2:2:1", TRUE);
1235 set_path_visibility (fixture, "2:2", TRUE);
1236 check_filter_model_with_root (fixture, path);
1237 check_level_length (fixture->filter, NULL, 1);
1238 check_level_length (fixture->filter, "0", 2);
1239 check_level_length (fixture->filter, "0:1", 0);
1243 empty_vroot_show_multiple_nodes (FilterTest *fixture,
1244 gconstpointer user_data)
1247 GtkTreePath *changed_path;
1248 GtkTreePath *path = (GtkTreePath *)user_data;
1250 check_filter_model_with_root (fixture, path);
1251 check_level_length (fixture->filter, NULL, 0);
1253 /* We simulate a change in visible func condition with this. The
1254 * visibility state of multiple nodes changes at once, we emit row-changed
1255 * for these nodes (and others) after that.
1257 filter_test_block_signals (fixture);
1258 set_path_visibility (fixture, "2", TRUE);
1259 set_path_visibility (fixture, "3", TRUE);
1260 filter_test_unblock_signals (fixture);
1262 changed_path = gtk_tree_path_new ();
1263 gtk_tree_path_append_index (changed_path, 1);
1264 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1265 &iter, changed_path);
1266 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1267 changed_path, &iter);
1269 gtk_tree_path_next (changed_path);
1270 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1271 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1272 changed_path, &iter);
1274 gtk_tree_path_next (changed_path);
1275 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1276 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1277 changed_path, &iter);
1279 gtk_tree_path_next (changed_path);
1280 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1281 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1282 changed_path, &iter);
1284 gtk_tree_path_free (changed_path);
1286 check_filter_model_with_root (fixture, path);
1287 check_level_length (fixture->filter, NULL, 0);
1289 set_path_visibility (fixture, "2:2:2", TRUE);
1290 check_filter_model_with_root (fixture, path);
1291 check_level_length (fixture->filter, NULL, 0);
1293 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1294 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1295 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
1296 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
1298 /* Again, we simulate a call to refilter */
1299 filter_test_block_signals (fixture);
1300 set_path_visibility (fixture, "2:2", TRUE);
1301 set_path_visibility (fixture, "2:3", TRUE);
1302 filter_test_unblock_signals (fixture);
1304 changed_path = gtk_tree_path_new ();
1305 gtk_tree_path_append_index (changed_path, 2);
1306 gtk_tree_path_append_index (changed_path, 1);
1307 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
1308 &iter, changed_path);
1309 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1310 changed_path, &iter);
1312 gtk_tree_path_next (changed_path);
1313 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1314 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1315 changed_path, &iter);
1317 gtk_tree_path_next (changed_path);
1318 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1319 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1320 changed_path, &iter);
1322 gtk_tree_path_next (changed_path);
1323 gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
1324 gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store),
1325 changed_path, &iter);
1327 gtk_tree_path_free (changed_path);
1329 check_filter_model_with_root (fixture, path);
1330 check_level_length (fixture->filter, NULL, 2);
1331 check_level_length (fixture->filter, "0", 1);
1332 check_level_length (fixture->filter, "0:0", 0);
1334 set_path_visibility (fixture, "3", TRUE);
1335 check_filter_model_with_root (fixture, path);
1336 check_level_length (fixture->filter, NULL, 2);
1338 signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
1339 set_path_visibility (fixture, "2:2", FALSE);
1340 check_filter_model_with_root (fixture, path);
1341 check_level_length (fixture->filter, NULL, 1);
1343 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1344 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1345 set_path_visibility (fixture, "2:2:1", TRUE);
1346 set_path_visibility (fixture, "2:2", TRUE);
1347 check_filter_model_with_root (fixture, path);
1348 check_level_length (fixture->filter, NULL, 2);
1349 check_level_length (fixture->filter, "0", 2);
1350 check_level_length (fixture->filter, "0:1", 0);
1355 unfiltered_hide_single (FilterTest *fixture,
1356 gconstpointer user_data)
1359 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1360 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1361 set_path_visibility (fixture, "2", FALSE);
1363 signal_monitor_assert_is_empty (fixture->monitor);
1364 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1366 /* The view only shows the root level, so we only expect signals
1367 * for the root level.
1369 filter_test_append_refilter_signals (fixture, 1);
1370 filter_test_enable_filter (fixture);
1372 check_filter_model (fixture);
1373 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1377 unfiltered_hide_single_root_expanded (FilterTest *fixture,
1378 gconstpointer user_data)
1381 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1382 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1383 set_path_visibility (fixture, "2", FALSE);
1385 signal_monitor_assert_is_empty (fixture->monitor);
1386 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1388 filter_test_append_refilter_signals (fixture, 2);
1389 filter_test_enable_filter (fixture);
1391 check_filter_model (fixture);
1392 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1396 unfiltered_hide_single_child (FilterTest *fixture,
1397 gconstpointer user_data)
1400 /* This row is not shown, so its signal is not propagated */
1401 set_path_visibility (fixture, "2:2", FALSE);
1403 signal_monitor_assert_is_empty (fixture->monitor);
1404 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1405 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1407 /* The view only shows the root level, so we only expect signals
1408 * for the root level.
1410 filter_test_append_refilter_signals (fixture, 0);
1411 filter_test_enable_filter (fixture);
1413 check_filter_model (fixture);
1414 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1415 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1419 unfiltered_hide_single_child_root_expanded (FilterTest *fixture,
1420 gconstpointer user_data)
1423 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1424 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1425 set_path_visibility (fixture, "2:2", FALSE);
1427 signal_monitor_assert_is_empty (fixture->monitor);
1428 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1429 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1431 filter_test_append_refilter_signals (fixture, 2);
1432 filter_test_enable_filter (fixture);
1434 check_filter_model (fixture);
1435 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1436 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1440 unfiltered_hide_single_multi_level (FilterTest *fixture,
1441 gconstpointer user_data)
1444 /* This row is not shown, so its signal is not propagated */
1445 set_path_visibility (fixture, "2:2:2", FALSE);
1447 /* This row is not shown, so its signal is not propagated */
1448 set_path_visibility (fixture, "2:2", FALSE);
1450 signal_monitor_assert_is_empty (fixture->monitor);
1451 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1452 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1453 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1455 /* The view only shows the root level, so we only expect signals
1456 * for the root level.
1458 filter_test_append_refilter_signals (fixture, 1);
1459 filter_test_enable_filter (fixture);
1461 check_filter_model (fixture);
1462 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1463 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1465 set_path_visibility (fixture, "2:2", TRUE);
1467 check_filter_model (fixture);
1468 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1469 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1470 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1474 unfiltered_hide_single_multi_level_root_expanded (FilterTest *fixture,
1475 gconstpointer user_data)
1478 /* This row is not shown, so its signal is not propagated */
1479 set_path_visibility (fixture, "2:2:2", FALSE);
1481 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1482 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1483 set_path_visibility (fixture, "2:2", FALSE);
1485 signal_monitor_assert_is_empty (fixture->monitor);
1486 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1487 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1488 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1490 filter_test_append_refilter_signals (fixture, 2);
1491 filter_test_enable_filter (fixture);
1493 check_filter_model (fixture);
1494 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1495 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1497 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1498 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1499 set_path_visibility (fixture, "2:2", TRUE);
1501 check_filter_model (fixture);
1502 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1503 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1504 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1510 unfiltered_vroot_hide_single (FilterTest *fixture,
1511 gconstpointer user_data)
1514 GtkTreePath *path = (GtkTreePath *)user_data;
1516 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1517 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1518 set_path_visibility (fixture, "2:2", FALSE);
1520 signal_monitor_assert_is_empty (fixture->monitor);
1521 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1523 /* The view only shows the root level, so we only expect signals
1524 * for the root level. (Though for the depth argument, we have to
1525 * take the virtual root into account).
1527 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1528 filter_test_enable_filter (fixture);
1530 check_filter_model_with_root (fixture, path);
1531 check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
1535 unfiltered_vroot_hide_single_child (FilterTest *fixture,
1536 gconstpointer user_data)
1539 GtkTreePath *path = (GtkTreePath *)user_data;
1541 /* Not visible, so no signal will be received. */
1542 set_path_visibility (fixture, "2:2:2", FALSE);
1544 signal_monitor_assert_is_empty (fixture->monitor);
1545 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1546 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1548 /* The view only shows the root level, so we only expect signals
1549 * for the root level. (Though for the depth argument, we have to
1550 * take the virtual root into account).
1552 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1553 filter_test_enable_filter (fixture);
1555 check_filter_model_with_root (fixture, path);
1556 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1557 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1561 unfiltered_vroot_hide_single_child_root_expanded (FilterTest *fixture,
1562 gconstpointer user_data)
1565 GtkTreePath *path = (GtkTreePath *)user_data;
1567 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1568 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1569 set_path_visibility (fixture, "2:2:2", FALSE);
1571 signal_monitor_assert_is_empty (fixture->monitor);
1572 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1573 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1575 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1576 filter_test_enable_filter (fixture);
1578 check_filter_model_with_root (fixture, path);
1579 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1580 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1584 unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
1585 gconstpointer user_data)
1588 GtkTreePath *path = (GtkTreePath *)user_data;
1590 /* This row is not shown, so its signal is not propagated */
1591 set_path_visibility (fixture, "2:2:2:2", FALSE);
1593 /* Not shown, so no signal */
1594 set_path_visibility (fixture, "2:2:2", FALSE);
1596 signal_monitor_assert_is_empty (fixture->monitor);
1597 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1598 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1599 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1601 /* We only expect signals for the root level. The depth is 2
1602 * because we have to take the virtual root into account.
1604 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1605 filter_test_enable_filter (fixture);
1607 check_filter_model_with_root (fixture, path);
1608 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1609 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1611 /* Not shown, so no signal */
1612 set_path_visibility (fixture, "2:2:2", TRUE);
1614 check_filter_model_with_root (fixture, path);
1615 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1616 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1617 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1621 unfiltered_vroot_hide_single_multi_level_root_expanded (FilterTest *fixture,
1622 gconstpointer user_data)
1625 GtkTreePath *path = (GtkTreePath *)user_data;
1627 /* This row is not shown, so its signal is not propagated */
1628 set_path_visibility (fixture, "2:2:2:2", FALSE);
1630 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1631 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1632 set_path_visibility (fixture, "2:2:2", FALSE);
1634 signal_monitor_assert_is_empty (fixture->monitor);
1635 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1636 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1637 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1639 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1640 filter_test_enable_filter (fixture);
1642 check_filter_model_with_root (fixture, path);
1643 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1644 check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
1646 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
1647 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1648 set_path_visibility (fixture, "2:2:2", TRUE);
1650 check_filter_model_with_root (fixture, path);
1651 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1652 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1653 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1);
1657 unfiltered_show_single (FilterTest *fixture,
1658 gconstpointer user_data)
1661 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1662 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1663 set_path_visibility (fixture, "2", TRUE);
1665 signal_monitor_assert_is_empty (fixture->monitor);
1666 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1668 /* We only expect signals for the root level */
1669 filter_test_append_refilter_signals (fixture, 1);
1670 filter_test_enable_filter (fixture);
1672 check_filter_model (fixture);
1673 check_level_length (fixture->filter, NULL, 1);
1677 unfiltered_show_single_child (FilterTest *fixture,
1678 gconstpointer user_data)
1681 set_path_visibility (fixture, "2:2", TRUE);
1683 signal_monitor_assert_is_empty (fixture->monitor);
1684 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1685 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1687 /* We only expect signals for the root level */
1688 filter_test_append_refilter_signals (fixture, 1);
1689 filter_test_enable_filter (fixture);
1691 check_filter_model (fixture);
1692 check_level_length (fixture->filter, NULL, 0);
1694 /* From here we are filtered, "2" in the real model is "0" in the filter
1697 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1698 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1699 set_path_visibility (fixture, "2", TRUE);
1700 signal_monitor_assert_is_empty (fixture->monitor);
1701 check_level_length (fixture->filter, NULL, 1);
1702 check_level_length (fixture->filter, "0", 1);
1706 unfiltered_show_single_child_root_expanded (FilterTest *fixture,
1707 gconstpointer user_data)
1710 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1711 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1712 set_path_visibility (fixture, "2:2", TRUE);
1714 signal_monitor_assert_is_empty (fixture->monitor);
1715 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1716 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1718 filter_test_append_refilter_signals (fixture, 2);
1719 filter_test_enable_filter (fixture);
1721 check_filter_model (fixture);
1722 check_level_length (fixture->filter, NULL, 0);
1724 /* From here we are filtered, "2" in the real model is "0" in the filter
1727 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1728 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1729 set_path_visibility (fixture, "2", TRUE);
1730 signal_monitor_assert_is_empty (fixture->monitor);
1731 check_level_length (fixture->filter, NULL, 1);
1732 check_level_length (fixture->filter, "0", 1);
1736 unfiltered_show_single_multi_level (FilterTest *fixture,
1737 gconstpointer user_data)
1740 /* The view is not showing these rows (collapsed state), so it is not
1741 * referenced. The signal should not go through.
1743 set_path_visibility (fixture, "2:2:2", TRUE);
1744 set_path_visibility (fixture, "2:2", TRUE);
1746 signal_monitor_assert_is_empty (fixture->monitor);
1747 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1748 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1749 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1751 /* We only expect signals for the first level */
1752 filter_test_append_refilter_signals (fixture, 1);
1753 filter_test_enable_filter (fixture);
1755 check_filter_model (fixture);
1756 check_level_length (fixture->filter, NULL, 0);
1758 /* From here we are filtered, "2" in the real model is "0" in the filter
1761 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1762 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1763 set_path_visibility (fixture, "2", TRUE);
1764 check_filter_model (fixture);
1765 check_level_length (fixture->filter, NULL, 1);
1766 check_level_length (fixture->filter, "0", 1);
1767 check_level_length (fixture->filter, "0:0", 1);
1771 unfiltered_show_single_multi_level_root_expanded (FilterTest *fixture,
1772 gconstpointer user_data)
1775 /* The view is not showing this row (collapsed state), so it is not
1776 * referenced. The signal should not go through.
1778 set_path_visibility (fixture, "2:2:2", TRUE);
1780 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1781 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1782 set_path_visibility (fixture, "2:2", TRUE);
1784 signal_monitor_assert_is_empty (fixture->monitor);
1785 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1786 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1787 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1789 filter_test_append_refilter_signals (fixture, 2);
1790 filter_test_enable_filter (fixture);
1792 check_filter_model (fixture);
1793 check_level_length (fixture->filter, NULL, 0);
1795 /* From here we are filtered, "2" in the real model is "0" in the filter
1798 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1799 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1800 set_path_visibility (fixture, "2", TRUE);
1801 check_filter_model (fixture);
1802 check_level_length (fixture->filter, NULL, 1);
1803 check_level_length (fixture->filter, "0", 1);
1804 check_level_length (fixture->filter, "0:0", 1);
1808 unfiltered_vroot_show_single (FilterTest *fixture,
1809 gconstpointer user_data)
1812 GtkTreePath *path = (GtkTreePath *)user_data;
1814 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
1815 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
1816 set_path_visibility (fixture, "2:2", TRUE);
1818 signal_monitor_assert_is_empty (fixture->monitor);
1819 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1821 /* The view only shows the root level, so the filter model only has
1822 * the first two levels cached.
1824 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1825 filter_test_enable_filter (fixture);
1827 check_filter_model_with_root (fixture, path);
1828 check_level_length (fixture->filter, NULL, 1);
1832 unfiltered_vroot_show_single_child (FilterTest *fixture,
1833 gconstpointer user_data)
1836 GtkTreePath *path = (GtkTreePath *)user_data;
1838 set_path_visibility (fixture, "2:2:2", TRUE);
1840 signal_monitor_assert_is_empty (fixture->monitor);
1841 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1842 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1844 /* The view only shows the root level, so the filter model only has
1845 * the first two levels cached.
1847 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1848 filter_test_enable_filter (fixture);
1850 check_filter_model_with_root (fixture, path);
1851 check_level_length (fixture->filter, NULL, 0);
1853 /* From here we are filtered, "2" in the real model is "0" in the filter
1856 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1857 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1858 set_path_visibility (fixture, "2:2", TRUE);
1859 signal_monitor_assert_is_empty (fixture->monitor);
1860 check_level_length (fixture->filter, NULL, 1);
1861 check_level_length (fixture->filter, "0", 1);
1865 unfiltered_vroot_show_single_child_root_expanded (FilterTest *fixture,
1866 gconstpointer user_data)
1869 GtkTreePath *path = (GtkTreePath *)user_data;
1871 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1872 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1873 set_path_visibility (fixture, "2:2:2", TRUE);
1875 signal_monitor_assert_is_empty (fixture->monitor);
1876 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1877 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1879 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1880 filter_test_enable_filter (fixture);
1882 check_filter_model_with_root (fixture, path);
1883 check_level_length (fixture->filter, NULL, 0);
1885 /* From here we are filtered, "2" in the real model is "0" in the filter
1888 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1889 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1890 set_path_visibility (fixture, "2:2", TRUE);
1891 signal_monitor_assert_is_empty (fixture->monitor);
1892 check_level_length (fixture->filter, NULL, 1);
1893 check_level_length (fixture->filter, "0", 1);
1898 unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
1899 gconstpointer user_data)
1902 GtkTreePath *path = (GtkTreePath *)user_data;
1904 /* The view is not showing this row (collapsed state), so it is not
1905 * referenced. The signal should not go through.
1907 set_path_visibility (fixture, "2:2:2:2", TRUE);
1909 set_path_visibility (fixture, "2:2:2", TRUE);
1911 signal_monitor_assert_is_empty (fixture->monitor);
1912 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1913 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1914 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1916 /* We only expect signals for the root level */
1917 filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
1918 filter_test_enable_filter (fixture);
1920 check_filter_model_with_root (fixture, path);
1921 check_level_length (fixture->filter, NULL, 0);
1923 /* From here we are filtered, "2" in the real model is "0" in the filter
1926 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1927 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1928 set_path_visibility (fixture, "2:2", TRUE);
1929 check_filter_model_with_root (fixture, path);
1930 check_level_length (fixture->filter, NULL, 1);
1931 check_level_length (fixture->filter, "0", 1);
1932 check_level_length (fixture->filter, "0:0", 1);
1936 unfiltered_vroot_show_single_multi_level_root_expanded (FilterTest *fixture,
1937 gconstpointer user_data)
1940 GtkTreePath *path = (GtkTreePath *)user_data;
1942 /* The view is not showing this row (collapsed state), so it is not
1943 * referenced. The signal should not go through.
1945 set_path_visibility (fixture, "2:2:2:2", TRUE);
1947 signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
1948 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
1949 set_path_visibility (fixture, "2:2:2", TRUE);
1951 signal_monitor_assert_is_empty (fixture->monitor);
1952 check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
1953 check_level_length (fixture->filter, "2", LEVEL_LENGTH);
1954 check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
1956 filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
1957 filter_test_enable_filter (fixture);
1959 check_filter_model_with_root (fixture, path);
1960 check_level_length (fixture->filter, NULL, 0);
1962 /* From here we are filtered, "2" in the real model is "0" in the filter
1965 signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
1966 signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
1967 set_path_visibility (fixture, "2:2", TRUE);
1968 check_filter_model_with_root (fixture, path);
1969 check_level_length (fixture->filter, NULL, 1);
1970 check_level_length (fixture->filter, "0", 1);
1971 check_level_length (fixture->filter, "0:0", 1);
1975 unfiltered_rows_reordered_root_level (FilterTest *fixture,
1976 gconstpointer user_data)
1978 int order0[] = { 1, 2, 3, 4, 0 };
1979 int order1[] = { 0, 2, 1, 3, 4 };
1980 int order2[] = { 4, 0, 1, 2, 3 };
1981 GtkTreeIter iter0, iter1, iter2, iter3, iter4;
1984 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
1986 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
1988 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
1990 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
1992 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
1995 path = gtk_tree_path_new ();
1996 signal_monitor_append_signal_reordered (fixture->monitor,
1999 gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
2000 signal_monitor_assert_is_empty (fixture->monitor);
2002 signal_monitor_append_signal_reordered (fixture->monitor,
2005 gtk_tree_store_move_after (fixture->store, &iter2, &iter3);
2006 signal_monitor_assert_is_empty (fixture->monitor);
2008 signal_monitor_append_signal_reordered (fixture->monitor,
2011 gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
2012 signal_monitor_assert_is_empty (fixture->monitor);
2014 gtk_tree_path_free (path);
2018 unfiltered_rows_reordered_child_level (FilterTest *fixture,
2019 gconstpointer user_data)
2021 int order0[] = { 1, 2, 3, 4, 0 };
2022 int order1[] = { 0, 2, 1, 3, 4 };
2023 int order2[] = { 4, 0, 1, 2, 3 };
2024 GtkTreeIter iter0, iter1, iter2, iter3, iter4;
2028 path = gtk_tree_path_new_from_indices (0, -1);
2029 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
2031 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2033 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2035 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2037 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2039 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2042 signal_monitor_append_signal_reordered (fixture->monitor,
2045 gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
2046 signal_monitor_assert_is_empty (fixture->monitor);
2048 signal_monitor_append_signal_reordered (fixture->monitor,
2051 gtk_tree_store_move_after (fixture->store, &iter2, &iter3);
2052 signal_monitor_assert_is_empty (fixture->monitor);
2054 signal_monitor_append_signal_reordered (fixture->monitor,
2057 gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
2058 signal_monitor_assert_is_empty (fixture->monitor);
2060 gtk_tree_path_free (path);
2064 filtered_rows_reordered_root_level_first_hidden (FilterTest *fixture,
2065 gconstpointer user_data)
2067 int order0[] = { 1, 2, 3, 0 };
2068 int order1[] = { 0, 2, 1, 3 };
2069 int order2[] = { 3, 0, 1, 2 };
2070 GtkTreeIter iter1, iter2, iter3, iter4;
2073 /* Hide middle path */
2074 signal_monitor_append_signal (fixture->monitor,
2076 set_path_visibility (fixture, "0", FALSE);
2077 signal_monitor_assert_is_empty (fixture->monitor);
2079 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2081 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2083 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2085 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2088 path = gtk_tree_path_new ();
2089 signal_monitor_append_signal_reordered (fixture->monitor,
2092 gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
2093 signal_monitor_assert_is_empty (fixture->monitor);
2095 signal_monitor_append_signal_reordered (fixture->monitor,
2098 gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
2099 signal_monitor_assert_is_empty (fixture->monitor);
2101 signal_monitor_append_signal_reordered (fixture->monitor,
2104 gtk_tree_store_move_before (fixture->store, &iter1, &iter2);
2105 signal_monitor_assert_is_empty (fixture->monitor);
2107 gtk_tree_path_free (path);
2111 filtered_rows_reordered_root_level_middle_hidden (FilterTest *fixture,
2112 gconstpointer user_data)
2114 int order0[] = { 1, 2, 3, 0 };
2115 int order1[] = { 0, 2, 1, 3 };
2116 int order2[] = { 3, 0, 1, 2 };
2117 GtkTreeIter iter0, iter1, iter3, iter4;
2120 /* Hide middle path */
2121 signal_monitor_append_signal (fixture->monitor,
2123 set_path_visibility (fixture, "2", FALSE);
2124 signal_monitor_assert_is_empty (fixture->monitor);
2126 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2128 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2130 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2132 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2135 path = gtk_tree_path_new ();
2136 signal_monitor_append_signal_reordered (fixture->monitor,
2139 gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
2140 signal_monitor_assert_is_empty (fixture->monitor);
2142 signal_monitor_append_signal_reordered (fixture->monitor,
2145 gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
2146 signal_monitor_assert_is_empty (fixture->monitor);
2148 signal_monitor_append_signal_reordered (fixture->monitor,
2151 gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
2152 signal_monitor_assert_is_empty (fixture->monitor);
2154 gtk_tree_path_free (path);
2158 filtered_rows_reordered_child_level_first_hidden (FilterTest *fixture,
2159 gconstpointer user_data)
2161 int order0[] = { 1, 2, 3, 0 };
2162 int order1[] = { 0, 2, 1, 3 };
2163 int order2[] = { 3, 0, 1, 2 };
2164 GtkTreeIter iter1, iter2, iter3, iter4;
2168 path = gtk_tree_path_new_from_indices (0, -1);
2169 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, TRUE);
2171 /* Hide middle path */
2172 signal_monitor_append_signal (fixture->monitor,
2173 ROW_DELETED, "0:0");
2174 set_path_visibility (fixture, "0:0", FALSE);
2175 signal_monitor_assert_is_empty (fixture->monitor);
2177 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2179 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2181 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2183 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2186 signal_monitor_append_signal_reordered (fixture->monitor,
2189 gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
2190 signal_monitor_assert_is_empty (fixture->monitor);
2192 signal_monitor_append_signal_reordered (fixture->monitor,
2195 gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
2196 signal_monitor_assert_is_empty (fixture->monitor);
2198 signal_monitor_append_signal_reordered (fixture->monitor,
2201 gtk_tree_store_move_before (fixture->store, &iter1, &iter2);
2202 signal_monitor_assert_is_empty (fixture->monitor);
2204 gtk_tree_path_free (path);
2208 filtered_rows_reordered_child_level_middle_hidden (FilterTest *fixture,
2209 gconstpointer user_data)
2211 int order0[] = { 1, 2, 3, 0 };
2212 int order1[] = { 0, 2, 1, 3 };
2213 int order2[] = { 3, 0, 1, 2 };
2214 GtkTreeIter iter0, iter1, iter3, iter4;
2218 path = gtk_tree_path_new_from_indices (0, -1);
2219 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
2221 /* Hide middle path */
2222 signal_monitor_append_signal (fixture->monitor,
2223 ROW_DELETED, "0:2");
2224 set_path_visibility (fixture, "0:2", FALSE);
2225 signal_monitor_assert_is_empty (fixture->monitor);
2227 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2229 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2231 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2233 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2236 signal_monitor_append_signal_reordered (fixture->monitor,
2239 gtk_tree_store_move_after (fixture->store, &iter0, &iter4);
2240 signal_monitor_assert_is_empty (fixture->monitor);
2242 signal_monitor_append_signal_reordered (fixture->monitor,
2245 gtk_tree_store_move_after (fixture->store, &iter3, &iter4);
2246 signal_monitor_assert_is_empty (fixture->monitor);
2248 signal_monitor_append_signal_reordered (fixture->monitor,
2251 gtk_tree_store_move_before (fixture->store, &iter0, &iter1);
2252 signal_monitor_assert_is_empty (fixture->monitor);
2254 gtk_tree_path_free (path);
2258 filtered_rows_reordered_child_level_4_hidden (FilterTest *fixture,
2259 gconstpointer user_data)
2261 int order0[] = { 0 };
2262 GtkTreeIter iter1, iter4;
2266 path = gtk_tree_path_new_from_indices (0, -1);
2267 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
2269 /* Hide last 4 paths */
2270 signal_monitor_append_signal (fixture->monitor,
2271 ROW_DELETED, "0:4");
2272 signal_monitor_append_signal (fixture->monitor,
2273 ROW_DELETED, "0:3");
2274 signal_monitor_append_signal (fixture->monitor,
2275 ROW_DELETED, "0:2");
2276 signal_monitor_append_signal (fixture->monitor,
2277 ROW_DELETED, "0:0");
2278 set_path_visibility (fixture, "0:4", FALSE);
2279 set_path_visibility (fixture, "0:3", FALSE);
2280 set_path_visibility (fixture, "0:2", FALSE);
2281 set_path_visibility (fixture, "0:0", FALSE);
2282 signal_monitor_assert_is_empty (fixture->monitor);
2284 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2286 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2289 signal_monitor_append_signal_reordered (fixture->monitor,
2292 gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
2293 signal_monitor_assert_is_empty (fixture->monitor);
2295 gtk_tree_path_free (path);
2299 filtered_rows_reordered_child_level_all_hidden (FilterTest *fixture,
2300 gconstpointer user_data)
2302 GtkTreeIter iter1, iter4;
2306 path = gtk_tree_path_new_from_indices (0, -1);
2307 gtk_tree_view_expand_row (GTK_TREE_VIEW (fixture->tree_view), path, FALSE);
2308 gtk_tree_path_free (path);
2310 /* Hide last 4 paths */
2311 signal_monitor_append_signal (fixture->monitor,
2312 ROW_DELETED, "0:4");
2313 signal_monitor_append_signal (fixture->monitor,
2314 ROW_DELETED, "0:3");
2315 signal_monitor_append_signal (fixture->monitor,
2316 ROW_DELETED, "0:2");
2317 signal_monitor_append_signal (fixture->monitor,
2318 ROW_DELETED, "0:1");
2319 signal_monitor_append_signal (fixture->monitor,
2320 ROW_DELETED, "0:0");
2321 signal_monitor_append_signal (fixture->monitor,
2322 ROW_HAS_CHILD_TOGGLED, "0");
2323 set_path_visibility (fixture, "0:4", FALSE);
2324 set_path_visibility (fixture, "0:3", FALSE);
2325 set_path_visibility (fixture, "0:2", FALSE);
2326 set_path_visibility (fixture, "0:1", FALSE);
2327 set_path_visibility (fixture, "0:0", FALSE);
2328 signal_monitor_assert_is_empty (fixture->monitor);
2330 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2332 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store),
2335 gtk_tree_store_move_after (fixture->store, &iter1, &iter4);
2336 signal_monitor_assert_is_empty (fixture->monitor);
2340 insert_before (void)
2342 GtkTreeStore *store;
2343 GtkTreeModel *filter;
2344 GtkWidget *tree_view;
2345 SignalMonitor *monitor;
2347 GtkTreeIter last_iter;
2350 /* This tests two aspects of the row-inserted handling:
2351 * 1) If the newly inserted node was already handled by building
2352 * the root level, don't handle it a second time.
2353 * 2) Offsets of existing nodes must be updated when a new
2357 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2358 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2359 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
2362 tree_view = gtk_tree_view_new_with_model (filter);
2363 monitor = signal_monitor_new (filter);
2365 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 0);
2368 path = gtk_tree_path_new_from_indices (0, -1);
2369 signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
2370 gtk_tree_path_free (path);
2372 gtk_tree_store_insert_with_values (store, &iter, NULL, 0,
2373 0, "Foo", 1, TRUE, -1);
2375 signal_monitor_assert_is_empty (monitor);
2376 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
2379 path = gtk_tree_path_new_from_indices (1, -1);
2380 signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
2381 gtk_tree_path_free (path);
2383 gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
2384 0, "Foo", 1, TRUE, -1);
2387 signal_monitor_assert_is_empty (monitor);
2388 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
2390 /* Insert on 1 again -- invisible */
2391 gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
2392 0, "Foo", 1, FALSE, -1);
2394 signal_monitor_assert_is_empty (monitor);
2395 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
2397 /* Insert on 1 again -- visible */
2398 path = gtk_tree_path_new_from_indices (1, -1);
2399 signal_monitor_append_signal_path (monitor, ROW_INSERTED, path);
2400 gtk_tree_path_free (path);
2402 gtk_tree_store_insert_with_values (store, &iter, NULL, 1,
2403 0, "Foo", 1, TRUE, -1);
2405 signal_monitor_assert_is_empty (monitor);
2406 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 3);
2408 /* Modify the iter that should be at the last position and check the
2411 path = gtk_tree_path_new_from_indices (2, -1);
2412 signal_monitor_append_signal_path (monitor, ROW_CHANGED, path);
2413 gtk_tree_path_free (path);
2415 gtk_tree_store_set (store, &last_iter, 0, "Foo changed", -1);
2417 signal_monitor_assert_is_empty (monitor);
2418 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 3);
2424 GtkTreeStore *store;
2425 GtkTreeModel *filter;
2426 GtkWidget *tree_view;
2427 SignalMonitor *monitor;
2428 GtkTreeIter parent, iter;
2431 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
2433 gtk_tree_store_insert_with_values (store, &parent, NULL, 0,
2434 0, "Parent", 1, TRUE, -1);
2437 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
2438 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter),
2441 tree_view = gtk_tree_view_new_with_model (filter);
2442 monitor = signal_monitor_new (filter);
2444 /* Insert child -- invisible */
2445 path = gtk_tree_path_new_from_indices (0, -1);
2446 signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
2447 /* The signal is received twice, once a pass through from GtkTreeStore
2448 * and one generated by GtkTreeModelFilter. Not accurate, but cannot
2451 signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
2452 gtk_tree_path_free (path);
2454 gtk_tree_store_insert_with_values (store, &iter, &parent, 1,
2455 0, "Child", 1, FALSE, -1);
2457 signal_monitor_assert_is_empty (monitor);
2458 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
2461 path = gtk_tree_path_new_from_indices (0, 0, -1);
2462 gtk_tree_path_up (path); /* 0 */
2463 signal_monitor_append_signal_path (monitor, ROW_HAS_CHILD_TOGGLED, path);
2464 gtk_tree_path_free (path);
2466 gtk_tree_store_insert_with_values (store, &iter, &parent, 0,
2467 0, "Child", 1, TRUE, -1);
2469 signal_monitor_assert_is_empty (monitor);
2470 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
2472 /* Insert child -- invisible */
2473 gtk_tree_store_insert_with_values (store, &iter, &parent, 1,
2474 0, "Child", 1, FALSE, -1);
2476 signal_monitor_assert_is_empty (monitor);
2477 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
2485 GtkTreeIter iter, iter1, iter2, iter3;
2487 GtkTreeModel *filter;
2488 GtkWidget *view G_GNUC_UNUSED;
2490 list = gtk_list_store_new (1, G_TYPE_INT);
2491 gtk_list_store_insert_with_values (list, &iter1, 0, 0, 1, -1);
2492 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
2493 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
2494 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
2495 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
2496 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
2497 gtk_list_store_insert_with_values (list, &iter2, 6, 0, 7, -1);
2498 gtk_list_store_insert_with_values (list, &iter3, 7, 0, 8, -1);
2500 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
2501 view = gtk_tree_view_new_with_model (filter);
2503 gtk_list_store_remove (list, &iter1);
2504 gtk_list_store_remove (list, &iter3);
2505 gtk_list_store_remove (list, &iter2);
2507 gtk_widget_destroy (view);
2508 g_object_unref (filter);
2509 g_object_unref (list);
2513 remove_node_vroot (void)
2515 GtkTreeIter parent, root;
2516 GtkTreeIter iter, iter1, iter2, iter3;
2518 GtkTreeModel *filter;
2520 GtkWidget *view G_GNUC_UNUSED;
2522 tree = gtk_tree_store_new (1, G_TYPE_INT);
2523 gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
2524 gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
2526 gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
2527 gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
2528 gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
2529 gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
2530 gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
2531 gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
2532 gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
2533 gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
2535 path = gtk_tree_path_new_from_indices (0, 0, -1);
2536 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
2537 gtk_tree_path_free (path);
2539 view = gtk_tree_view_new_with_model (filter);
2541 gtk_tree_store_remove (tree, &iter1);
2542 gtk_tree_store_remove (tree, &iter3);
2543 gtk_tree_store_remove (tree, &iter2);
2545 gtk_widget_destroy (view);
2546 g_object_unref (filter);
2547 g_object_unref (tree);
2551 remove_vroot_ancestor (void)
2553 GtkTreeIter parent, root;
2554 GtkTreeIter iter, iter1, iter2, iter3;
2556 GtkTreeModel *filter;
2558 GtkWidget *view G_GNUC_UNUSED;
2560 tree = gtk_tree_store_new (1, G_TYPE_INT);
2561 gtk_tree_store_insert_with_values (tree, &parent, NULL, 0, 0, 0, -1);
2562 gtk_tree_store_insert_with_values (tree, &root, &parent, 0, 0, 0, -1);
2564 gtk_tree_store_insert_with_values (tree, &iter1, &root, 0, 0, 1, -1);
2565 gtk_tree_store_insert_with_values (tree, &iter, &root, 1, 0, 2, -1);
2566 gtk_tree_store_insert_with_values (tree, &iter, &root, 2, 0, 3, -1);
2567 gtk_tree_store_insert_with_values (tree, &iter, &root, 3, 0, 4, -1);
2568 gtk_tree_store_insert_with_values (tree, &iter, &root, 4, 0, 5, -1);
2569 gtk_tree_store_insert_with_values (tree, &iter, &root, 5, 0, 6, -1);
2570 gtk_tree_store_insert_with_values (tree, &iter2, &root, 6, 0, 7, -1);
2571 gtk_tree_store_insert_with_values (tree, &iter3, &root, 7, 0, 8, -1);
2573 path = gtk_tree_path_new_from_indices (0, 0, -1);
2574 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
2575 gtk_tree_path_free (path);
2577 view = gtk_tree_view_new_with_model (filter);
2579 gtk_tree_store_remove (tree, &parent);
2581 gtk_widget_destroy (view);
2582 g_object_unref (filter);
2583 g_object_unref (tree);
2587 ref_count_single_level (void)
2589 GtkTreeIter iter[5];
2590 GtkTreeModel *model;
2591 GtkTreeModelRefCount *ref_model;
2592 GtkTreeModel *filter_model;
2593 GtkWidget *tree_view;
2595 model = gtk_tree_model_ref_count_new ();
2596 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
2598 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[0], NULL);
2599 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[1], NULL);
2600 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[2], NULL);
2601 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[3], NULL);
2602 gtk_tree_store_append (GTK_TREE_STORE (model), &iter[4], NULL);
2604 assert_root_level_unreferenced (ref_model);
2606 filter_model = gtk_tree_model_filter_new (model, NULL);
2607 tree_view = gtk_tree_view_new_with_model (filter_model);
2609 assert_node_ref_count (ref_model, &iter[0], 2);
2610 assert_node_ref_count (ref_model, &iter[1], 1);
2611 assert_node_ref_count (ref_model, &iter[2], 1);
2612 assert_node_ref_count (ref_model, &iter[3], 1);
2613 assert_node_ref_count (ref_model, &iter[4], 1);
2615 gtk_widget_destroy (tree_view);
2617 assert_node_ref_count (ref_model, &iter[0], 1);
2618 assert_node_ref_count (ref_model, &iter[1], 0);
2619 assert_node_ref_count (ref_model, &iter[2], 0);
2620 assert_node_ref_count (ref_model, &iter[3], 0);
2621 assert_node_ref_count (ref_model, &iter[4], 0);
2623 g_object_unref (filter_model);
2625 assert_node_ref_count (ref_model, &iter[0], 0);
2627 g_object_unref (ref_model);
2631 ref_count_two_levels (void)
2633 GtkTreeIter parent1, parent2, iter, iter_first;
2634 GtkTreeModel *model;
2635 GtkTreeModelRefCount *ref_model;
2636 GtkTreeModel *filter_model;
2637 GtkWidget *tree_view;
2639 model = gtk_tree_model_ref_count_new ();
2640 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
2642 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
2643 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
2644 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_first, &parent2);
2645 gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
2646 gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
2648 assert_entire_model_unreferenced (ref_model);
2650 filter_model = gtk_tree_model_filter_new (model, NULL);
2651 tree_view = gtk_tree_view_new_with_model (filter_model);
2653 /* This is quite confusing:
2654 * - node 0 has a ref count of 2 because it is referenced as the
2655 * first node in a level and by the tree view.
2656 * - node 1 has a ref count of 2 because it is referenced by its
2657 * child level and by the tree view.
2659 assert_root_level_referenced (ref_model, 2);
2660 assert_node_ref_count (ref_model, &iter_first, 1);
2661 assert_node_ref_count (ref_model, &iter, 0);
2663 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2665 assert_node_ref_count (ref_model, &parent1, 2);
2666 assert_node_ref_count (ref_model, &parent2, 2);
2667 assert_node_ref_count (ref_model, &iter_first, 2);
2668 assert_node_ref_count (ref_model, &iter, 1);
2670 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
2672 /* The child level is not destroyed because its parent is visible */
2673 assert_node_ref_count (ref_model, &parent1, 2);
2674 assert_node_ref_count (ref_model, &parent2, 2);
2675 assert_node_ref_count (ref_model, &iter_first, 1);
2676 assert_node_ref_count (ref_model, &iter, 0);
2678 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2680 assert_node_ref_count (ref_model, &parent1, 2);
2681 assert_node_ref_count (ref_model, &parent2, 2);
2682 assert_node_ref_count (ref_model, &iter_first, 1);
2683 assert_node_ref_count (ref_model, &iter, 0);
2685 gtk_widget_destroy (tree_view);
2687 assert_root_level_referenced (ref_model, 1);
2688 assert_node_ref_count (ref_model, &iter_first, 1);
2689 assert_node_ref_count (ref_model, &iter, 0);
2691 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2693 /* Only the reference on the first node of the root level is kept. */
2694 assert_node_ref_count (ref_model, &parent1, 1);
2695 assert_node_ref_count (ref_model, &parent2, 0);
2696 assert_node_ref_count (ref_model, &iter_first, 0);
2697 assert_node_ref_count (ref_model, &iter, 0);
2699 g_object_unref (filter_model);
2700 g_object_unref (ref_model);
2704 ref_count_three_levels (void)
2706 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
2707 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
2708 GtkTreeModel *model;
2709 GtkTreeModelRefCount *ref_model;
2710 GtkTreeModel *filter_model;
2712 GtkWidget *tree_view;
2714 model = gtk_tree_model_ref_count_new ();
2715 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
2722 * + iter_parent2_first
2726 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
2727 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
2728 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
2729 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
2730 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
2731 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
2732 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
2734 assert_entire_model_unreferenced (ref_model);
2736 filter_model = gtk_tree_model_filter_new (model, NULL);
2737 tree_view = gtk_tree_view_new_with_model (filter_model);
2739 /* This is quite confusing:
2740 * - node 0 has a ref count of 2 because it is referenced as the
2741 * first node in a level and by the tree view.
2742 * - node 1 has a ref count of 2 because it is referenced by its
2743 * child level and by the tree view.
2745 assert_root_level_referenced (ref_model, 2);
2746 assert_node_ref_count (ref_model, &parent1, 1);
2747 assert_node_ref_count (ref_model, &parent2, 0);
2748 assert_level_unreferenced (ref_model, &parent1);
2749 assert_level_unreferenced (ref_model, &parent2);
2751 path = gtk_tree_path_new_from_indices (1, -1);
2752 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
2754 assert_node_ref_count (ref_model, &grandparent1, 2);
2755 assert_node_ref_count (ref_model, &grandparent2, 2);
2756 assert_node_ref_count (ref_model, &parent1, 3);
2757 assert_node_ref_count (ref_model, &parent2, 2);
2758 assert_node_ref_count (ref_model, &iter_parent1, 1);
2759 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
2760 assert_node_ref_count (ref_model, &iter_parent2, 0);
2762 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
2764 assert_node_ref_count (ref_model, &grandparent1, 2);
2765 assert_node_ref_count (ref_model, &grandparent2, 2);
2766 assert_node_ref_count (ref_model, &parent1, 3);
2767 assert_node_ref_count (ref_model, &parent2, 2);
2768 assert_node_ref_count (ref_model, &iter_parent1, 2);
2769 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
2770 assert_node_ref_count (ref_model, &iter_parent2, 1);
2772 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
2774 assert_node_ref_count (ref_model, &grandparent1, 2);
2775 assert_node_ref_count (ref_model, &grandparent2, 2);
2776 assert_node_ref_count (ref_model, &parent1, 2);
2777 assert_node_ref_count (ref_model, &parent2, 1);
2778 assert_node_ref_count (ref_model, &iter_parent1, 1);
2779 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
2780 assert_node_ref_count (ref_model, &iter_parent2, 0);
2782 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2784 assert_node_ref_count (ref_model, &grandparent1, 2);
2785 assert_node_ref_count (ref_model, &grandparent2, 2);
2786 assert_node_ref_count (ref_model, &parent1, 1);
2787 assert_node_ref_count (ref_model, &parent2, 0);
2788 assert_node_ref_count (ref_model, &iter_parent1, 0);
2789 assert_node_ref_count (ref_model, &iter_parent2_first, 0);
2790 assert_node_ref_count (ref_model, &iter_parent2, 0);
2792 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
2794 assert_node_ref_count (ref_model, &grandparent1, 2);
2795 assert_node_ref_count (ref_model, &grandparent2, 2);
2796 assert_node_ref_count (ref_model, &parent1, 3);
2797 assert_node_ref_count (ref_model, &parent2, 2);
2798 assert_node_ref_count (ref_model, &iter_parent1, 1);
2799 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
2800 assert_node_ref_count (ref_model, &iter_parent2, 0);
2802 gtk_tree_path_append_index (path, 1);
2803 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
2805 assert_node_ref_count (ref_model, &grandparent1, 2);
2806 assert_node_ref_count (ref_model, &grandparent2, 2);
2807 assert_node_ref_count (ref_model, &parent1, 3);
2808 assert_node_ref_count (ref_model, &parent2, 2);
2809 assert_node_ref_count (ref_model, &iter_parent1, 1);
2810 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
2811 assert_node_ref_count (ref_model, &iter_parent2, 1);
2813 gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
2815 assert_node_ref_count (ref_model, &grandparent1, 2);
2816 assert_node_ref_count (ref_model, &grandparent2, 2);
2817 assert_node_ref_count (ref_model, &parent1, 3);
2818 assert_node_ref_count (ref_model, &parent2, 2);
2819 assert_node_ref_count (ref_model, &iter_parent1, 1);
2820 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
2821 assert_node_ref_count (ref_model, &iter_parent2, 0);
2823 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2825 assert_node_ref_count (ref_model, &grandparent1, 2);
2826 assert_node_ref_count (ref_model, &grandparent2, 2);
2827 assert_node_ref_count (ref_model, &parent1, 3);
2828 assert_node_ref_count (ref_model, &parent2, 2);
2829 assert_node_ref_count (ref_model, &iter_parent1, 1);
2830 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
2831 assert_node_ref_count (ref_model, &iter_parent2, 0);
2833 gtk_tree_path_up (path);
2834 gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
2835 gtk_tree_path_free (path);
2837 assert_node_ref_count (ref_model, &grandparent1, 2);
2838 assert_node_ref_count (ref_model, &grandparent2, 2);
2839 assert_node_ref_count (ref_model, &parent1, 2);
2840 assert_node_ref_count (ref_model, &parent2, 1);
2841 assert_node_ref_count (ref_model, &iter_parent1, 1);
2842 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
2843 assert_node_ref_count (ref_model, &iter_parent2, 0);
2845 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2847 assert_node_ref_count (ref_model, &grandparent1, 2);
2848 assert_node_ref_count (ref_model, &grandparent2, 2);
2849 assert_node_ref_count (ref_model, &parent1, 1);
2850 assert_node_ref_count (ref_model, &parent2, 0);
2851 assert_node_ref_count (ref_model, &iter_parent1, 0);
2852 assert_node_ref_count (ref_model, &iter_parent2_first, 0);
2853 assert_node_ref_count (ref_model, &iter_parent2, 0);
2855 gtk_widget_destroy (tree_view);
2857 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2859 /* Only the reference on the first node of the root level is kept. */
2860 assert_node_ref_count (ref_model, &grandparent1, 1);
2861 assert_node_ref_count (ref_model, &grandparent2, 0);
2862 assert_node_ref_count (ref_model, &parent1, 0);
2863 assert_node_ref_count (ref_model, &parent2, 0);
2864 assert_node_ref_count (ref_model, &iter_parent1, 0);
2865 assert_node_ref_count (ref_model, &iter_parent2_first, 0);
2866 assert_node_ref_count (ref_model, &iter_parent2, 0);
2868 g_object_unref (filter_model);
2869 g_object_unref (ref_model);
2873 ref_count_delete_row (void)
2875 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
2876 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
2877 GtkTreeModel *model;
2878 GtkTreeModelRefCount *ref_model;
2879 GtkTreeModel *filter_model;
2881 GtkWidget *tree_view;
2883 model = gtk_tree_model_ref_count_new ();
2884 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
2891 * + iter_parent2_first
2895 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
2896 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
2897 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
2898 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
2899 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
2900 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
2901 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
2903 assert_entire_model_unreferenced (ref_model);
2905 filter_model = gtk_tree_model_filter_new (model, NULL);
2906 tree_view = gtk_tree_view_new_with_model (filter_model);
2908 assert_root_level_referenced (ref_model, 2);
2909 assert_node_ref_count (ref_model, &parent1, 1);
2910 assert_node_ref_count (ref_model, &parent2, 0);
2911 assert_level_unreferenced (ref_model, &parent1);
2912 assert_level_unreferenced (ref_model, &parent2);
2914 path = gtk_tree_path_new_from_indices (1, -1);
2915 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
2916 gtk_tree_path_free (path);
2918 assert_node_ref_count (ref_model, &grandparent1, 2);
2919 assert_node_ref_count (ref_model, &grandparent2, 2);
2920 assert_node_ref_count (ref_model, &parent1, 3);
2921 assert_node_ref_count (ref_model, &parent2, 2);
2922 assert_node_ref_count (ref_model, &iter_parent1, 2);
2923 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
2924 assert_node_ref_count (ref_model, &iter_parent2, 1);
2926 gtk_tree_store_remove (GTK_TREE_STORE (model), &iter_parent2);
2928 assert_node_ref_count (ref_model, &grandparent1, 2);
2929 assert_node_ref_count (ref_model, &grandparent2, 2);
2930 assert_node_ref_count (ref_model, &parent1, 3);
2931 assert_node_ref_count (ref_model, &parent2, 2);
2932 assert_node_ref_count (ref_model, &iter_parent1, 2);
2933 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
2935 gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
2937 assert_node_ref_count (ref_model, &grandparent1, 2);
2938 assert_node_ref_count (ref_model, &grandparent2, 2);
2939 assert_node_ref_count (ref_model, &parent2, 3);
2940 assert_level_referenced (ref_model, 2, &parent2);
2942 gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
2944 assert_node_ref_count (ref_model, &grandparent1, 2);
2946 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2948 assert_node_ref_count (ref_model, &grandparent1, 2);
2950 gtk_widget_destroy (tree_view);
2951 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2953 assert_node_ref_count (ref_model, &grandparent1, 1);
2955 g_object_unref (filter_model);
2957 assert_node_ref_count (ref_model, &grandparent1, 0);
2959 g_object_unref (ref_model);
2963 ref_count_cleanup (void)
2965 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
2966 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
2967 GtkTreeModel *model;
2968 GtkTreeModelRefCount *ref_model;
2969 GtkTreeModel *filter_model;
2970 GtkWidget *tree_view;
2972 model = gtk_tree_model_ref_count_new ();
2973 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
2980 * + iter_parent2_first
2984 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
2985 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
2986 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
2987 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
2988 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
2989 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
2990 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
2992 filter_model = gtk_tree_model_filter_new (model, NULL);
2993 tree_view = gtk_tree_view_new_with_model (filter_model);
2995 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2997 assert_node_ref_count (ref_model, &grandparent1, 2);
2998 assert_node_ref_count (ref_model, &grandparent2, 2);
2999 assert_node_ref_count (ref_model, &parent1, 3);
3000 assert_node_ref_count (ref_model, &parent2, 2);
3001 assert_node_ref_count (ref_model, &iter_parent1, 2);
3002 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
3003 assert_node_ref_count (ref_model, &iter_parent2, 1);
3005 gtk_widget_destroy (tree_view);
3007 assert_node_ref_count (ref_model, &grandparent1, 1);
3008 assert_node_ref_count (ref_model, &grandparent2, 1);
3009 assert_node_ref_count (ref_model, &parent1, 2);
3010 assert_node_ref_count (ref_model, &parent2, 1);
3011 assert_node_ref_count (ref_model, &iter_parent1, 1);
3012 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3013 assert_node_ref_count (ref_model, &iter_parent2, 0);
3015 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3017 /* Only the reference on the first node of the root level is kept. */
3018 assert_node_ref_count (ref_model, &grandparent1, 1);
3019 assert_node_ref_count (ref_model, &grandparent2, 0);
3020 assert_node_ref_count (ref_model, &parent1, 0);
3021 assert_node_ref_count (ref_model, &parent2, 0);
3022 assert_node_ref_count (ref_model, &iter_parent1, 0);
3023 assert_node_ref_count (ref_model, &iter_parent2_first, 0);
3024 assert_node_ref_count (ref_model, &iter_parent2, 0);
3026 g_object_unref (filter_model);
3027 g_object_unref (ref_model);
3031 ref_count_row_ref (void)
3033 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
3034 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
3035 GtkTreeModel *model;
3036 GtkTreeModelRefCount *ref_model;
3037 GtkTreeModel *filter_model;
3038 GtkWidget *tree_view;
3040 GtkTreeRowReference *row_ref;
3042 model = gtk_tree_model_ref_count_new ();
3043 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3054 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3055 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3056 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
3057 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
3058 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
3059 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
3060 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
3062 filter_model = gtk_tree_model_filter_new (model, NULL);
3063 tree_view = gtk_tree_view_new_with_model (filter_model);
3065 path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
3066 row_ref = gtk_tree_row_reference_new (filter_model, path);
3067 gtk_tree_path_free (path);
3069 assert_node_ref_count (ref_model, &grandparent1, 2);
3070 assert_node_ref_count (ref_model, &grandparent2, 3);
3071 assert_node_ref_count (ref_model, &parent1, 1);
3072 assert_node_ref_count (ref_model, &parent2, 2);
3073 assert_node_ref_count (ref_model, &iter_parent1, 0);
3074 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3075 assert_node_ref_count (ref_model, &iter_parent2, 1);
3077 gtk_tree_row_reference_free (row_ref);
3079 assert_node_ref_count (ref_model, &grandparent1, 2);
3080 assert_node_ref_count (ref_model, &grandparent2, 2);
3081 assert_node_ref_count (ref_model, &parent1, 1);
3082 assert_node_ref_count (ref_model, &parent2, 1);
3083 assert_node_ref_count (ref_model, &iter_parent1, 0);
3084 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3085 assert_node_ref_count (ref_model, &iter_parent2, 0);
3087 path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
3088 row_ref = gtk_tree_row_reference_new (filter_model, path);
3089 gtk_tree_path_free (path);
3091 assert_node_ref_count (ref_model, &grandparent1, 2);
3092 assert_node_ref_count (ref_model, &grandparent2, 3);
3093 assert_node_ref_count (ref_model, &parent1, 1);
3094 assert_node_ref_count (ref_model, &parent2, 2);
3095 assert_node_ref_count (ref_model, &iter_parent1, 0);
3096 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3097 assert_node_ref_count (ref_model, &iter_parent2, 1);
3099 gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
3101 assert_node_ref_count (ref_model, &grandparent1, 2);
3102 assert_node_ref_count (ref_model, &grandparent2, 2);
3103 assert_node_ref_count (ref_model, &parent1, 1);
3104 assert_node_ref_count (ref_model, &iter_parent1, 0);
3106 gtk_tree_row_reference_free (row_ref);
3108 assert_node_ref_count (ref_model, &grandparent1, 2);
3109 assert_node_ref_count (ref_model, &grandparent2, 2);
3110 assert_node_ref_count (ref_model, &parent1, 1);
3111 assert_node_ref_count (ref_model, &iter_parent1, 0);
3113 gtk_widget_destroy (tree_view);
3115 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3117 /* Only the reference on the first node of the root level is kept. */
3118 assert_node_ref_count (ref_model, &grandparent1, 1);
3119 assert_node_ref_count (ref_model, &grandparent2, 0);
3120 assert_node_ref_count (ref_model, &parent1, 0);
3122 g_object_unref (filter_model);
3123 g_object_unref (ref_model);
3127 ref_count_transfer_root_level_insert (void)
3129 GtkTreeIter grandparent1, grandparent2, grandparent3;
3130 GtkTreeIter new_node;
3131 GtkTreeModel *model;
3132 GtkTreeModelRefCount *ref_model;
3133 GtkTreeModel *filter_model;
3134 GtkWidget *tree_view;
3136 model = gtk_tree_model_ref_count_new ();
3137 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3144 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3145 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3146 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
3148 filter_model = gtk_tree_model_filter_new (model, NULL);
3149 tree_view = gtk_tree_view_new_with_model (filter_model);
3151 assert_node_ref_count (ref_model, &grandparent1, 2);
3152 assert_node_ref_count (ref_model, &grandparent2, 1);
3153 assert_node_ref_count (ref_model, &grandparent3, 1);
3155 gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
3157 assert_node_ref_count (ref_model, &new_node, 2);
3158 assert_node_ref_count (ref_model, &grandparent1, 1);
3159 assert_node_ref_count (ref_model, &grandparent2, 1);
3160 assert_node_ref_count (ref_model, &grandparent3, 1);
3162 gtk_widget_destroy (tree_view);
3163 g_object_unref (filter_model);
3164 g_object_unref (ref_model);
3168 ref_count_transfer_root_level_reordered (void)
3170 GtkTreeIter grandparent1, grandparent2, grandparent3;
3171 GtkTreeModel *model;
3172 GtkTreeModelRefCount *ref_model;
3173 GtkTreeModel *filter_model;
3174 GtkWidget *tree_view;
3176 model = gtk_tree_model_ref_count_new ();
3177 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3184 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3185 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3186 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
3188 filter_model = gtk_tree_model_filter_new (model, NULL);
3189 tree_view = gtk_tree_view_new_with_model (filter_model);
3191 assert_node_ref_count (ref_model, &grandparent1, 2);
3192 assert_node_ref_count (ref_model, &grandparent2, 1);
3193 assert_node_ref_count (ref_model, &grandparent3, 1);
3195 /* gtk_tree_store_move() will emit rows-reordered */
3196 gtk_tree_store_move_after (GTK_TREE_STORE (model),
3197 &grandparent1, &grandparent3);
3199 assert_node_ref_count (ref_model, &grandparent2, 2);
3200 assert_node_ref_count (ref_model, &grandparent3, 1);
3201 assert_node_ref_count (ref_model, &grandparent1, 1);
3203 gtk_widget_destroy (tree_view);
3204 g_object_unref (filter_model);
3205 g_object_unref (ref_model);
3209 ref_count_transfer_child_level_insert (void)
3211 GtkTreeIter grandparent1;
3212 GtkTreeIter parent1, parent2, parent3;
3213 GtkTreeIter new_node;
3214 GtkTreeModel *model;
3215 GtkTreeModelRefCount *ref_model;
3216 GtkTreeModel *filter_model;
3217 GtkWidget *tree_view;
3219 model = gtk_tree_model_ref_count_new ();
3220 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3228 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3229 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
3230 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
3231 gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
3233 filter_model = gtk_tree_model_filter_new (model, NULL);
3234 tree_view = gtk_tree_view_new_with_model (filter_model);
3236 assert_node_ref_count (ref_model, &grandparent1, 3);
3237 assert_node_ref_count (ref_model, &parent1, 1);
3238 assert_node_ref_count (ref_model, &parent2, 0);
3239 assert_node_ref_count (ref_model, &parent3, 0);
3241 gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &grandparent1);
3243 assert_node_ref_count (ref_model, &grandparent1, 3);
3244 assert_node_ref_count (ref_model, &new_node, 1);
3245 assert_node_ref_count (ref_model, &parent1, 0);
3246 assert_node_ref_count (ref_model, &parent2, 0);
3247 assert_node_ref_count (ref_model, &parent3, 0);
3249 gtk_widget_destroy (tree_view);
3250 g_object_unref (filter_model);
3251 g_object_unref (ref_model);
3255 ref_count_transfer_child_level_reordered (void)
3257 GtkTreeIter grandparent1;
3258 GtkTreeIter parent1, parent2, parent3;
3259 GtkTreeModel *model;
3260 GtkTreeModelRefCount *ref_model;
3261 GtkTreeModel *filter_model;
3262 GtkWidget *tree_view;
3264 model = gtk_tree_model_ref_count_new ();
3265 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3273 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3274 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
3275 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
3276 gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
3278 filter_model = gtk_tree_model_filter_new (model, NULL);
3279 tree_view = gtk_tree_view_new_with_model (filter_model);
3281 assert_node_ref_count (ref_model, &grandparent1, 3);
3282 assert_node_ref_count (ref_model, &parent1, 1);
3283 assert_node_ref_count (ref_model, &parent2, 0);
3284 assert_node_ref_count (ref_model, &parent3, 0);
3286 /* gtk_tree_store_move() will emit rows-reordered */
3287 gtk_tree_store_move_after (GTK_TREE_STORE (model),
3288 &parent1, &parent3);
3290 assert_node_ref_count (ref_model, &grandparent1, 3);
3291 assert_node_ref_count (ref_model, &parent2, 1);
3292 assert_node_ref_count (ref_model, &parent3, 0);
3293 assert_node_ref_count (ref_model, &parent1, 0);
3295 gtk_widget_destroy (tree_view);
3296 g_object_unref (filter_model);
3297 g_object_unref (ref_model);
3302 specific_path_dependent_filter_func (GtkTreeModel *model,
3308 path = gtk_tree_model_get_path (model, iter);
3309 if (gtk_tree_path_get_indices (path)[0] < 4)
3316 specific_path_dependent_filter (void)
3322 GtkTreeModel *filter;
3324 list = gtk_list_store_new (1, G_TYPE_INT);
3325 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
3326 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
3327 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
3328 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
3329 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
3330 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
3331 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
3332 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
3334 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
3335 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
3336 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3337 specific_path_dependent_filter_func,
3340 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
3341 GTK_SORT_DESCENDING);
3343 for (i = 0; i < 4; i++)
3345 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
3347 gtk_list_store_remove (list, &iter);
3349 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
3351 gtk_list_store_remove (list, &iter);
3354 g_object_unref (filter);
3355 g_object_unref (sort);
3356 g_object_unref (list);
3361 specific_append_after_collapse_visible_func (GtkTreeModel *model,
3366 gboolean hide_negative_numbers;
3368 gtk_tree_model_get (model, iter, 1, &number, -1);
3369 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
3371 return (number >= 0 || !hide_negative_numbers);
3375 specific_append_after_collapse (void)
3377 /* This test is based on one of the test cases I found in my
3378 * old test cases directory. I unfortunately do not have a record
3379 * from who this test case originated. -Kris.
3383 * - Show tree, expand, collapse.
3388 GtkTreeIter child_iter;
3389 GtkTreeIter child_iter2;
3390 GtkTreePath *append_path;
3391 GtkTreeStore *store;
3392 GtkTreeModel *filter;
3396 GtkWidget *tree_view;
3398 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
3400 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
3401 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
3402 GINT_TO_POINTER (FALSE));
3403 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3404 specific_append_after_collapse_visible_func,
3407 sort = gtk_tree_model_sort_new_with_model (filter);
3409 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3410 tree_view = gtk_tree_view_new_with_model (sort);
3411 gtk_container_add (GTK_CONTAINER (window), tree_view);
3412 gtk_widget_realize (tree_view);
3414 while (gtk_events_pending ())
3415 gtk_main_iteration ();
3417 gtk_tree_store_prepend (store, &iter, NULL);
3418 gtk_tree_store_set (store, &iter,
3419 0, "hallo", 1, 1, -1);
3421 gtk_tree_store_append (store, &child_iter, &iter);
3422 gtk_tree_store_set (store, &child_iter,
3423 0, "toemaar", 1, 1, -1);
3425 gtk_tree_store_append (store, &child_iter2, &child_iter);
3426 gtk_tree_store_set (store, &child_iter2,
3427 0, "very deep", 1, 1, -1);
3429 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
3431 gtk_tree_store_append (store, &child_iter, &iter);
3432 gtk_tree_store_set (store, &child_iter,
3433 0, "sja", 1, 1, -1);
3435 gtk_tree_store_append (store, &child_iter, &iter);
3436 gtk_tree_store_set (store, &child_iter,
3437 0, "some word", 1, -1, -1);
3439 /* Expand and collapse the tree */
3440 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3441 while (gtk_events_pending ())
3442 gtk_main_iteration ();
3444 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
3445 while (gtk_events_pending ())
3446 gtk_main_iteration ();
3448 /* Add another it */
3449 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
3450 GINT_TO_POINTER (TRUE));
3452 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
3454 gtk_tree_store_append (store, &child_iter, &iter);
3455 gtk_tree_store_set (store, &child_iter,
3456 0, "new new new !!", 1, 1, -1);
3458 gtk_tree_path_free (append_path);
3461 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3462 while (gtk_events_pending ())
3463 gtk_main_iteration ();
3468 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
3477 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
3483 /* Do reference the model */
3484 gtk_tree_model_get (model, iter, 0, &item, -1);
3491 specific_sort_filter_remove_node (void)
3493 /* This test is based on one of the test cases I found in my
3494 * old test cases directory. I unfortunately do not have a record
3495 * from who this test case originated. -Kris.
3498 * - Create tree store, sort, filter models. The sort model has
3499 * a default sort func that is enabled, filter model a visible func
3500 * that defaults to returning FALSE.
3501 * - Remove a node from the tree store.
3505 GtkTreeStore *store;
3506 GtkTreeModel *filter;
3510 GtkWidget *tree_view;
3512 store = gtk_tree_store_new (1, G_TYPE_STRING);
3513 gtk_tree_store_append (store, &iter, NULL);
3514 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
3516 gtk_tree_store_append (store, &iter, NULL);
3517 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
3519 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
3520 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
3521 specific_sort_filter_remove_node_compare_func, NULL, NULL);
3523 filter = gtk_tree_model_filter_new (sort, NULL);
3524 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3525 specific_sort_filter_remove_node_visible_func,
3529 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3530 tree_view = gtk_tree_view_new_with_model (filter);
3531 gtk_container_add (GTK_CONTAINER (window), tree_view);
3532 gtk_widget_realize (tree_view);
3534 while (gtk_events_pending ())
3535 gtk_main_iteration ();
3538 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
3539 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
3540 gtk_tree_store_remove (store, &iter);
3542 while (gtk_events_pending ())
3543 gtk_main_iteration ();
3548 specific_sort_filter_remove_root (void)
3550 /* This test is based on one of the test cases I found in my
3551 * old test cases directory. I unfortunately do not have a record
3552 * from who this test case originated. -Kris.
3555 GtkTreeModel *model, *sort, *filter;
3556 GtkTreeIter root, mid, leaf;
3559 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
3560 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
3561 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
3562 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
3564 path = gtk_tree_model_get_path (model, &mid);
3566 sort = gtk_tree_model_sort_new_with_model (model);
3567 filter = gtk_tree_model_filter_new (sort, path);
3569 gtk_tree_path_free (path);
3571 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
3573 g_object_unref (filter);
3574 g_object_unref (sort);
3575 g_object_unref (model);
3580 specific_root_mixed_visibility (void)
3583 GtkTreeModel *filter;
3584 /* A bit nasty, apologies */
3587 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3589 for (i = 0; i < LEVEL_LENGTH; i++)
3593 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
3595 create_tree_store_set_values (fixture.store, &iter, TRUE);
3597 create_tree_store_set_values (fixture.store, &iter, FALSE);
3600 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3601 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3602 fixture.monitor = NULL;
3604 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
3606 /* In order to trigger the potential bug, we should not access
3607 * the filter model here (so don't call the check functions).
3610 /* Change visibility of an odd row to TRUE */
3611 set_path_visibility (&fixture, "3", TRUE);
3612 check_filter_model (&fixture);
3613 check_level_length (fixture.filter, NULL, 4);
3619 specific_has_child_filter_filter_func (GtkTreeModel *model,
3623 return gtk_tree_model_iter_has_child (model, iter);
3627 specific_has_child_filter (void)
3629 GtkTreeModel *filter;
3630 GtkTreeIter iter, root;
3631 FilterTest fixture; /* This is not how it should be done */
3632 GtkWidget *tree_view;
3634 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3635 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3636 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3637 fixture.monitor = signal_monitor_new (filter);
3639 tree_view = gtk_tree_view_new_with_model (filter);
3641 /* We will filter on parent state using a filter function. We will
3642 * manually keep the boolean column in sync, so that we can use
3643 * check_filter_model() to check the consistency of the model.
3645 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3646 * to be able to check the structure here. We keep the calls to
3647 * check_filter_model() commented out until then.
3649 gtk_tree_model_filter_set_visible_func (fixture.filter,
3650 specific_has_child_filter_filter_func,
3653 /* The first node will be initially invisible: no signals */
3654 gtk_tree_store_append (fixture.store, &root, NULL);
3655 create_tree_store_set_values (fixture.store, &root, FALSE);
3657 /* check_filter_model (&fixture); */
3658 check_level_length (fixture.filter, NULL, 0);
3659 signal_monitor_assert_is_empty (fixture.monitor);
3661 /* Insert a child node. This will cause the parent to become visible
3662 * since there is a child now.
3664 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3665 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3666 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3668 gtk_tree_store_append (fixture.store, &iter, &root);
3669 create_tree_store_set_values (fixture.store, &iter, TRUE);
3671 /* Parent must now be visible. Do the level length check first,
3672 * to avoid modifying the child model triggering a row-changed to
3675 check_level_length (fixture.filter, NULL, 1);
3676 check_level_length (fixture.filter, "0", 0);
3677 signal_monitor_assert_is_empty (fixture.monitor);
3679 /* This should propagate row-changed */
3680 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3681 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3683 set_path_visibility (&fixture, "0", TRUE);
3684 /* check_filter_model (&fixture); */
3685 signal_monitor_assert_is_empty (fixture.monitor);
3687 /* New root node, no child, so no signal */
3688 gtk_tree_store_append (fixture.store, &root, NULL);
3689 check_level_length (fixture.filter, NULL, 1);
3690 signal_monitor_assert_is_empty (fixture.monitor);
3692 /* When the child comes in, this node will become visible */
3693 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
3694 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3695 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3696 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
3697 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3699 gtk_tree_store_append (fixture.store, &iter, &root);
3700 check_level_length (fixture.filter, NULL, 2);
3701 check_level_length (fixture.filter, "1", 0);
3703 create_tree_store_set_values (fixture.store, &root, TRUE);
3704 create_tree_store_set_values (fixture.store, &iter, TRUE);
3706 /* check_filter_model (&fixture); */
3707 signal_monitor_assert_is_empty (fixture.monitor);
3709 /* Add another child for 1 */
3710 gtk_tree_store_append (fixture.store, &iter, &root);
3711 create_tree_store_set_values (fixture.store, &iter, TRUE);
3712 check_level_length (fixture.filter, NULL, 2);
3713 check_level_length (fixture.filter, "0", 0);
3714 check_level_length (fixture.filter, "1", 0);
3715 signal_monitor_assert_is_empty (fixture.monitor);
3717 /* Now remove one of the remaining child rows */
3718 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
3720 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
3722 gtk_tree_store_remove (fixture.store, &iter);
3724 check_level_length (fixture.filter, NULL, 1);
3725 check_level_length (fixture.filter, "0", 0);
3727 set_path_visibility (&fixture, "0", FALSE);
3728 /* check_filter_model (&fixture); */
3729 signal_monitor_assert_is_empty (fixture.monitor);
3734 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
3741 path = gtk_tree_model_get_path (model, iter);
3742 depth = gtk_tree_path_get_depth (path);
3743 gtk_tree_path_free (path);
3748 return gtk_tree_model_iter_has_child (model, iter);
3752 specific_root_has_child_filter (void)
3754 GtkTreeModel *filter;
3755 GtkTreeIter iter, root;
3756 FilterTest fixture; /* This is not how it should be done ... */
3757 GtkWidget *tree_view;
3759 /* This is a variation on the above test case, specific has-child-filter,
3760 * herein the has-child check for visibility only applies to root level
3761 * nodes. In this test, children are always visible because we
3762 * only filter based on the "has child" criterion.
3765 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3766 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3767 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3768 fixture.monitor = signal_monitor_new (filter);
3770 tree_view = gtk_tree_view_new_with_model (filter);
3772 /* We will filter on parent state using a filter function. We will
3773 * manually keep the boolean column in sync, so that we can use
3774 * check_filter_model() to check the consistency of the model.
3776 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3777 * to be able to check the structure here. We keep the calls to
3778 * check_filter_model() commented out until then.
3780 gtk_tree_model_filter_set_visible_func (fixture.filter,
3781 specific_root_has_child_filter_filter_func,
3784 /* Add a first node, this will be invisible initially, so no signal
3785 * should be emitted.
3787 gtk_tree_store_append (fixture.store, &root, NULL);
3788 create_tree_store_set_values (fixture.store, &root, FALSE);
3790 signal_monitor_assert_is_empty (fixture.monitor);
3791 /* check_filter_model (&fixture); */
3792 check_level_length (fixture.filter, NULL, 0);
3794 /* Add a child node. This will cause the parent to become visible,
3795 * so we expect row-inserted signals for both.
3797 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3798 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3799 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3801 gtk_tree_store_append (fixture.store, &iter, &root);
3802 signal_monitor_assert_is_empty (fixture.monitor);
3804 check_level_length (fixture.filter, NULL, 1);
3805 check_level_length (fixture.filter, "0", 1);
3807 /* Modify the content of iter, no signals because the parent is not
3810 create_tree_store_set_values (fixture.store, &iter, TRUE);
3811 signal_monitor_assert_is_empty (fixture.monitor);
3813 /* Parent must now be visible. Do the level length check first,
3814 * to avoid modifying the child model triggering a row-changed to
3817 check_level_length (fixture.filter, NULL, 1);
3818 check_level_length (fixture.filter, "0", 1);
3821 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3822 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3824 set_path_visibility (&fixture, "0", TRUE);
3825 /* check_filter_model (&fixture); */
3827 signal_monitor_assert_is_empty (fixture.monitor);
3829 /* Insert another node in the root level. Initially invisible, so
3830 * not expecting any signal.
3832 gtk_tree_store_append (fixture.store, &root, NULL);
3833 check_level_length (fixture.filter, NULL, 1);
3835 signal_monitor_assert_is_empty (fixture.monitor);
3837 /* Adding a child node which also makes parent at path 1 visible. */
3838 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
3839 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3840 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3842 gtk_tree_store_append (fixture.store, &iter, &root);
3843 check_level_length (fixture.filter, NULL, 2);
3844 check_level_length (fixture.filter, "1", 1);
3846 signal_monitor_assert_is_empty (fixture.monitor);
3848 /* Check if row-changed is propagated */
3849 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
3850 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3852 create_tree_store_set_values (fixture.store, &root, TRUE);
3853 create_tree_store_set_values (fixture.store, &iter, TRUE);
3854 /* check_filter_model (&fixture); */
3855 signal_monitor_assert_is_empty (fixture.monitor);
3857 /* Insert another child under node 1 */
3858 gtk_tree_store_append (fixture.store, &iter, &root);
3859 create_tree_store_set_values (fixture.store, &iter, TRUE);
3860 check_level_length (fixture.filter, NULL, 2);
3861 check_level_length (fixture.filter, "0", 1);
3862 check_level_length (fixture.filter, "1", 2);
3863 signal_monitor_assert_is_empty (fixture.monitor);
3865 /* Set a child node to invisible. This should not yield any
3866 * change, because filtering is only done on whether the root
3867 * node has a child, which it still has.
3869 set_path_visibility (&fixture, "0:0", FALSE);
3870 signal_monitor_assert_is_empty (fixture.monitor);
3872 /* Now remove one of the remaining child rows */
3873 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3874 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
3876 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
3878 gtk_tree_store_remove (fixture.store, &iter);
3880 check_level_length (fixture.filter, NULL, 1);
3881 check_level_length (fixture.filter, "0", 2);
3882 signal_monitor_assert_is_empty (fixture.monitor);
3884 /* Set visibility of 0 to FALSE, no-op for filter model since
3885 * the child 0:0 is already gone
3887 set_path_visibility (&fixture, "0", FALSE);
3888 /* check_filter_model (&fixture); */
3889 signal_monitor_assert_is_empty (fixture.monitor);
3893 specific_has_child_filter_on_sort_model (void)
3895 GtkTreeModel *filter;
3896 GtkTreeModel *sort_model;
3897 GtkTreeIter iter, root;
3898 FilterTest fixture; /* This is not how it should be done */
3899 GtkWidget *tree_view;
3901 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3902 sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
3903 filter = gtk_tree_model_filter_new (sort_model, NULL);
3904 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3905 fixture.monitor = signal_monitor_new (filter);
3907 tree_view = gtk_tree_view_new_with_model (filter);
3909 /* We will filter on parent state using a filter function. We will
3910 * manually keep the boolean column in sync, so that we can use
3911 * check_filter_model() to check the consistency of the model.
3913 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3914 * to be able to check the structure here. We keep the calls to
3915 * check_filter_model() commented out until then.
3917 gtk_tree_model_filter_set_visible_func (fixture.filter,
3918 specific_has_child_filter_filter_func,
3921 /* The first node will be initially invisible: no signals */
3922 gtk_tree_store_append (fixture.store, &root, NULL);
3923 create_tree_store_set_values (fixture.store, &root, FALSE);
3925 /* check_filter_model (&fixture); */
3926 check_level_length (fixture.filter, NULL, 0);
3927 signal_monitor_assert_is_empty (fixture.monitor);
3929 /* Insert a child node. This will cause the parent to become visible
3930 * since there is a child now.
3932 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3933 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3935 gtk_tree_store_append (fixture.store, &iter, &root);
3936 create_tree_store_set_values (fixture.store, &iter, TRUE);
3938 /* Parent must now be visible. Do the level length check first,
3939 * to avoid modifying the child model triggering a row-changed to
3942 check_level_length (fixture.filter, NULL, 1);
3943 check_level_length (fixture.filter, "0", 0);
3944 signal_monitor_assert_is_empty (fixture.monitor);
3946 /* This should propagate row-changed */
3947 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3948 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3950 set_path_visibility (&fixture, "0", TRUE);
3951 /* check_filter_model (&fixture); */
3952 signal_monitor_assert_is_empty (fixture.monitor);
3954 /* New root node, no child, so no signal */
3955 gtk_tree_store_append (fixture.store, &root, NULL);
3956 check_level_length (fixture.filter, NULL, 1);
3957 signal_monitor_assert_is_empty (fixture.monitor);
3959 /* When the child comes in, this node will become visible */
3960 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
3961 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3962 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
3963 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3965 gtk_tree_store_append (fixture.store, &iter, &root);
3966 check_level_length (fixture.filter, NULL, 2);
3967 check_level_length (fixture.filter, "1", 0);
3969 create_tree_store_set_values (fixture.store, &root, TRUE);
3970 create_tree_store_set_values (fixture.store, &iter, TRUE);
3972 /* check_filter_model (&fixture); */
3973 signal_monitor_assert_is_empty (fixture.monitor);
3975 /* Add another child for 1 */
3976 gtk_tree_store_append (fixture.store, &iter, &root);
3977 create_tree_store_set_values (fixture.store, &iter, TRUE);
3978 check_level_length (fixture.filter, NULL, 2);
3979 check_level_length (fixture.filter, "0", 0);
3980 check_level_length (fixture.filter, "1", 0);
3981 signal_monitor_assert_is_empty (fixture.monitor);
3983 /* Now remove one of the remaining child rows */
3984 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
3986 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
3988 gtk_tree_store_remove (fixture.store, &iter);
3990 check_level_length (fixture.filter, NULL, 1);
3991 check_level_length (fixture.filter, "0", 0);
3993 set_path_visibility (&fixture, "0", FALSE);
3994 /* check_filter_model (&fixture); */
3995 signal_monitor_assert_is_empty (fixture.monitor);
3999 specific_at_least_2_children_filter_filter_func (GtkTreeModel *model,
4003 return gtk_tree_model_iter_n_children (model, iter) >= 2;
4007 specific_at_least_2_children_filter (void)
4009 GtkTreeModel *filter;
4010 GtkTreeIter iter, root;
4011 FilterTest fixture; /* This is not how it should be done */
4012 GtkWidget *tree_view;
4014 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4015 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
4016 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4017 fixture.monitor = signal_monitor_new (filter);
4019 tree_view = gtk_tree_view_new_with_model (filter);
4021 gtk_tree_model_filter_set_visible_func (fixture.filter,
4022 specific_at_least_2_children_filter_filter_func,
4025 /* The first node will be initially invisible: no signals */
4026 gtk_tree_store_append (fixture.store, &root, NULL);
4027 create_tree_store_set_values (fixture.store, &root, FALSE);
4029 /* check_filter_model (&fixture); */
4030 check_level_length (fixture.filter, NULL, 0);
4031 signal_monitor_assert_is_empty (fixture.monitor);
4033 /* Insert a child node. Nothing should happen.
4035 gtk_tree_store_append (fixture.store, &iter, &root);
4036 create_tree_store_set_values (fixture.store, &iter, TRUE);
4038 check_level_length (fixture.filter, NULL, 0);
4039 signal_monitor_assert_is_empty (fixture.monitor);
4041 /* Insert a second child node. This will cause the parent to become
4044 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4045 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4047 gtk_tree_store_append (fixture.store, &iter, &root);
4048 create_tree_store_set_values (fixture.store, &iter, TRUE);
4050 /* Parent must now be visible. Do the level length check first,
4051 * to avoid modifying the child model triggering a row-changed to
4054 check_level_length (fixture.filter, NULL, 1);
4055 check_level_length (fixture.filter, "0", 0);
4056 signal_monitor_assert_is_empty (fixture.monitor);
4058 /* This should propagate row-changed */
4059 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4060 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4062 set_path_visibility (&fixture, "0", TRUE);
4063 /* check_filter_model (&fixture); */
4064 signal_monitor_assert_is_empty (fixture.monitor);
4066 /* New root node, no child, so no signal */
4067 gtk_tree_store_append (fixture.store, &root, NULL);
4068 check_level_length (fixture.filter, NULL, 1);
4069 signal_monitor_assert_is_empty (fixture.monitor);
4071 /* First child, no signal, no change */
4072 gtk_tree_store_append (fixture.store, &iter, &root);
4073 check_level_length (fixture.filter, NULL, 1);
4074 signal_monitor_assert_is_empty (fixture.monitor);
4076 /* When the second child comes in, this node will become visible */
4077 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
4078 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4079 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
4080 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4082 gtk_tree_store_append (fixture.store, &iter, &root);
4083 check_level_length (fixture.filter, NULL, 2);
4084 check_level_length (fixture.filter, "1", 0);
4086 create_tree_store_set_values (fixture.store, &root, TRUE);
4087 create_tree_store_set_values (fixture.store, &iter, TRUE);
4089 /* check_filter_model (&fixture); */
4090 signal_monitor_assert_is_empty (fixture.monitor);
4092 /* Add another child for 1 */
4093 gtk_tree_store_append (fixture.store, &iter, &root);
4094 create_tree_store_set_values (fixture.store, &iter, TRUE);
4095 check_level_length (fixture.filter, NULL, 2);
4096 check_level_length (fixture.filter, "0", 0);
4097 check_level_length (fixture.filter, "1", 0);
4098 signal_monitor_assert_is_empty (fixture.monitor);
4100 /* Now remove one of the remaining child rows */
4101 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4103 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4105 gtk_tree_store_remove (fixture.store, &iter);
4107 check_level_length (fixture.filter, NULL, 1);
4108 check_level_length (fixture.filter, "0", 0);
4110 set_path_visibility (&fixture, "0", FALSE);
4111 /* check_filter_model (&fixture); */
4112 signal_monitor_assert_is_empty (fixture.monitor);
4116 specific_at_least_2_children_filter_on_sort_model (void)
4118 GtkTreeModel *filter;
4119 GtkTreeModel *sort_model;
4120 GtkTreeIter iter, root;
4121 FilterTest fixture; /* This is not how it should be done */
4122 GtkWidget *tree_view;
4124 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4125 sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
4126 filter = gtk_tree_model_filter_new (sort_model, NULL);
4127 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4128 fixture.monitor = signal_monitor_new (filter);
4130 tree_view = gtk_tree_view_new_with_model (filter);
4132 gtk_tree_model_filter_set_visible_func (fixture.filter,
4133 specific_at_least_2_children_filter_filter_func,
4136 /* The first node will be initially invisible: no signals */
4137 gtk_tree_store_append (fixture.store, &root, NULL);
4138 create_tree_store_set_values (fixture.store, &root, FALSE);
4140 /* check_filter_model (&fixture); */
4141 check_level_length (fixture.filter, NULL, 0);
4142 signal_monitor_assert_is_empty (fixture.monitor);
4144 /* Insert a child node. Nothing should happen.
4146 gtk_tree_store_append (fixture.store, &iter, &root);
4147 create_tree_store_set_values (fixture.store, &iter, TRUE);
4149 check_level_length (fixture.filter, NULL, 0);
4150 signal_monitor_assert_is_empty (fixture.monitor);
4153 GtkTreePath *path = gtk_tree_path_new_from_indices (0, 0, -1);
4154 GtkTreeRowReference *ref;
4156 ref = gtk_tree_row_reference_new (sort_model, path);
4157 gtk_tree_path_free (path);
4160 /* Insert a second child node. This will cause the parent to become
4163 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4164 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4166 gtk_tree_store_append (fixture.store, &iter, &root);
4167 create_tree_store_set_values (fixture.store, &iter, TRUE);
4169 /* Parent must now be visible. Do the level length check first,
4170 * to avoid modifying the child model triggering a row-changed to
4173 check_level_length (fixture.filter, NULL, 1);
4174 check_level_length (fixture.filter, "0", 0);
4175 signal_monitor_assert_is_empty (fixture.monitor);
4177 /* This should propagate row-changed */
4178 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4179 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4181 set_path_visibility (&fixture, "0", TRUE);
4182 /* check_filter_model (&fixture); */
4183 signal_monitor_assert_is_empty (fixture.monitor);
4185 /* New root node, no child, so no signal */
4186 gtk_tree_store_append (fixture.store, &root, NULL);
4187 check_level_length (fixture.filter, NULL, 1);
4188 signal_monitor_assert_is_empty (fixture.monitor);
4193 specific_filter_add_child (void)
4195 /* This test is based on one of the test cases I found in my
4196 * old test cases directory. I unfortunately do not have a record
4197 * from who this test case originated. -Kris.
4201 GtkTreeIter iter_first;
4203 GtkTreeStore *store;
4204 GtkTreeModel *filter G_GNUC_UNUSED;
4206 store = gtk_tree_store_new (1, G_TYPE_STRING);
4208 gtk_tree_store_append (store, &iter_first, NULL);
4209 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
4211 gtk_tree_store_append (store, &iter, NULL);
4212 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4214 gtk_tree_store_append (store, &iter, NULL);
4215 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4217 gtk_tree_store_append (store, &iter, NULL);
4218 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4220 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4222 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4223 gtk_tree_store_append (store, &child, &iter_first);
4224 gtk_tree_store_set (store, &child, 0, "Hello", -1);
4228 specific_list_store_clear (void)
4232 GtkTreeModel *filter;
4233 GtkWidget *view G_GNUC_UNUSED;
4235 list = gtk_list_store_new (1, G_TYPE_INT);
4236 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
4237 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
4238 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
4239 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
4240 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
4241 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
4242 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
4243 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
4245 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
4246 view = gtk_tree_view_new_with_model (filter);
4248 gtk_list_store_clear (list);
4252 specific_sort_ref_leaf_and_remove_ancestor (void)
4254 GtkTreeIter iter, child, child2, child3;
4258 GtkTreeRowReference *rowref;
4259 GtkWidget *view G_GNUC_UNUSED;
4261 tree = gtk_tree_store_new (1, G_TYPE_INT);
4262 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4263 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4264 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4265 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4267 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4268 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4269 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4271 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
4272 view = gtk_tree_view_new_with_model (sort);
4273 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4275 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4276 rowref = gtk_tree_row_reference_new (sort, path);
4277 gtk_tree_path_free (path);
4279 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4280 rowref = gtk_tree_row_reference_new (sort, path);
4281 gtk_tree_path_free (path);
4283 path = gtk_tree_path_new_from_indices (3, 0, -1);
4284 rowref = gtk_tree_row_reference_new (sort, path);
4285 gtk_tree_path_free (path);
4287 path = gtk_tree_path_new_from_indices (3, -1);
4288 rowref = gtk_tree_row_reference_new (sort, path);
4289 gtk_tree_path_free (path);
4291 /* Deleting a parent */
4292 path = gtk_tree_path_new_from_indices (3, 0, -1);
4293 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4294 gtk_tree_store_remove (tree, &iter);
4295 gtk_tree_path_free (path);
4297 gtk_tree_row_reference_free (rowref);
4301 specific_ref_leaf_and_remove_ancestor (void)
4303 GtkTreeIter iter, child, child2, child3;
4305 GtkTreeModel *filter;
4307 GtkTreeRowReference *rowref;
4308 GtkWidget *view G_GNUC_UNUSED;
4310 tree = gtk_tree_store_new (1, G_TYPE_INT);
4311 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4312 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4313 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4314 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4316 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4317 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4318 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4320 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), NULL);
4321 view = gtk_tree_view_new_with_model (filter);
4322 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4324 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4325 rowref = gtk_tree_row_reference_new (filter, path);
4326 gtk_tree_path_free (path);
4328 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4329 rowref = gtk_tree_row_reference_new (filter, path);
4330 gtk_tree_path_free (path);
4332 path = gtk_tree_path_new_from_indices (3, 0, -1);
4333 rowref = gtk_tree_row_reference_new (filter, path);
4334 gtk_tree_path_free (path);
4336 path = gtk_tree_path_new_from_indices (3, -1);
4337 rowref = gtk_tree_row_reference_new (filter, path);
4338 gtk_tree_path_free (path);
4340 /* Deleting a parent */
4341 path = gtk_tree_path_new_from_indices (3, 0, -1);
4342 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4343 gtk_tree_store_remove (tree, &iter);
4344 gtk_tree_path_free (path);
4346 gtk_tree_row_reference_free (rowref);
4350 specific_virtual_ref_leaf_and_remove_ancestor (void)
4352 GtkTreeIter iter, child, child2, child3;
4354 GtkTreeModel *filter;
4356 GtkTreeRowReference *rowref;
4357 GtkWidget *view G_GNUC_UNUSED;
4359 tree = gtk_tree_store_new (1, G_TYPE_INT);
4360 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4361 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4362 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4363 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4365 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4366 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4367 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4369 /* Set a virtual root of 3:0 */
4370 path = gtk_tree_path_new_from_indices (3, 0, -1);
4371 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
4372 gtk_tree_path_free (path);
4374 view = gtk_tree_view_new_with_model (filter);
4375 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4377 path = gtk_tree_path_new_from_indices (0, 0, -1);
4378 rowref = gtk_tree_row_reference_new (filter, path);
4379 gtk_tree_path_free (path);
4381 path = gtk_tree_path_new_from_indices (0, 0, -1);
4382 rowref = gtk_tree_row_reference_new (filter, path);
4383 gtk_tree_path_free (path);
4385 path = gtk_tree_path_new_from_indices (0, -1);
4386 rowref = gtk_tree_row_reference_new (filter, path);
4387 gtk_tree_path_free (path);
4389 /* Deleting the virtual root */
4390 path = gtk_tree_path_new_from_indices (3, 0, -1);
4391 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4392 gtk_tree_store_remove (tree, &iter);
4393 gtk_tree_path_free (path);
4395 gtk_tree_row_reference_free (rowref);
4400 specific_bug_301558_sort_func (GtkTreeModel *model,
4407 gtk_tree_model_get (model, a, 0, &i, -1);
4408 gtk_tree_model_get (model, b, 0, &j, -1);
4414 specific_bug_301558 (void)
4416 /* Test case for GNOME Bugzilla bug 301558 provided by
4420 GtkTreeModel *filter;
4422 GtkTreeIter root, iter, iter2;
4423 GtkWidget *view G_GNUC_UNUSED;
4427 g_test_bug ("301558");
4429 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
4430 gtk_tree_store_append (tree, &iter, NULL);
4431 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
4432 gtk_tree_store_append (tree, &iter2, &iter);
4433 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
4435 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
4436 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
4437 specific_bug_301558_sort_func,
4440 filter = gtk_tree_model_filter_new (sort, NULL);
4441 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
4443 view = gtk_tree_view_new_with_model (filter);
4445 while (gtk_events_pending ())
4446 gtk_main_iteration ();
4450 for (i = 0; i < 10; i++)
4452 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
4453 g_assert_not_reached ();
4457 gtk_tree_store_append (tree, &iter, &root);
4458 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
4463 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
4464 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
4466 gtk_tree_store_remove (tree, &iter);
4475 specific_bug_311955_filter_func (GtkTreeModel *model,
4481 gtk_tree_model_get (model, iter, 0, &value, -1);
4483 return (value != 0);
4487 specific_bug_311955 (void)
4489 /* This is a test case for GNOME Bugzilla bug 311955. It was written
4492 GtkTreeIter iter, child, root;
4493 GtkTreeStore *store;
4495 GtkTreeModel *filter;
4497 GtkWidget *window G_GNUC_UNUSED;
4498 GtkWidget *tree_view;
4503 g_test_bug ("311955");
4505 store = gtk_tree_store_new (1, G_TYPE_INT);
4507 gtk_tree_store_append (store, &root, NULL);
4508 gtk_tree_store_set (store, &root, 0, 33, -1);
4510 gtk_tree_store_append (store, &iter, &root);
4511 gtk_tree_store_set (store, &iter, 0, 50, -1);
4513 gtk_tree_store_append (store, &iter, NULL);
4514 gtk_tree_store_set (store, &iter, 0, 22, -1);
4516 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
4517 filter = gtk_tree_model_filter_new (sort, NULL);
4519 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4520 specific_bug_311955_filter_func,
4523 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4524 tree_view = gtk_tree_view_new_with_model (filter);
4525 g_object_unref (store);
4527 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
4529 while (gtk_events_pending ())
4530 gtk_main_iteration ();
4532 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
4533 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
4536 for (i = 0; i < 4; i++)
4538 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
4540 gtk_tree_store_append (store, &iter, &root);
4543 gtk_tree_store_set (store, &iter, 0, i, -1);
4547 gtk_tree_store_append (store, &child, &iter);
4548 gtk_tree_store_set (store, &child, 0, 10, -1);
4552 while (gtk_events_pending ())
4553 gtk_main_iteration ();
4555 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4556 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 1);
4558 /* Remove bottommost child from the tree. */
4559 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
4560 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
4562 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
4564 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
4565 gtk_tree_store_remove (store, &child);
4568 g_assert_not_reached ();
4570 path = gtk_tree_path_new_from_indices (0, 2, -1);
4571 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
4572 gtk_tree_path_free (path);
4574 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4575 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
4579 specific_bug_311955_clean (void)
4581 /* Cleaned up version of the test case for GNOME Bugzilla bug 311955,
4582 * which is easier to understand.
4584 GtkTreeIter iter, child, grandchild;
4585 GtkTreeStore *store;
4587 GtkTreeModel *filter;
4589 GtkWidget *tree_view;
4592 store = gtk_tree_store_new (1, G_TYPE_INT);
4594 gtk_tree_store_append (store, &iter, NULL);
4595 gtk_tree_store_set (store, &iter, 0, 1, -1);
4597 gtk_tree_store_append (store, &child, &iter);
4598 gtk_tree_store_set (store, &child, 0, 1, -1);
4600 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
4601 filter = gtk_tree_model_filter_new (sort, NULL);
4603 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4604 specific_bug_311955_filter_func,
4607 tree_view = gtk_tree_view_new_with_model (filter);
4608 g_object_unref (store);
4610 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
4612 while (gtk_events_pending ())
4613 gtk_main_iteration ();
4615 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
4616 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
4618 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
4620 gtk_tree_store_append (store, &child, &iter);
4621 gtk_tree_store_set (store, &child, 0, 0, -1);
4623 gtk_tree_store_append (store, &child, &iter);
4624 gtk_tree_store_set (store, &child, 0, 1, -1);
4626 gtk_tree_store_append (store, &child, &iter);
4627 gtk_tree_store_set (store, &child, 0, 1, -1);
4629 gtk_tree_store_append (store, &grandchild, &child);
4630 gtk_tree_store_set (store, &grandchild, 0, 1, -1);
4632 gtk_tree_store_append (store, &child, &iter);
4633 /* Don't set a value: assume 0 */
4635 /* Remove leaf node, check trigger row-has-child-toggled */
4636 path = gtk_tree_path_new_from_indices (0, 3, 0, -1);
4637 gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
4638 gtk_tree_path_free (path);
4639 gtk_tree_store_remove (store, &iter);
4641 path = gtk_tree_path_new_from_indices (0, 2, -1);
4642 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
4643 gtk_tree_path_free (path);
4645 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4646 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
4648 gtk_widget_destroy (tree_view);
4652 specific_bug_346800 (void)
4654 /* This is a test case for GNOME Bugzilla bug 346800. It was written
4655 * by Jonathan Matthew.
4658 GtkTreeIter node_iters[50];
4659 GtkTreeIter child_iters[50];
4660 GtkTreeModel *model;
4661 GtkTreeModelFilter *filter;
4662 GtkTreeStore *store;
4666 columns = g_new (GType, 2);
4667 columns[0] = G_TYPE_STRING;
4668 columns[1] = G_TYPE_BOOLEAN;
4669 store = gtk_tree_store_newv (2, columns);
4670 model = GTK_TREE_MODEL (store);
4672 g_test_bug ("346800");
4674 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
4675 gtk_tree_model_filter_set_visible_column (filter, 1);
4677 for (i=0; i<items; i++)
4679 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
4682 gtk_tree_store_append (store, &node_iters[i], NULL);
4683 gtk_tree_store_set (store, &node_iters[i],
4685 1, ((i%6) == 0) ? FALSE : TRUE,
4689 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
4690 gtk_tree_store_set (store, &child_iters[i],
4691 0, "something else",
4694 gtk_tree_model_filter_refilter (filter);
4698 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
4699 (i & 1) ? TRUE : FALSE, -1);
4700 gtk_tree_model_filter_refilter (filter);
4702 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
4703 (i & 1) ? FALSE: TRUE, -1);
4704 gtk_tree_model_filter_refilter (filter);
4710 specific_bug_464173_visible_func (GtkTreeModel *model,
4714 gboolean *visible = (gboolean *)data;
4720 specific_bug_464173 (void)
4722 /* Test case for GNOME Bugzilla bug 464173, test case written
4723 * by Andreas Koehler.
4725 GtkTreeStore *model;
4726 GtkTreeModelFilter *f_model;
4727 GtkTreeIter iter1, iter2;
4728 GtkWidget *view G_GNUC_UNUSED;
4729 gboolean visible = TRUE;
4731 g_test_bug ("464173");
4733 model = gtk_tree_store_new (1, G_TYPE_STRING);
4734 gtk_tree_store_append (model, &iter1, NULL);
4735 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
4736 gtk_tree_store_append (model, &iter2, &iter1);
4737 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
4739 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
4740 gtk_tree_model_filter_set_visible_func (f_model,
4741 specific_bug_464173_visible_func,
4744 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
4747 gtk_tree_model_filter_refilter (f_model);
4752 specific_bug_540201_filter_func (GtkTreeModel *model,
4756 gboolean has_children;
4758 has_children = gtk_tree_model_iter_has_child (model, iter);
4760 return has_children;
4764 specific_bug_540201 (void)
4766 /* Test case for GNOME Bugzilla bug 540201, steps provided by
4769 GtkTreeIter iter, root;
4770 GtkTreeStore *store;
4771 GtkTreeModel *filter;
4773 GtkWidget *tree_view G_GNUC_UNUSED;
4775 g_test_bug ("540201");
4777 store = gtk_tree_store_new (1, G_TYPE_INT);
4779 gtk_tree_store_append (store, &root, NULL);
4780 gtk_tree_store_set (store, &root, 0, 33, -1);
4782 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4783 tree_view = gtk_tree_view_new_with_model (filter);
4785 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4786 specific_bug_540201_filter_func,
4789 gtk_tree_store_append (store, &iter, &root);
4790 gtk_tree_store_set (store, &iter, 0, 50, -1);
4792 gtk_tree_store_append (store, &iter, &root);
4793 gtk_tree_store_set (store, &iter, 0, 22, -1);
4796 gtk_tree_store_append (store, &root, NULL);
4797 gtk_tree_store_set (store, &root, 0, 33, -1);
4799 gtk_tree_store_append (store, &iter, &root);
4800 gtk_tree_store_set (store, &iter, 0, 22, -1);
4805 specific_bug_549287_visible_func (GtkTreeModel *model,
4809 gboolean result = FALSE;
4811 result = gtk_tree_model_iter_has_child (model, iter);
4817 specific_bug_549287 (void)
4819 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
4822 GtkTreeStore *store;
4823 GtkTreeModel *filtered;
4824 GtkWidget *view G_GNUC_UNUSED;
4826 GtkTreeIter *swap, *parent, *child;
4828 g_test_bug ("529287");
4830 store = gtk_tree_store_new (1, G_TYPE_STRING);
4831 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4832 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
4833 specific_bug_549287_visible_func,
4836 view = gtk_tree_view_new_with_model (filtered);
4838 for (i = 0; i < 4; i++)
4840 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
4842 parent = gtk_tree_iter_copy (&iter);
4843 child = gtk_tree_iter_copy (&iter);
4845 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
4854 gtk_tree_store_append (store, child, parent);
4855 gtk_tree_store_set (store, child,
4859 gtk_tree_iter_free (parent);
4860 gtk_tree_iter_free (child);
4864 gtk_tree_store_append (store, &iter, NULL);
4865 gtk_tree_store_set (store, &iter,
4870 /* since we inserted something, we changed the visibility conditions: */
4871 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
4876 specific_bug_621076_visible_func (GtkTreeModel *model,
4880 gboolean visible = FALSE;
4883 gtk_tree_model_get (model, iter, 0, &str, -1);
4884 if (str != NULL && g_str_has_prefix (str, "visible"))
4890 GtkTreeIter child_iter;
4893 /* Recursively check if we have a visible child */
4894 for (valid = gtk_tree_model_iter_children (model, &child_iter, iter);
4895 valid; valid = gtk_tree_model_iter_next (model, &child_iter))
4897 if (specific_bug_621076_visible_func (model, &child_iter, data))
4912 specific_bug_621076 (void)
4914 /* Test case for GNOME Bugzilla bug 621076, provided by Xavier Claessens */
4916 /* This test case differs from has-child-filter and root-has-child-filter
4917 * in that the visible function both filters on content and model
4918 * structure. Also, it is recursive.
4921 GtkTreeStore *store;
4922 GtkTreeModel *filter;
4924 GtkTreeIter group_iter;
4925 GtkTreeIter item_iter;
4926 SignalMonitor *monitor;
4928 g_test_bug ("621076");
4930 store = gtk_tree_store_new (1, G_TYPE_STRING);
4931 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4932 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4933 specific_bug_621076_visible_func,
4936 view = gtk_tree_view_new_with_model (filter);
4937 g_object_ref_sink (view);
4939 monitor = signal_monitor_new (filter);
4941 signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
4942 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
4943 0, "visible-group-0",
4945 signal_monitor_assert_is_empty (monitor);
4947 /* visible-group-0 is not expanded, so ROW_INSERTED should not be emitted
4948 * for its children. However, ROW_HAS_CHILD_TOGGLED should be emitted on
4949 * visible-group-0 to tell the view that row can be expanded. */
4950 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
4951 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
4952 group_iter = item_iter;
4953 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
4956 signal_monitor_assert_is_empty (monitor);
4958 signal_monitor_append_signal (monitor, ROW_INSERTED, "1");
4959 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
4960 0, "visible-group-1",
4962 signal_monitor_assert_is_empty (monitor);
4964 /* We are adding an hidden item inside visible-group-1, so
4965 * ROW_HAS_CHILD_TOGGLED should not be emitted. It is emitted though,
4966 * because the signal originating at TreeStore will be propagated,
4967 * as well a generated signal because the state of the parent *could*
4968 * change by a change in the model.
4970 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
4971 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
4972 group_iter = item_iter;
4973 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
4976 signal_monitor_assert_is_empty (monitor);
4978 /* This group is invisible and its parent too. Nothing should be emitted */
4979 group_iter = item_iter;
4980 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
4983 signal_monitor_assert_is_empty (monitor);
4985 /* Adding a visible item in this group hierarchy will make all nodes
4986 * in this path visible. The first level should simply tell the view
4987 * that it now has a child, and the view will load the tree if needed
4988 * (depends on the expanded state).
4990 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
4991 group_iter = item_iter;
4992 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
4993 0, "visible-1:0:0:0",
4995 signal_monitor_assert_is_empty (monitor);
4997 check_level_length (GTK_TREE_MODEL_FILTER (filter), "1", 1);
4999 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5002 signal_monitor_assert_is_empty (monitor);
5004 /* Parent is invisible, and adding this invisible item won't change that,
5005 * so no signal should be emitted. */
5006 group_iter = item_iter;
5007 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5010 signal_monitor_assert_is_empty (monitor);
5012 /* This makes group-2 visible, so it gets inserted and tells it has
5015 signal_monitor_append_signal (monitor, ROW_INSERTED, "2");
5016 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5017 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5020 signal_monitor_assert_is_empty (monitor);
5022 /* group-2 is already visible, so this time it is a normal insertion */
5023 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5026 signal_monitor_assert_is_empty (monitor);
5029 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5032 signal_monitor_assert_is_empty (monitor);
5034 /* Parent is invisible, and adding this invisible item won't change that,
5035 * so no signal should be emitted. */
5036 group_iter = item_iter;
5037 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5040 signal_monitor_assert_is_empty (monitor);
5042 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5045 signal_monitor_assert_is_empty (monitor);
5047 /* This will make group 3 visible. */
5048 signal_monitor_append_signal (monitor, ROW_INSERTED, "3");
5049 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
5050 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
5051 gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
5052 signal_monitor_assert_is_empty (monitor);
5054 /* Make sure all groups are expanded, so the filter has the tree cached */
5055 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
5056 while (gtk_events_pending ())
5057 gtk_main_iteration ();
5059 /* Should only yield a row-changed */
5060 signal_monitor_append_signal (monitor, ROW_CHANGED, "3:0");
5061 gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
5062 signal_monitor_assert_is_empty (monitor);
5064 /* Now remove/hide some items. If a group loses its last item, the group
5065 * should be deleted instead of the item.
5068 signal_monitor_append_signal (monitor, ROW_DELETED, "2:1");
5069 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:2");
5070 gtk_tree_store_remove (store, &item_iter);
5071 signal_monitor_assert_is_empty (monitor);
5073 signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
5074 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5075 signal_monitor_append_signal (monitor, ROW_DELETED, "2");
5076 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:1");
5077 gtk_tree_store_set (store, &item_iter, 0, "invisible-2:1", -1);
5078 signal_monitor_assert_is_empty (monitor);
5080 signal_monitor_append_signal (monitor, ROW_DELETED, "1:0:0:0");
5081 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1:0:0");
5082 signal_monitor_append_signal (monitor, ROW_DELETED, "1:0");
5083 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5084 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "1:0:0:0");
5085 gtk_tree_store_remove (store, &item_iter);
5086 signal_monitor_assert_is_empty (monitor);
5088 /* Hide a group using row-changed instead of row-deleted */
5089 /* Caution: group 2 is gone, so offsets of the signals have moved. */
5090 signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
5091 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5092 signal_monitor_append_signal (monitor, ROW_DELETED, "2");
5093 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter,
5095 gtk_tree_store_set (store, &item_iter, 0, "invisible-3:1", -1);
5096 signal_monitor_assert_is_empty (monitor);
5101 GtkTreeViewColumn *col;
5103 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
5105 col = gtk_tree_view_column_new_with_attributes ("foo",
5106 gtk_cell_renderer_text_new (),
5108 gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
5110 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5111 g_signal_connect (window, "delete-event",
5112 G_CALLBACK (gtk_widget_destroy), NULL);
5113 g_signal_connect (window, "destroy",
5114 G_CALLBACK (gtk_main_quit), NULL);
5116 gtk_container_add (GTK_CONTAINER (window), view);
5118 gtk_widget_show (view);
5119 gtk_widget_show (window);
5126 signal_monitor_free (monitor);
5127 g_object_unref (view);
5128 g_object_unref (store);
5129 g_object_unref (filter);
5135 register_filter_model_tests (void)
5137 g_test_add ("/TreeModelFilter/self/verify-test-suite",
5141 filter_test_teardown);
5143 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-1",
5144 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5146 verify_test_suite_vroot,
5147 filter_test_teardown);
5148 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-2",
5149 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
5151 verify_test_suite_vroot,
5152 filter_test_teardown);
5155 g_test_add ("/TreeModelFilter/filled/hide-root-level",
5158 filled_hide_root_level,
5159 filter_test_teardown);
5160 g_test_add ("/TreeModelFilter/filled/hide-child-levels",
5163 filled_hide_child_levels,
5164 filter_test_teardown);
5165 g_test_add ("/TreeModelFilter/filled/hide-child-levels/root-expanded",
5168 filled_hide_child_levels_root_expanded,
5169 filter_test_teardown);
5171 g_test_add ("/TreeModelFilter/filled/hide-root-level/vroot",
5172 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5174 filled_vroot_hide_root_level,
5175 filter_test_teardown);
5176 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot",
5177 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5179 filled_vroot_hide_child_levels,
5180 filter_test_teardown);
5181 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot-root-expanded",
5182 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5184 filled_vroot_hide_child_levels_root_expanded,
5185 filter_test_teardown);
5188 g_test_add ("/TreeModelFilter/empty/show-nodes",
5190 filter_test_setup_empty,
5192 filter_test_teardown);
5193 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes",
5195 filter_test_setup_empty,
5196 empty_show_multiple_nodes,
5197 filter_test_teardown);
5199 g_test_add ("/TreeModelFilter/empty/show-nodes/vroot",
5200 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5201 filter_test_setup_empty,
5202 empty_vroot_show_nodes,
5203 filter_test_teardown);
5204 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes/vroot",
5205 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5206 filter_test_setup_empty,
5207 empty_vroot_show_multiple_nodes,
5208 filter_test_teardown);
5211 g_test_add ("/TreeModelFilter/unfiltered/hide-single",
5213 filter_test_setup_unfiltered,
5214 unfiltered_hide_single,
5215 filter_test_teardown);
5216 g_test_add ("/TreeModelFilter/unfiltered/hide-single/root-expanded",
5218 filter_test_setup_unfiltered_root_expanded,
5219 unfiltered_hide_single_root_expanded,
5220 filter_test_teardown);
5221 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child",
5223 filter_test_setup_unfiltered,
5224 unfiltered_hide_single_child,
5225 filter_test_teardown);
5226 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/root-expanded",
5228 filter_test_setup_unfiltered_root_expanded,
5229 unfiltered_hide_single_child_root_expanded,
5230 filter_test_teardown);
5231 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level",
5233 filter_test_setup_unfiltered,
5234 unfiltered_hide_single_multi_level,
5235 filter_test_teardown);
5236 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/root-expanded",
5238 filter_test_setup_unfiltered_root_expanded,
5239 unfiltered_hide_single_multi_level_root_expanded,
5240 filter_test_teardown);
5242 g_test_add ("/TreeModelFilter/unfiltered/hide-single/vroot",
5243 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5244 filter_test_setup_unfiltered,
5245 unfiltered_vroot_hide_single,
5246 filter_test_teardown);
5247 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot",
5248 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5249 filter_test_setup_unfiltered,
5250 unfiltered_vroot_hide_single_child,
5251 filter_test_teardown);
5252 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot/root-expanded",
5253 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5254 filter_test_setup_unfiltered_root_expanded,
5255 unfiltered_vroot_hide_single_child_root_expanded,
5256 filter_test_teardown);
5257 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot",
5258 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5259 filter_test_setup_unfiltered,
5260 unfiltered_vroot_hide_single_multi_level,
5261 filter_test_teardown);
5262 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot/root-expanded",
5263 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5264 filter_test_setup_unfiltered_root_expanded,
5265 unfiltered_vroot_hide_single_multi_level_root_expanded,
5266 filter_test_teardown);
5270 g_test_add ("/TreeModelFilter/unfiltered/show-single",
5272 filter_test_setup_empty_unfiltered,
5273 unfiltered_show_single,
5274 filter_test_teardown);
5275 g_test_add ("/TreeModelFilter/unfiltered/show-single-child",
5277 filter_test_setup_empty_unfiltered,
5278 unfiltered_show_single_child,
5279 filter_test_teardown);
5280 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/root-expanded",
5282 filter_test_setup_empty_unfiltered_root_expanded,
5283 unfiltered_show_single_child_root_expanded,
5284 filter_test_teardown);
5285 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level",
5287 filter_test_setup_empty_unfiltered,
5288 unfiltered_show_single_multi_level,
5289 filter_test_teardown);
5290 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/root-expanded",
5292 filter_test_setup_empty_unfiltered_root_expanded,
5293 unfiltered_show_single_multi_level_root_expanded,
5294 filter_test_teardown);
5296 g_test_add ("/TreeModelFilter/unfiltered/show-single/vroot",
5297 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5298 filter_test_setup_empty_unfiltered,
5299 unfiltered_vroot_show_single,
5300 filter_test_teardown);
5301 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot",
5302 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5303 filter_test_setup_empty_unfiltered,
5304 unfiltered_vroot_show_single_child,
5305 filter_test_teardown);
5306 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot/root-expanded",
5307 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5308 filter_test_setup_empty_unfiltered_root_expanded,
5309 unfiltered_vroot_show_single_child_root_expanded,
5310 filter_test_teardown);
5311 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot",
5312 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5313 filter_test_setup_empty_unfiltered,
5314 unfiltered_vroot_show_single_multi_level,
5315 filter_test_teardown);
5316 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot/root-expanded",
5317 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5318 filter_test_setup_empty_unfiltered_root_expanded,
5319 unfiltered_vroot_show_single_multi_level_root_expanded,
5320 filter_test_teardown);
5323 g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/root-level",
5325 filter_test_setup_unfiltered,
5326 unfiltered_rows_reordered_root_level,
5327 filter_test_teardown);
5328 g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/child-level",
5330 filter_test_setup_unfiltered,
5331 unfiltered_rows_reordered_child_level,
5332 filter_test_teardown);
5334 g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/first-hidden",
5337 filtered_rows_reordered_root_level_first_hidden,
5338 filter_test_teardown);
5339 g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/middle-hidden",
5342 filtered_rows_reordered_root_level_middle_hidden,
5343 filter_test_teardown);
5344 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/first-hidden",
5347 filtered_rows_reordered_child_level_first_hidden,
5348 filter_test_teardown);
5349 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/middle-hidden",
5352 filtered_rows_reordered_child_level_middle_hidden,
5353 filter_test_teardown);
5354 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/4-hidden",
5357 filtered_rows_reordered_child_level_4_hidden,
5358 filter_test_teardown);
5359 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/all-hidden",
5362 filtered_rows_reordered_child_level_all_hidden,
5363 filter_test_teardown);
5365 /* Inserts in child models after creation of filter model */
5366 g_test_add_func ("/TreeModelFilter/insert/before",
5368 g_test_add_func ("/TreeModelFilter/insert/child",
5371 /* Removals from child model after creating of filter model */
5372 g_test_add_func ("/TreeModelFilter/remove/node",
5374 g_test_add_func ("/TreeModelFilter/remove/node-vroot",
5376 g_test_add_func ("/TreeModelFilter/remove/vroot-ancestor",
5377 remove_vroot_ancestor);
5379 /* Reference counting */
5380 g_test_add_func ("/TreeModelFilter/ref-count/single-level",
5381 ref_count_single_level);
5382 g_test_add_func ("/TreeModelFilter/ref-count/two-levels",
5383 ref_count_two_levels);
5384 g_test_add_func ("/TreeModelFilter/ref-count/three-levels",
5385 ref_count_three_levels);
5386 g_test_add_func ("/TreeModelFilter/ref-count/delete-row",
5387 ref_count_delete_row);
5388 g_test_add_func ("/TreeModelFilter/ref-count/cleanup",
5390 g_test_add_func ("/TreeModelFilter/ref-count/row-ref",
5393 /* Reference counting, transfer of first reference on
5394 * first node in level. This is a GtkTreeModelFilter-specific
5397 g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/insert",
5398 ref_count_transfer_root_level_insert);
5399 g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/reordered",
5400 ref_count_transfer_root_level_reordered);
5401 g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/insert",
5402 ref_count_transfer_child_level_insert);
5403 g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/reordered",
5404 ref_count_transfer_child_level_reordered);
5406 g_test_add_func ("/TreeModelFilter/specific/path-dependent-filter",
5407 specific_path_dependent_filter);
5408 g_test_add_func ("/TreeModelFilter/specific/append-after-collapse",
5409 specific_append_after_collapse);
5410 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-node",
5411 specific_sort_filter_remove_node);
5412 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-root",
5413 specific_sort_filter_remove_root);
5414 g_test_add_func ("/TreeModelFilter/specific/root-mixed-visibility",
5415 specific_root_mixed_visibility);
5416 g_test_add_func ("/TreeModelFilter/specific/has-child-filter",
5417 specific_has_child_filter);
5418 g_test_add_func ("/TreeModelFilter/specific/has-child-filter-on-sort-model",
5419 specific_has_child_filter_on_sort_model);
5420 g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter",
5421 specific_at_least_2_children_filter);
5422 g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter-on-sort-model",
5423 specific_at_least_2_children_filter_on_sort_model);
5424 g_test_add_func ("/TreeModelFilter/specific/root-has-child-filter",
5425 specific_root_has_child_filter);
5426 g_test_add_func ("/TreeModelFilter/specific/filter-add-child",
5427 specific_filter_add_child);
5428 g_test_add_func ("/TreeModelFilter/specific/list-store-clear",
5429 specific_list_store_clear);
5430 g_test_add_func ("/TreeModelFilter/specific/sort-ref-leaf-and-remove-ancestor",
5431 specific_sort_ref_leaf_and_remove_ancestor);
5432 g_test_add_func ("/TreeModelFilter/specific/ref-leaf-and-remove-ancestor",
5433 specific_ref_leaf_and_remove_ancestor);
5434 g_test_add_func ("/TreeModelFilter/specific/virtual-ref-leaf-and-remove-ancestor",
5435 specific_virtual_ref_leaf_and_remove_ancestor);
5437 g_test_add_func ("/TreeModelFilter/specific/bug-301558",
5438 specific_bug_301558);
5439 g_test_add_func ("/TreeModelFilter/specific/bug-311955",
5440 specific_bug_311955);
5441 g_test_add_func ("/TreeModelFilter/specific/bug-311955-clean",
5442 specific_bug_311955_clean);
5443 g_test_add_func ("/TreeModelFilter/specific/bug-346800",
5444 specific_bug_346800);
5445 g_test_add_func ("/TreeModelFilter/specific/bug-464173",
5446 specific_bug_464173);
5447 g_test_add_func ("/TreeModelFilter/specific/bug-540201",
5448 specific_bug_540201);
5449 g_test_add_func ("/TreeModelFilter/specific/bug-549287",
5450 specific_bug_549287);
5451 g_test_add_func ("/TreeModelFilter/specific/bug-621076",
5452 specific_bug_621076);