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);
2917 assert_node_ref_count (ref_model, &grandparent1, 2);
2918 assert_node_ref_count (ref_model, &grandparent2, 2);
2919 assert_node_ref_count (ref_model, &parent1, 3);
2920 assert_node_ref_count (ref_model, &parent2, 2);
2921 assert_node_ref_count (ref_model, &iter_parent1, 2);
2922 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
2923 assert_node_ref_count (ref_model, &iter_parent2, 1);
2925 gtk_tree_store_remove (GTK_TREE_STORE (model), &iter_parent2);
2927 assert_node_ref_count (ref_model, &grandparent1, 2);
2928 assert_node_ref_count (ref_model, &grandparent2, 2);
2929 assert_node_ref_count (ref_model, &parent1, 3);
2930 assert_node_ref_count (ref_model, &parent2, 2);
2931 assert_node_ref_count (ref_model, &iter_parent1, 2);
2932 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
2934 gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
2936 assert_node_ref_count (ref_model, &grandparent1, 2);
2937 assert_node_ref_count (ref_model, &grandparent2, 2);
2938 assert_node_ref_count (ref_model, &parent2, 3);
2939 assert_level_referenced (ref_model, 2, &parent2);
2941 gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
2943 assert_node_ref_count (ref_model, &grandparent1, 2);
2945 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2947 assert_node_ref_count (ref_model, &grandparent1, 2);
2949 gtk_widget_destroy (tree_view);
2950 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
2952 assert_node_ref_count (ref_model, &grandparent1, 1);
2954 g_object_unref (filter_model);
2956 assert_node_ref_count (ref_model, &grandparent1, 0);
2958 g_object_unref (ref_model);
2962 ref_count_cleanup (void)
2964 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
2965 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
2966 GtkTreeModel *model;
2967 GtkTreeModelRefCount *ref_model;
2968 GtkTreeModel *filter_model;
2969 GtkWidget *tree_view;
2971 model = gtk_tree_model_ref_count_new ();
2972 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
2979 * + iter_parent2_first
2983 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
2984 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
2985 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
2986 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
2987 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
2988 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
2989 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
2991 filter_model = gtk_tree_model_filter_new (model, NULL);
2992 tree_view = gtk_tree_view_new_with_model (filter_model);
2994 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
2996 assert_node_ref_count (ref_model, &grandparent1, 2);
2997 assert_node_ref_count (ref_model, &grandparent2, 2);
2998 assert_node_ref_count (ref_model, &parent1, 3);
2999 assert_node_ref_count (ref_model, &parent2, 2);
3000 assert_node_ref_count (ref_model, &iter_parent1, 2);
3001 assert_node_ref_count (ref_model, &iter_parent2_first, 2);
3002 assert_node_ref_count (ref_model, &iter_parent2, 1);
3004 gtk_widget_destroy (tree_view);
3006 assert_node_ref_count (ref_model, &grandparent1, 1);
3007 assert_node_ref_count (ref_model, &grandparent2, 1);
3008 assert_node_ref_count (ref_model, &parent1, 2);
3009 assert_node_ref_count (ref_model, &parent2, 1);
3010 assert_node_ref_count (ref_model, &iter_parent1, 1);
3011 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3012 assert_node_ref_count (ref_model, &iter_parent2, 0);
3014 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3016 /* Only the reference on the first node of the root level is kept. */
3017 assert_node_ref_count (ref_model, &grandparent1, 1);
3018 assert_node_ref_count (ref_model, &grandparent2, 0);
3019 assert_node_ref_count (ref_model, &parent1, 0);
3020 assert_node_ref_count (ref_model, &parent2, 0);
3021 assert_node_ref_count (ref_model, &iter_parent1, 0);
3022 assert_node_ref_count (ref_model, &iter_parent2_first, 0);
3023 assert_node_ref_count (ref_model, &iter_parent2, 0);
3025 g_object_unref (filter_model);
3026 g_object_unref (ref_model);
3030 ref_count_row_ref (void)
3032 GtkTreeIter grandparent1, grandparent2, parent1, parent2;
3033 GtkTreeIter iter_parent1, iter_parent2, iter_parent2_first;
3034 GtkTreeModel *model;
3035 GtkTreeModelRefCount *ref_model;
3036 GtkTreeModel *filter_model;
3037 GtkWidget *tree_view;
3039 GtkTreeRowReference *row_ref;
3041 model = gtk_tree_model_ref_count_new ();
3042 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3053 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3054 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3055 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
3056 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
3057 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
3058 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2_first, &parent2);
3059 gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
3061 filter_model = gtk_tree_model_filter_new (model, NULL);
3062 tree_view = gtk_tree_view_new_with_model (filter_model);
3064 path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
3065 row_ref = gtk_tree_row_reference_new (filter_model, path);
3066 gtk_tree_path_free (path);
3068 assert_node_ref_count (ref_model, &grandparent1, 2);
3069 assert_node_ref_count (ref_model, &grandparent2, 3);
3070 assert_node_ref_count (ref_model, &parent1, 1);
3071 assert_node_ref_count (ref_model, &parent2, 2);
3072 assert_node_ref_count (ref_model, &iter_parent1, 0);
3073 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3074 assert_node_ref_count (ref_model, &iter_parent2, 1);
3076 gtk_tree_row_reference_free (row_ref);
3078 assert_node_ref_count (ref_model, &grandparent1, 2);
3079 assert_node_ref_count (ref_model, &grandparent2, 2);
3080 assert_node_ref_count (ref_model, &parent1, 1);
3081 assert_node_ref_count (ref_model, &parent2, 1);
3082 assert_node_ref_count (ref_model, &iter_parent1, 0);
3083 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3084 assert_node_ref_count (ref_model, &iter_parent2, 0);
3086 path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
3087 row_ref = gtk_tree_row_reference_new (filter_model, path);
3088 gtk_tree_path_free (path);
3090 assert_node_ref_count (ref_model, &grandparent1, 2);
3091 assert_node_ref_count (ref_model, &grandparent2, 3);
3092 assert_node_ref_count (ref_model, &parent1, 1);
3093 assert_node_ref_count (ref_model, &parent2, 2);
3094 assert_node_ref_count (ref_model, &iter_parent1, 0);
3095 assert_node_ref_count (ref_model, &iter_parent2_first, 1);
3096 assert_node_ref_count (ref_model, &iter_parent2, 1);
3098 gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
3100 assert_node_ref_count (ref_model, &grandparent1, 2);
3101 assert_node_ref_count (ref_model, &grandparent2, 2);
3102 assert_node_ref_count (ref_model, &parent1, 1);
3103 assert_node_ref_count (ref_model, &iter_parent1, 0);
3105 gtk_tree_row_reference_free (row_ref);
3107 assert_node_ref_count (ref_model, &grandparent1, 2);
3108 assert_node_ref_count (ref_model, &grandparent2, 2);
3109 assert_node_ref_count (ref_model, &parent1, 1);
3110 assert_node_ref_count (ref_model, &iter_parent1, 0);
3112 gtk_widget_destroy (tree_view);
3114 gtk_tree_model_filter_clear_cache (GTK_TREE_MODEL_FILTER (filter_model));
3116 /* Only the reference on the first node of the root level is kept. */
3117 assert_node_ref_count (ref_model, &grandparent1, 1);
3118 assert_node_ref_count (ref_model, &grandparent2, 0);
3119 assert_node_ref_count (ref_model, &parent1, 0);
3121 g_object_unref (filter_model);
3122 g_object_unref (ref_model);
3126 ref_count_transfer_root_level_insert (void)
3128 GtkTreeIter grandparent1, grandparent2, grandparent3;
3129 GtkTreeIter new_node;
3130 GtkTreeModel *model;
3131 GtkTreeModelRefCount *ref_model;
3132 GtkTreeModel *filter_model;
3133 GtkWidget *tree_view;
3135 model = gtk_tree_model_ref_count_new ();
3136 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3143 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3144 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3145 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
3147 filter_model = gtk_tree_model_filter_new (model, NULL);
3148 tree_view = gtk_tree_view_new_with_model (filter_model);
3150 assert_node_ref_count (ref_model, &grandparent1, 2);
3151 assert_node_ref_count (ref_model, &grandparent2, 1);
3152 assert_node_ref_count (ref_model, &grandparent3, 1);
3154 gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, NULL);
3156 assert_node_ref_count (ref_model, &new_node, 2);
3157 assert_node_ref_count (ref_model, &grandparent1, 1);
3158 assert_node_ref_count (ref_model, &grandparent2, 1);
3159 assert_node_ref_count (ref_model, &grandparent3, 1);
3161 gtk_widget_destroy (tree_view);
3162 g_object_unref (filter_model);
3163 g_object_unref (ref_model);
3167 ref_count_transfer_root_level_reordered (void)
3169 GtkTreeIter grandparent1, grandparent2, grandparent3;
3170 GtkTreeModel *model;
3171 GtkTreeModelRefCount *ref_model;
3172 GtkTreeModel *filter_model;
3173 GtkWidget *tree_view;
3175 model = gtk_tree_model_ref_count_new ();
3176 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3183 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3184 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
3185 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent3, NULL);
3187 filter_model = gtk_tree_model_filter_new (model, NULL);
3188 tree_view = gtk_tree_view_new_with_model (filter_model);
3190 assert_node_ref_count (ref_model, &grandparent1, 2);
3191 assert_node_ref_count (ref_model, &grandparent2, 1);
3192 assert_node_ref_count (ref_model, &grandparent3, 1);
3194 /* gtk_tree_store_move() will emit rows-reordered */
3195 gtk_tree_store_move_after (GTK_TREE_STORE (model),
3196 &grandparent1, &grandparent3);
3198 assert_node_ref_count (ref_model, &grandparent2, 2);
3199 assert_node_ref_count (ref_model, &grandparent3, 1);
3200 assert_node_ref_count (ref_model, &grandparent1, 1);
3202 gtk_widget_destroy (tree_view);
3203 g_object_unref (filter_model);
3204 g_object_unref (ref_model);
3208 ref_count_transfer_child_level_insert (void)
3210 GtkTreeIter grandparent1;
3211 GtkTreeIter parent1, parent2, parent3;
3212 GtkTreeIter new_node;
3213 GtkTreeModel *model;
3214 GtkTreeModelRefCount *ref_model;
3215 GtkTreeModel *filter_model;
3216 GtkWidget *tree_view;
3218 model = gtk_tree_model_ref_count_new ();
3219 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3227 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3228 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
3229 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
3230 gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
3232 filter_model = gtk_tree_model_filter_new (model, NULL);
3233 tree_view = gtk_tree_view_new_with_model (filter_model);
3235 assert_node_ref_count (ref_model, &grandparent1, 3);
3236 assert_node_ref_count (ref_model, &parent1, 1);
3237 assert_node_ref_count (ref_model, &parent2, 0);
3238 assert_node_ref_count (ref_model, &parent3, 0);
3240 gtk_tree_store_prepend (GTK_TREE_STORE (model), &new_node, &grandparent1);
3242 assert_node_ref_count (ref_model, &grandparent1, 3);
3243 assert_node_ref_count (ref_model, &new_node, 1);
3244 assert_node_ref_count (ref_model, &parent1, 0);
3245 assert_node_ref_count (ref_model, &parent2, 0);
3246 assert_node_ref_count (ref_model, &parent3, 0);
3248 gtk_widget_destroy (tree_view);
3249 g_object_unref (filter_model);
3250 g_object_unref (ref_model);
3254 ref_count_transfer_child_level_reordered (void)
3256 GtkTreeIter grandparent1;
3257 GtkTreeIter parent1, parent2, parent3;
3258 GtkTreeModel *model;
3259 GtkTreeModelRefCount *ref_model;
3260 GtkTreeModel *filter_model;
3261 GtkWidget *tree_view;
3263 model = gtk_tree_model_ref_count_new ();
3264 ref_model = GTK_TREE_MODEL_REF_COUNT (model);
3272 gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
3273 gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent1);
3274 gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent1);
3275 gtk_tree_store_append (GTK_TREE_STORE (model), &parent3, &grandparent1);
3277 filter_model = gtk_tree_model_filter_new (model, NULL);
3278 tree_view = gtk_tree_view_new_with_model (filter_model);
3280 assert_node_ref_count (ref_model, &grandparent1, 3);
3281 assert_node_ref_count (ref_model, &parent1, 1);
3282 assert_node_ref_count (ref_model, &parent2, 0);
3283 assert_node_ref_count (ref_model, &parent3, 0);
3285 /* gtk_tree_store_move() will emit rows-reordered */
3286 gtk_tree_store_move_after (GTK_TREE_STORE (model),
3287 &parent1, &parent3);
3289 assert_node_ref_count (ref_model, &grandparent1, 3);
3290 assert_node_ref_count (ref_model, &parent2, 1);
3291 assert_node_ref_count (ref_model, &parent3, 0);
3292 assert_node_ref_count (ref_model, &parent1, 0);
3294 gtk_widget_destroy (tree_view);
3295 g_object_unref (filter_model);
3296 g_object_unref (ref_model);
3301 specific_path_dependent_filter_func (GtkTreeModel *model,
3307 path = gtk_tree_model_get_path (model, iter);
3308 if (gtk_tree_path_get_indices (path)[0] < 4)
3315 specific_path_dependent_filter (void)
3321 GtkTreeModel *filter;
3323 list = gtk_list_store_new (1, G_TYPE_INT);
3324 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
3325 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
3326 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
3327 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
3328 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
3329 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
3330 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
3331 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
3333 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list));
3334 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL);
3335 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3336 specific_path_dependent_filter_func,
3339 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0,
3340 GTK_SORT_DESCENDING);
3342 for (i = 0; i < 4; i++)
3344 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
3346 gtk_list_store_remove (list, &iter);
3348 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter,
3350 gtk_list_store_remove (list, &iter);
3353 g_object_unref (filter);
3354 g_object_unref (sort);
3355 g_object_unref (list);
3360 specific_append_after_collapse_visible_func (GtkTreeModel *model,
3365 gboolean hide_negative_numbers;
3367 gtk_tree_model_get (model, iter, 1, &number, -1);
3368 hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers"));
3370 return (number >= 0 || !hide_negative_numbers);
3374 specific_append_after_collapse (void)
3376 /* This test is based on one of the test cases I found in my
3377 * old test cases directory. I unfortunately do not have a record
3378 * from who this test case originated. -Kris.
3382 * - Show tree, expand, collapse.
3387 GtkTreeIter child_iter;
3388 GtkTreeIter child_iter2;
3389 GtkTreePath *append_path;
3390 GtkTreeStore *store;
3391 GtkTreeModel *filter;
3395 GtkWidget *tree_view;
3397 store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT);
3399 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
3400 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
3401 GINT_TO_POINTER (FALSE));
3402 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3403 specific_append_after_collapse_visible_func,
3406 sort = gtk_tree_model_sort_new_with_model (filter);
3408 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3409 tree_view = gtk_tree_view_new_with_model (sort);
3410 gtk_container_add (GTK_CONTAINER (window), tree_view);
3411 gtk_widget_realize (tree_view);
3413 while (gtk_events_pending ())
3414 gtk_main_iteration ();
3416 gtk_tree_store_prepend (store, &iter, NULL);
3417 gtk_tree_store_set (store, &iter,
3418 0, "hallo", 1, 1, -1);
3420 gtk_tree_store_append (store, &child_iter, &iter);
3421 gtk_tree_store_set (store, &child_iter,
3422 0, "toemaar", 1, 1, -1);
3424 gtk_tree_store_append (store, &child_iter2, &child_iter);
3425 gtk_tree_store_set (store, &child_iter2,
3426 0, "very deep", 1, 1, -1);
3428 append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2);
3430 gtk_tree_store_append (store, &child_iter, &iter);
3431 gtk_tree_store_set (store, &child_iter,
3432 0, "sja", 1, 1, -1);
3434 gtk_tree_store_append (store, &child_iter, &iter);
3435 gtk_tree_store_set (store, &child_iter,
3436 0, "some word", 1, -1, -1);
3438 /* Expand and collapse the tree */
3439 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3440 while (gtk_events_pending ())
3441 gtk_main_iteration ();
3443 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
3444 while (gtk_events_pending ())
3445 gtk_main_iteration ();
3447 /* Add another it */
3448 g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers",
3449 GINT_TO_POINTER (TRUE));
3451 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path))
3453 gtk_tree_store_append (store, &child_iter, &iter);
3454 gtk_tree_store_set (store, &child_iter,
3455 0, "new new new !!", 1, 1, -1);
3457 gtk_tree_path_free (append_path);
3460 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
3461 while (gtk_events_pending ())
3462 gtk_main_iteration ();
3467 specific_sort_filter_remove_node_compare_func (GtkTreeModel *model,
3476 specific_sort_filter_remove_node_visible_func (GtkTreeModel *model,
3482 /* Do reference the model */
3483 gtk_tree_model_get (model, iter, 0, &item, -1);
3490 specific_sort_filter_remove_node (void)
3492 /* This test is based on one of the test cases I found in my
3493 * old test cases directory. I unfortunately do not have a record
3494 * from who this test case originated. -Kris.
3497 * - Create tree store, sort, filter models. The sort model has
3498 * a default sort func that is enabled, filter model a visible func
3499 * that defaults to returning FALSE.
3500 * - Remove a node from the tree store.
3504 GtkTreeStore *store;
3505 GtkTreeModel *filter;
3509 GtkWidget *tree_view;
3511 store = gtk_tree_store_new (1, G_TYPE_STRING);
3512 gtk_tree_store_append (store, &iter, NULL);
3513 gtk_tree_store_set (store, &iter, 0, "Hello1", -1);
3515 gtk_tree_store_append (store, &iter, NULL);
3516 gtk_tree_store_set (store, &iter, 0, "Hello2", -1);
3518 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
3519 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
3520 specific_sort_filter_remove_node_compare_func, NULL, NULL);
3522 filter = gtk_tree_model_filter_new (sort, NULL);
3523 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
3524 specific_sort_filter_remove_node_visible_func,
3528 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3529 tree_view = gtk_tree_view_new_with_model (filter);
3530 gtk_container_add (GTK_CONTAINER (window), tree_view);
3531 gtk_widget_realize (tree_view);
3533 while (gtk_events_pending ())
3534 gtk_main_iteration ();
3537 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
3538 gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
3539 gtk_tree_store_remove (store, &iter);
3541 while (gtk_events_pending ())
3542 gtk_main_iteration ();
3547 specific_sort_filter_remove_root (void)
3549 /* This test is based on one of the test cases I found in my
3550 * old test cases directory. I unfortunately do not have a record
3551 * from who this test case originated. -Kris.
3554 GtkTreeModel *model, *sort, *filter;
3555 GtkTreeIter root, mid, leaf;
3558 model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT));
3559 gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL);
3560 gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root);
3561 gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid);
3563 path = gtk_tree_model_get_path (model, &mid);
3565 sort = gtk_tree_model_sort_new_with_model (model);
3566 filter = gtk_tree_model_filter_new (sort, path);
3568 gtk_tree_path_free (path);
3570 gtk_tree_store_remove (GTK_TREE_STORE (model), &root);
3572 g_object_unref (filter);
3573 g_object_unref (sort);
3574 g_object_unref (model);
3579 specific_root_mixed_visibility (void)
3582 GtkTreeModel *filter;
3583 /* A bit nasty, apologies */
3586 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3588 for (i = 0; i < LEVEL_LENGTH; i++)
3592 gtk_tree_store_insert (fixture.store, &iter, NULL, i);
3594 create_tree_store_set_values (fixture.store, &iter, TRUE);
3596 create_tree_store_set_values (fixture.store, &iter, FALSE);
3599 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3600 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3601 fixture.monitor = NULL;
3603 gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
3605 /* In order to trigger the potential bug, we should not access
3606 * the filter model here (so don't call the check functions).
3609 /* Change visibility of an odd row to TRUE */
3610 set_path_visibility (&fixture, "3", TRUE);
3611 check_filter_model (&fixture);
3612 check_level_length (fixture.filter, NULL, 4);
3618 specific_has_child_filter_filter_func (GtkTreeModel *model,
3622 return gtk_tree_model_iter_has_child (model, iter);
3626 specific_has_child_filter (void)
3628 GtkTreeModel *filter;
3629 GtkTreeIter iter, root;
3630 FilterTest fixture; /* This is not how it should be done */
3631 GtkWidget *tree_view;
3633 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3634 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3635 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3636 fixture.monitor = signal_monitor_new (filter);
3638 tree_view = gtk_tree_view_new_with_model (filter);
3640 /* We will filter on parent state using a filter function. We will
3641 * manually keep the boolean column in sync, so that we can use
3642 * check_filter_model() to check the consistency of the model.
3644 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3645 * to be able to check the structure here. We keep the calls to
3646 * check_filter_model() commented out until then.
3648 gtk_tree_model_filter_set_visible_func (fixture.filter,
3649 specific_has_child_filter_filter_func,
3652 /* The first node will be initially invisible: no signals */
3653 gtk_tree_store_append (fixture.store, &root, NULL);
3654 create_tree_store_set_values (fixture.store, &root, FALSE);
3656 /* check_filter_model (&fixture); */
3657 check_level_length (fixture.filter, NULL, 0);
3658 signal_monitor_assert_is_empty (fixture.monitor);
3660 /* Insert a child node. This will cause the parent to become visible
3661 * since there is a child now.
3663 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3664 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3665 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3667 gtk_tree_store_append (fixture.store, &iter, &root);
3668 create_tree_store_set_values (fixture.store, &iter, TRUE);
3670 /* Parent must now be visible. Do the level length check first,
3671 * to avoid modifying the child model triggering a row-changed to
3674 check_level_length (fixture.filter, NULL, 1);
3675 check_level_length (fixture.filter, "0", 0);
3676 signal_monitor_assert_is_empty (fixture.monitor);
3678 /* This should propagate row-changed */
3679 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3680 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3682 set_path_visibility (&fixture, "0", TRUE);
3683 /* check_filter_model (&fixture); */
3684 signal_monitor_assert_is_empty (fixture.monitor);
3686 /* New root node, no child, so no signal */
3687 gtk_tree_store_append (fixture.store, &root, NULL);
3688 check_level_length (fixture.filter, NULL, 1);
3689 signal_monitor_assert_is_empty (fixture.monitor);
3691 /* When the child comes in, this node will become visible */
3692 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
3693 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3694 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3695 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
3696 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3698 gtk_tree_store_append (fixture.store, &iter, &root);
3699 check_level_length (fixture.filter, NULL, 2);
3700 check_level_length (fixture.filter, "1", 0);
3702 create_tree_store_set_values (fixture.store, &root, TRUE);
3703 create_tree_store_set_values (fixture.store, &iter, TRUE);
3705 /* check_filter_model (&fixture); */
3706 signal_monitor_assert_is_empty (fixture.monitor);
3708 /* Add another child for 1 */
3709 gtk_tree_store_append (fixture.store, &iter, &root);
3710 create_tree_store_set_values (fixture.store, &iter, TRUE);
3711 check_level_length (fixture.filter, NULL, 2);
3712 check_level_length (fixture.filter, "0", 0);
3713 check_level_length (fixture.filter, "1", 0);
3714 signal_monitor_assert_is_empty (fixture.monitor);
3716 /* Now remove one of the remaining child rows */
3717 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
3719 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
3721 gtk_tree_store_remove (fixture.store, &iter);
3723 check_level_length (fixture.filter, NULL, 1);
3724 check_level_length (fixture.filter, "0", 0);
3726 set_path_visibility (&fixture, "0", FALSE);
3727 /* check_filter_model (&fixture); */
3728 signal_monitor_assert_is_empty (fixture.monitor);
3733 specific_root_has_child_filter_filter_func (GtkTreeModel *model,
3740 path = gtk_tree_model_get_path (model, iter);
3741 depth = gtk_tree_path_get_depth (path);
3742 gtk_tree_path_free (path);
3747 return gtk_tree_model_iter_has_child (model, iter);
3751 specific_root_has_child_filter (void)
3753 GtkTreeModel *filter;
3754 GtkTreeIter iter, root;
3755 FilterTest fixture; /* This is not how it should be done ... */
3756 GtkWidget *tree_view;
3758 /* This is a variation on the above test case, specific has-child-filter,
3759 * herein the has-child check for visibility only applies to root level
3760 * nodes. In this test, children are always visible because we
3761 * only filter based on the "has child" criterion.
3764 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3765 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
3766 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3767 fixture.monitor = signal_monitor_new (filter);
3769 tree_view = gtk_tree_view_new_with_model (filter);
3771 /* We will filter on parent state using a filter function. We will
3772 * manually keep the boolean column in sync, so that we can use
3773 * check_filter_model() to check the consistency of the model.
3775 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3776 * to be able to check the structure here. We keep the calls to
3777 * check_filter_model() commented out until then.
3779 gtk_tree_model_filter_set_visible_func (fixture.filter,
3780 specific_root_has_child_filter_filter_func,
3783 /* Add a first node, this will be invisible initially, so no signal
3784 * should be emitted.
3786 gtk_tree_store_append (fixture.store, &root, NULL);
3787 create_tree_store_set_values (fixture.store, &root, FALSE);
3789 signal_monitor_assert_is_empty (fixture.monitor);
3790 /* check_filter_model (&fixture); */
3791 check_level_length (fixture.filter, NULL, 0);
3793 /* Add a child node. This will cause the parent to become visible,
3794 * so we expect row-inserted signals for both.
3796 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3797 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3798 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3800 gtk_tree_store_append (fixture.store, &iter, &root);
3801 signal_monitor_assert_is_empty (fixture.monitor);
3803 check_level_length (fixture.filter, NULL, 1);
3804 check_level_length (fixture.filter, "0", 1);
3806 /* Modify the content of iter, no signals because the parent is not
3809 create_tree_store_set_values (fixture.store, &iter, TRUE);
3810 signal_monitor_assert_is_empty (fixture.monitor);
3812 /* Parent must now be visible. Do the level length check first,
3813 * to avoid modifying the child model triggering a row-changed to
3816 check_level_length (fixture.filter, NULL, 1);
3817 check_level_length (fixture.filter, "0", 1);
3820 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3821 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3823 set_path_visibility (&fixture, "0", TRUE);
3824 /* check_filter_model (&fixture); */
3826 signal_monitor_assert_is_empty (fixture.monitor);
3828 /* Insert another node in the root level. Initially invisible, so
3829 * not expecting any signal.
3831 gtk_tree_store_append (fixture.store, &root, NULL);
3832 check_level_length (fixture.filter, NULL, 1);
3834 signal_monitor_assert_is_empty (fixture.monitor);
3836 /* Adding a child node which also makes parent at path 1 visible. */
3837 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
3838 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3839 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3841 gtk_tree_store_append (fixture.store, &iter, &root);
3842 check_level_length (fixture.filter, NULL, 2);
3843 check_level_length (fixture.filter, "1", 1);
3845 signal_monitor_assert_is_empty (fixture.monitor);
3847 /* Check if row-changed is propagated */
3848 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
3849 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3851 create_tree_store_set_values (fixture.store, &root, TRUE);
3852 create_tree_store_set_values (fixture.store, &iter, TRUE);
3853 /* check_filter_model (&fixture); */
3854 signal_monitor_assert_is_empty (fixture.monitor);
3856 /* Insert another child under node 1 */
3857 gtk_tree_store_append (fixture.store, &iter, &root);
3858 create_tree_store_set_values (fixture.store, &iter, TRUE);
3859 check_level_length (fixture.filter, NULL, 2);
3860 check_level_length (fixture.filter, "0", 1);
3861 check_level_length (fixture.filter, "1", 2);
3862 signal_monitor_assert_is_empty (fixture.monitor);
3864 /* Set a child node to invisible. This should not yield any
3865 * change, because filtering is only done on whether the root
3866 * node has a child, which it still has.
3868 set_path_visibility (&fixture, "0:0", FALSE);
3869 signal_monitor_assert_is_empty (fixture.monitor);
3871 /* Now remove one of the remaining child rows */
3872 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3873 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
3875 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
3877 gtk_tree_store_remove (fixture.store, &iter);
3879 check_level_length (fixture.filter, NULL, 1);
3880 check_level_length (fixture.filter, "0", 2);
3881 signal_monitor_assert_is_empty (fixture.monitor);
3883 /* Set visibility of 0 to FALSE, no-op for filter model since
3884 * the child 0:0 is already gone
3886 set_path_visibility (&fixture, "0", FALSE);
3887 /* check_filter_model (&fixture); */
3888 signal_monitor_assert_is_empty (fixture.monitor);
3892 specific_has_child_filter_on_sort_model (void)
3894 GtkTreeModel *filter;
3895 GtkTreeModel *sort_model;
3896 GtkTreeIter iter, root;
3897 FilterTest fixture; /* This is not how it should be done */
3898 GtkWidget *tree_view;
3900 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
3901 sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
3902 filter = gtk_tree_model_filter_new (sort_model, NULL);
3903 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
3904 fixture.monitor = signal_monitor_new (filter);
3906 tree_view = gtk_tree_view_new_with_model (filter);
3908 /* We will filter on parent state using a filter function. We will
3909 * manually keep the boolean column in sync, so that we can use
3910 * check_filter_model() to check the consistency of the model.
3912 /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH
3913 * to be able to check the structure here. We keep the calls to
3914 * check_filter_model() commented out until then.
3916 gtk_tree_model_filter_set_visible_func (fixture.filter,
3917 specific_has_child_filter_filter_func,
3920 /* The first node will be initially invisible: no signals */
3921 gtk_tree_store_append (fixture.store, &root, NULL);
3922 create_tree_store_set_values (fixture.store, &root, FALSE);
3924 /* check_filter_model (&fixture); */
3925 check_level_length (fixture.filter, NULL, 0);
3926 signal_monitor_assert_is_empty (fixture.monitor);
3928 /* Insert a child node. This will cause the parent to become visible
3929 * since there is a child now.
3931 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
3932 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3934 gtk_tree_store_append (fixture.store, &iter, &root);
3935 create_tree_store_set_values (fixture.store, &iter, TRUE);
3937 /* Parent must now be visible. Do the level length check first,
3938 * to avoid modifying the child model triggering a row-changed to
3941 check_level_length (fixture.filter, NULL, 1);
3942 check_level_length (fixture.filter, "0", 0);
3943 signal_monitor_assert_is_empty (fixture.monitor);
3945 /* This should propagate row-changed */
3946 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
3947 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
3949 set_path_visibility (&fixture, "0", TRUE);
3950 /* check_filter_model (&fixture); */
3951 signal_monitor_assert_is_empty (fixture.monitor);
3953 /* New root node, no child, so no signal */
3954 gtk_tree_store_append (fixture.store, &root, NULL);
3955 check_level_length (fixture.filter, NULL, 1);
3956 signal_monitor_assert_is_empty (fixture.monitor);
3958 /* When the child comes in, this node will become visible */
3959 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
3960 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3961 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
3962 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
3964 gtk_tree_store_append (fixture.store, &iter, &root);
3965 check_level_length (fixture.filter, NULL, 2);
3966 check_level_length (fixture.filter, "1", 0);
3968 create_tree_store_set_values (fixture.store, &root, TRUE);
3969 create_tree_store_set_values (fixture.store, &iter, TRUE);
3971 /* check_filter_model (&fixture); */
3972 signal_monitor_assert_is_empty (fixture.monitor);
3974 /* Add another child for 1 */
3975 gtk_tree_store_append (fixture.store, &iter, &root);
3976 create_tree_store_set_values (fixture.store, &iter, TRUE);
3977 check_level_length (fixture.filter, NULL, 2);
3978 check_level_length (fixture.filter, "0", 0);
3979 check_level_length (fixture.filter, "1", 0);
3980 signal_monitor_assert_is_empty (fixture.monitor);
3982 /* Now remove one of the remaining child rows */
3983 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
3985 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
3987 gtk_tree_store_remove (fixture.store, &iter);
3989 check_level_length (fixture.filter, NULL, 1);
3990 check_level_length (fixture.filter, "0", 0);
3992 set_path_visibility (&fixture, "0", FALSE);
3993 /* check_filter_model (&fixture); */
3994 signal_monitor_assert_is_empty (fixture.monitor);
3998 specific_at_least_2_children_filter_filter_func (GtkTreeModel *model,
4002 return gtk_tree_model_iter_n_children (model, iter) >= 2;
4006 specific_at_least_2_children_filter (void)
4008 GtkTreeModel *filter;
4009 GtkTreeIter iter, root;
4010 FilterTest fixture; /* This is not how it should be done */
4011 GtkWidget *tree_view;
4013 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4014 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
4015 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4016 fixture.monitor = signal_monitor_new (filter);
4018 tree_view = gtk_tree_view_new_with_model (filter);
4020 gtk_tree_model_filter_set_visible_func (fixture.filter,
4021 specific_at_least_2_children_filter_filter_func,
4024 /* The first node will be initially invisible: no signals */
4025 gtk_tree_store_append (fixture.store, &root, NULL);
4026 create_tree_store_set_values (fixture.store, &root, FALSE);
4028 /* check_filter_model (&fixture); */
4029 check_level_length (fixture.filter, NULL, 0);
4030 signal_monitor_assert_is_empty (fixture.monitor);
4032 /* Insert a child node. Nothing should happen.
4034 gtk_tree_store_append (fixture.store, &iter, &root);
4035 create_tree_store_set_values (fixture.store, &iter, TRUE);
4037 check_level_length (fixture.filter, NULL, 0);
4038 signal_monitor_assert_is_empty (fixture.monitor);
4040 /* Insert a second child node. This will cause the parent to become
4043 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4044 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4046 gtk_tree_store_append (fixture.store, &iter, &root);
4047 create_tree_store_set_values (fixture.store, &iter, TRUE);
4049 /* Parent must now be visible. Do the level length check first,
4050 * to avoid modifying the child model triggering a row-changed to
4053 check_level_length (fixture.filter, NULL, 1);
4054 check_level_length (fixture.filter, "0", 0);
4055 signal_monitor_assert_is_empty (fixture.monitor);
4057 /* This should propagate row-changed */
4058 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4059 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4061 set_path_visibility (&fixture, "0", TRUE);
4062 /* check_filter_model (&fixture); */
4063 signal_monitor_assert_is_empty (fixture.monitor);
4065 /* New root node, no child, so no signal */
4066 gtk_tree_store_append (fixture.store, &root, NULL);
4067 check_level_length (fixture.filter, NULL, 1);
4068 signal_monitor_assert_is_empty (fixture.monitor);
4070 /* First child, no signal, no change */
4071 gtk_tree_store_append (fixture.store, &iter, &root);
4072 check_level_length (fixture.filter, NULL, 1);
4073 signal_monitor_assert_is_empty (fixture.monitor);
4075 /* When the second child comes in, this node will become visible */
4076 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "1");
4077 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4078 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "1");
4079 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "1");
4081 gtk_tree_store_append (fixture.store, &iter, &root);
4082 check_level_length (fixture.filter, NULL, 2);
4083 check_level_length (fixture.filter, "1", 0);
4085 create_tree_store_set_values (fixture.store, &root, TRUE);
4086 create_tree_store_set_values (fixture.store, &iter, TRUE);
4088 /* check_filter_model (&fixture); */
4089 signal_monitor_assert_is_empty (fixture.monitor);
4091 /* Add another child for 1 */
4092 gtk_tree_store_append (fixture.store, &iter, &root);
4093 create_tree_store_set_values (fixture.store, &iter, TRUE);
4094 check_level_length (fixture.filter, NULL, 2);
4095 check_level_length (fixture.filter, "0", 0);
4096 check_level_length (fixture.filter, "1", 0);
4097 signal_monitor_assert_is_empty (fixture.monitor);
4099 /* Now remove one of the remaining child rows */
4100 signal_monitor_append_signal (fixture.monitor, ROW_DELETED, "0");
4102 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store),
4104 gtk_tree_store_remove (fixture.store, &iter);
4106 check_level_length (fixture.filter, NULL, 1);
4107 check_level_length (fixture.filter, "0", 0);
4109 set_path_visibility (&fixture, "0", FALSE);
4110 /* check_filter_model (&fixture); */
4111 signal_monitor_assert_is_empty (fixture.monitor);
4115 specific_at_least_2_children_filter_on_sort_model (void)
4117 GtkTreeModel *filter;
4118 GtkTreeModel *sort_model;
4119 GtkTreeIter iter, root;
4120 FilterTest fixture; /* This is not how it should be done */
4121 GtkWidget *tree_view;
4123 fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
4124 sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (fixture.store));
4125 filter = gtk_tree_model_filter_new (sort_model, NULL);
4126 fixture.filter = GTK_TREE_MODEL_FILTER (filter);
4127 fixture.monitor = signal_monitor_new (filter);
4129 tree_view = gtk_tree_view_new_with_model (filter);
4131 gtk_tree_model_filter_set_visible_func (fixture.filter,
4132 specific_at_least_2_children_filter_filter_func,
4135 /* The first node will be initially invisible: no signals */
4136 gtk_tree_store_append (fixture.store, &root, NULL);
4137 create_tree_store_set_values (fixture.store, &root, FALSE);
4139 /* check_filter_model (&fixture); */
4140 check_level_length (fixture.filter, NULL, 0);
4141 signal_monitor_assert_is_empty (fixture.monitor);
4143 /* Insert a child node. Nothing should happen.
4145 gtk_tree_store_append (fixture.store, &iter, &root);
4146 create_tree_store_set_values (fixture.store, &iter, TRUE);
4148 check_level_length (fixture.filter, NULL, 0);
4149 signal_monitor_assert_is_empty (fixture.monitor);
4152 GtkTreePath *path = gtk_tree_path_new_from_indices (0, 0, -1);
4153 GtkTreeRowReference *ref;
4155 ref = gtk_tree_row_reference_new (sort_model, path);
4156 gtk_tree_path_free (path);
4159 /* Insert a second child node. This will cause the parent to become
4162 signal_monitor_append_signal (fixture.monitor, ROW_INSERTED, "0");
4163 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4165 gtk_tree_store_append (fixture.store, &iter, &root);
4166 create_tree_store_set_values (fixture.store, &iter, TRUE);
4168 /* Parent must now be visible. Do the level length check first,
4169 * to avoid modifying the child model triggering a row-changed to
4172 check_level_length (fixture.filter, NULL, 1);
4173 check_level_length (fixture.filter, "0", 0);
4174 signal_monitor_assert_is_empty (fixture.monitor);
4176 /* This should propagate row-changed */
4177 signal_monitor_append_signal (fixture.monitor, ROW_CHANGED, "0");
4178 signal_monitor_append_signal (fixture.monitor, ROW_HAS_CHILD_TOGGLED, "0");
4180 set_path_visibility (&fixture, "0", TRUE);
4181 /* check_filter_model (&fixture); */
4182 signal_monitor_assert_is_empty (fixture.monitor);
4184 /* New root node, no child, so no signal */
4185 gtk_tree_store_append (fixture.store, &root, NULL);
4186 check_level_length (fixture.filter, NULL, 1);
4187 signal_monitor_assert_is_empty (fixture.monitor);
4192 specific_filter_add_child (void)
4194 /* This test is based on one of the test cases I found in my
4195 * old test cases directory. I unfortunately do not have a record
4196 * from who this test case originated. -Kris.
4200 GtkTreeIter iter_first;
4202 GtkTreeStore *store;
4203 GtkTreeModel *filter G_GNUC_UNUSED;
4205 store = gtk_tree_store_new (1, G_TYPE_STRING);
4207 gtk_tree_store_append (store, &iter_first, NULL);
4208 gtk_tree_store_set (store, &iter_first, 0, "Hello", -1);
4210 gtk_tree_store_append (store, &iter, NULL);
4211 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4213 gtk_tree_store_append (store, &iter, NULL);
4214 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4216 gtk_tree_store_append (store, &iter, NULL);
4217 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4219 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4221 gtk_tree_store_set (store, &iter, 0, "Hello", -1);
4222 gtk_tree_store_append (store, &child, &iter_first);
4223 gtk_tree_store_set (store, &child, 0, "Hello", -1);
4227 specific_list_store_clear (void)
4231 GtkTreeModel *filter;
4232 GtkWidget *view G_GNUC_UNUSED;
4234 list = gtk_list_store_new (1, G_TYPE_INT);
4235 gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1);
4236 gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1);
4237 gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1);
4238 gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1);
4239 gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1);
4240 gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1);
4241 gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1);
4242 gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1);
4244 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL);
4245 view = gtk_tree_view_new_with_model (filter);
4247 gtk_list_store_clear (list);
4251 specific_sort_ref_leaf_and_remove_ancestor (void)
4253 GtkTreeIter iter, child, child2, child3;
4257 GtkTreeRowReference *rowref;
4258 GtkWidget *view G_GNUC_UNUSED;
4260 tree = gtk_tree_store_new (1, G_TYPE_INT);
4261 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4262 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4263 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4264 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4266 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4267 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4268 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4270 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
4271 view = gtk_tree_view_new_with_model (sort);
4272 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4274 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4275 rowref = gtk_tree_row_reference_new (sort, path);
4276 gtk_tree_path_free (path);
4278 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4279 rowref = gtk_tree_row_reference_new (sort, path);
4280 gtk_tree_path_free (path);
4282 path = gtk_tree_path_new_from_indices (3, 0, -1);
4283 rowref = gtk_tree_row_reference_new (sort, path);
4284 gtk_tree_path_free (path);
4286 path = gtk_tree_path_new_from_indices (3, -1);
4287 rowref = gtk_tree_row_reference_new (sort, path);
4288 gtk_tree_path_free (path);
4290 /* Deleting a parent */
4291 path = gtk_tree_path_new_from_indices (3, 0, -1);
4292 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4293 gtk_tree_store_remove (tree, &iter);
4294 gtk_tree_path_free (path);
4296 gtk_tree_row_reference_free (rowref);
4300 specific_ref_leaf_and_remove_ancestor (void)
4302 GtkTreeIter iter, child, child2, child3;
4304 GtkTreeModel *filter;
4306 GtkTreeRowReference *rowref;
4307 GtkWidget *view G_GNUC_UNUSED;
4309 tree = gtk_tree_store_new (1, G_TYPE_INT);
4310 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4311 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4312 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4313 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4315 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4316 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4317 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4319 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), NULL);
4320 view = gtk_tree_view_new_with_model (filter);
4321 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4323 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4324 rowref = gtk_tree_row_reference_new (filter, path);
4325 gtk_tree_path_free (path);
4327 path = gtk_tree_path_new_from_indices (3, 0, 0, 0, -1);
4328 rowref = gtk_tree_row_reference_new (filter, path);
4329 gtk_tree_path_free (path);
4331 path = gtk_tree_path_new_from_indices (3, 0, -1);
4332 rowref = gtk_tree_row_reference_new (filter, path);
4333 gtk_tree_path_free (path);
4335 path = gtk_tree_path_new_from_indices (3, -1);
4336 rowref = gtk_tree_row_reference_new (filter, path);
4337 gtk_tree_path_free (path);
4339 /* Deleting a parent */
4340 path = gtk_tree_path_new_from_indices (3, 0, -1);
4341 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4342 gtk_tree_store_remove (tree, &iter);
4343 gtk_tree_path_free (path);
4345 gtk_tree_row_reference_free (rowref);
4349 specific_virtual_ref_leaf_and_remove_ancestor (void)
4351 GtkTreeIter iter, child, child2, child3;
4353 GtkTreeModel *filter;
4355 GtkTreeRowReference *rowref;
4356 GtkWidget *view G_GNUC_UNUSED;
4358 tree = gtk_tree_store_new (1, G_TYPE_INT);
4359 gtk_tree_store_insert_with_values (tree, &iter, NULL, 0, 0, 1, -1);
4360 gtk_tree_store_insert_with_values (tree, &iter, NULL, 1, 0, 2, -1);
4361 gtk_tree_store_insert_with_values (tree, &iter, NULL, 2, 0, 3, -1);
4362 gtk_tree_store_insert_with_values (tree, &iter, NULL, 3, 0, 4, -1);
4364 gtk_tree_store_insert_with_values (tree, &child, &iter, 0, 0, 50, -1);
4365 gtk_tree_store_insert_with_values (tree, &child2, &child, 0, 0, 6, -1);
4366 gtk_tree_store_insert_with_values (tree, &child3, &child2, 0, 0, 7, -1);
4368 /* Set a virtual root of 3:0 */
4369 path = gtk_tree_path_new_from_indices (3, 0, -1);
4370 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (tree), path);
4371 gtk_tree_path_free (path);
4373 view = gtk_tree_view_new_with_model (filter);
4374 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
4376 path = gtk_tree_path_new_from_indices (0, 0, -1);
4377 rowref = gtk_tree_row_reference_new (filter, path);
4378 gtk_tree_path_free (path);
4380 path = gtk_tree_path_new_from_indices (0, 0, -1);
4381 rowref = gtk_tree_row_reference_new (filter, path);
4382 gtk_tree_path_free (path);
4384 path = gtk_tree_path_new_from_indices (0, -1);
4385 rowref = gtk_tree_row_reference_new (filter, path);
4386 gtk_tree_path_free (path);
4388 /* Deleting the virtual root */
4389 path = gtk_tree_path_new_from_indices (3, 0, -1);
4390 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree), &iter, path);
4391 gtk_tree_store_remove (tree, &iter);
4392 gtk_tree_path_free (path);
4394 gtk_tree_row_reference_free (rowref);
4399 specific_bug_301558_sort_func (GtkTreeModel *model,
4406 gtk_tree_model_get (model, a, 0, &i, -1);
4407 gtk_tree_model_get (model, b, 0, &j, -1);
4413 specific_bug_301558 (void)
4415 /* Test case for GNOME Bugzilla bug 301558 provided by
4419 GtkTreeModel *filter;
4421 GtkTreeIter root, iter, iter2;
4422 GtkWidget *view G_GNUC_UNUSED;
4426 g_test_bug ("301558");
4428 tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
4429 gtk_tree_store_append (tree, &iter, NULL);
4430 gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1);
4431 gtk_tree_store_append (tree, &iter2, &iter);
4432 gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1);
4434 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree));
4435 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort),
4436 specific_bug_301558_sort_func,
4439 filter = gtk_tree_model_filter_new (sort, NULL);
4440 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1);
4442 view = gtk_tree_view_new_with_model (filter);
4444 while (gtk_events_pending ())
4445 gtk_main_iteration ();
4449 for (i = 0; i < 10; i++)
4451 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root))
4452 g_assert_not_reached ();
4456 gtk_tree_store_append (tree, &iter, &root);
4457 gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1);
4462 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root);
4463 gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter,
4465 gtk_tree_store_remove (tree, &iter);
4474 specific_bug_311955_filter_func (GtkTreeModel *model,
4480 gtk_tree_model_get (model, iter, 0, &value, -1);
4482 return (value != 0);
4486 specific_bug_311955 (void)
4488 /* This is a test case for GNOME Bugzilla bug 311955. It was written
4491 GtkTreeIter iter, child, root;
4492 GtkTreeStore *store;
4494 GtkTreeModel *filter;
4496 GtkWidget *window G_GNUC_UNUSED;
4497 GtkWidget *tree_view;
4502 g_test_bug ("311955");
4504 store = gtk_tree_store_new (1, G_TYPE_INT);
4506 gtk_tree_store_append (store, &root, NULL);
4507 gtk_tree_store_set (store, &root, 0, 33, -1);
4509 gtk_tree_store_append (store, &iter, &root);
4510 gtk_tree_store_set (store, &iter, 0, 50, -1);
4512 gtk_tree_store_append (store, &iter, NULL);
4513 gtk_tree_store_set (store, &iter, 0, 22, -1);
4515 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
4516 filter = gtk_tree_model_filter_new (sort, NULL);
4518 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4519 specific_bug_311955_filter_func,
4522 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4523 tree_view = gtk_tree_view_new_with_model (filter);
4524 g_object_unref (store);
4526 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
4528 while (gtk_events_pending ())
4529 gtk_main_iteration ();
4531 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 2);
4532 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
4535 for (i = 0; i < 4; i++)
4537 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
4539 gtk_tree_store_append (store, &iter, &root);
4542 gtk_tree_store_set (store, &iter, 0, i, -1);
4546 gtk_tree_store_append (store, &child, &iter);
4547 gtk_tree_store_set (store, &child, 0, 10, -1);
4551 while (gtk_events_pending ())
4552 gtk_main_iteration ();
4554 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4555 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 1);
4557 /* Remove bottommost child from the tree. */
4558 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root);
4559 n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root);
4561 if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2))
4563 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter))
4564 gtk_tree_store_remove (store, &child);
4567 g_assert_not_reached ();
4569 path = gtk_tree_path_new_from_indices (0, 2, -1);
4570 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
4571 gtk_tree_path_free (path);
4573 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4574 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
4578 specific_bug_311955_clean (void)
4580 /* Cleaned up version of the test case for GNOME Bugzilla bug 311955,
4581 * which is easier to understand.
4583 GtkTreeIter iter, child, grandchild;
4584 GtkTreeStore *store;
4586 GtkTreeModel *filter;
4588 GtkWidget *tree_view;
4591 store = gtk_tree_store_new (1, G_TYPE_INT);
4593 gtk_tree_store_append (store, &iter, NULL);
4594 gtk_tree_store_set (store, &iter, 0, 1, -1);
4596 gtk_tree_store_append (store, &child, &iter);
4597 gtk_tree_store_set (store, &child, 0, 1, -1);
4599 sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
4600 filter = gtk_tree_model_filter_new (sort, NULL);
4602 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4603 specific_bug_311955_filter_func,
4606 tree_view = gtk_tree_view_new_with_model (filter);
4607 g_object_unref (store);
4609 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
4611 while (gtk_events_pending ())
4612 gtk_main_iteration ();
4614 check_level_length (GTK_TREE_MODEL_FILTER (filter), NULL, 1);
4615 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 1);
4617 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
4619 gtk_tree_store_append (store, &child, &iter);
4620 gtk_tree_store_set (store, &child, 0, 0, -1);
4622 gtk_tree_store_append (store, &child, &iter);
4623 gtk_tree_store_set (store, &child, 0, 1, -1);
4625 gtk_tree_store_append (store, &child, &iter);
4626 gtk_tree_store_set (store, &child, 0, 1, -1);
4628 gtk_tree_store_append (store, &grandchild, &child);
4629 gtk_tree_store_set (store, &grandchild, 0, 1, -1);
4631 gtk_tree_store_append (store, &child, &iter);
4632 /* Don't set a value: assume 0 */
4634 /* Remove leaf node, check trigger row-has-child-toggled */
4635 path = gtk_tree_path_new_from_indices (0, 3, 0, -1);
4636 gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
4637 gtk_tree_path_free (path);
4638 gtk_tree_store_remove (store, &iter);
4640 path = gtk_tree_path_new_from_indices (0, 2, -1);
4641 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
4642 gtk_tree_path_free (path);
4644 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0", 3);
4645 check_level_length (GTK_TREE_MODEL_FILTER (filter), "0:2", 0);
4647 gtk_widget_destroy (tree_view);
4651 specific_bug_346800 (void)
4653 /* This is a test case for GNOME Bugzilla bug 346800. It was written
4654 * by Jonathan Matthew.
4657 GtkTreeIter node_iters[50];
4658 GtkTreeIter child_iters[50];
4659 GtkTreeModel *model;
4660 GtkTreeModelFilter *filter;
4661 GtkTreeStore *store;
4665 columns = g_new (GType, 2);
4666 columns[0] = G_TYPE_STRING;
4667 columns[1] = G_TYPE_BOOLEAN;
4668 store = gtk_tree_store_newv (2, columns);
4669 model = GTK_TREE_MODEL (store);
4671 g_test_bug ("346800");
4673 filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
4674 gtk_tree_model_filter_set_visible_column (filter, 1);
4676 for (i=0; i<items; i++)
4678 /* allocate random amounts of junk, otherwise the filter model's arrays can expand without moving */
4681 gtk_tree_store_append (store, &node_iters[i], NULL);
4682 gtk_tree_store_set (store, &node_iters[i],
4684 1, ((i%6) == 0) ? FALSE : TRUE,
4688 gtk_tree_store_append (store, &child_iters[i], &node_iters[i]);
4689 gtk_tree_store_set (store, &child_iters[i],
4690 0, "something else",
4693 gtk_tree_model_filter_refilter (filter);
4697 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1,
4698 (i & 1) ? TRUE : FALSE, -1);
4699 gtk_tree_model_filter_refilter (filter);
4701 gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1,
4702 (i & 1) ? FALSE: TRUE, -1);
4703 gtk_tree_model_filter_refilter (filter);
4709 specific_bug_464173_visible_func (GtkTreeModel *model,
4713 gboolean *visible = (gboolean *)data;
4719 specific_bug_464173 (void)
4721 /* Test case for GNOME Bugzilla bug 464173, test case written
4722 * by Andreas Koehler.
4724 GtkTreeStore *model;
4725 GtkTreeModelFilter *f_model;
4726 GtkTreeIter iter1, iter2;
4727 GtkWidget *view G_GNUC_UNUSED;
4728 gboolean visible = TRUE;
4730 g_test_bug ("464173");
4732 model = gtk_tree_store_new (1, G_TYPE_STRING);
4733 gtk_tree_store_append (model, &iter1, NULL);
4734 gtk_tree_store_set (model, &iter1, 0, "Foo", -1);
4735 gtk_tree_store_append (model, &iter2, &iter1);
4736 gtk_tree_store_set (model, &iter2, 0, "Bar", -1);
4738 f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL));
4739 gtk_tree_model_filter_set_visible_func (f_model,
4740 specific_bug_464173_visible_func,
4743 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model));
4746 gtk_tree_model_filter_refilter (f_model);
4751 specific_bug_540201_filter_func (GtkTreeModel *model,
4755 gboolean has_children;
4757 has_children = gtk_tree_model_iter_has_child (model, iter);
4759 return has_children;
4763 specific_bug_540201 (void)
4765 /* Test case for GNOME Bugzilla bug 540201, steps provided by
4768 GtkTreeIter iter, root;
4769 GtkTreeStore *store;
4770 GtkTreeModel *filter;
4772 GtkWidget *tree_view G_GNUC_UNUSED;
4774 g_test_bug ("540201");
4776 store = gtk_tree_store_new (1, G_TYPE_INT);
4778 gtk_tree_store_append (store, &root, NULL);
4779 gtk_tree_store_set (store, &root, 0, 33, -1);
4781 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4782 tree_view = gtk_tree_view_new_with_model (filter);
4784 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4785 specific_bug_540201_filter_func,
4788 gtk_tree_store_append (store, &iter, &root);
4789 gtk_tree_store_set (store, &iter, 0, 50, -1);
4791 gtk_tree_store_append (store, &iter, &root);
4792 gtk_tree_store_set (store, &iter, 0, 22, -1);
4795 gtk_tree_store_append (store, &root, NULL);
4796 gtk_tree_store_set (store, &root, 0, 33, -1);
4798 gtk_tree_store_append (store, &iter, &root);
4799 gtk_tree_store_set (store, &iter, 0, 22, -1);
4804 specific_bug_549287_visible_func (GtkTreeModel *model,
4808 gboolean result = FALSE;
4810 result = gtk_tree_model_iter_has_child (model, iter);
4816 specific_bug_549287 (void)
4818 /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */
4821 GtkTreeStore *store;
4822 GtkTreeModel *filtered;
4823 GtkWidget *view G_GNUC_UNUSED;
4825 GtkTreeIter *swap, *parent, *child;
4827 g_test_bug ("529287");
4829 store = gtk_tree_store_new (1, G_TYPE_STRING);
4830 filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4831 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered),
4832 specific_bug_549287_visible_func,
4835 view = gtk_tree_view_new_with_model (filtered);
4837 for (i = 0; i < 4; i++)
4839 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
4841 parent = gtk_tree_iter_copy (&iter);
4842 child = gtk_tree_iter_copy (&iter);
4844 while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store),
4853 gtk_tree_store_append (store, child, parent);
4854 gtk_tree_store_set (store, child,
4858 gtk_tree_iter_free (parent);
4859 gtk_tree_iter_free (child);
4863 gtk_tree_store_append (store, &iter, NULL);
4864 gtk_tree_store_set (store, &iter,
4869 /* since we inserted something, we changed the visibility conditions: */
4870 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered));
4875 specific_bug_621076_visible_func (GtkTreeModel *model,
4879 gboolean visible = FALSE;
4882 gtk_tree_model_get (model, iter, 0, &str, -1);
4883 if (str != NULL && g_str_has_prefix (str, "visible"))
4889 GtkTreeIter child_iter;
4892 /* Recursively check if we have a visible child */
4893 for (valid = gtk_tree_model_iter_children (model, &child_iter, iter);
4894 valid; valid = gtk_tree_model_iter_next (model, &child_iter))
4896 if (specific_bug_621076_visible_func (model, &child_iter, data))
4911 specific_bug_621076 (void)
4913 /* Test case for GNOME Bugzilla bug 621076, provided by Xavier Claessens */
4915 /* This test case differs from has-child-filter and root-has-child-filter
4916 * in that the visible function both filters on content and model
4917 * structure. Also, it is recursive.
4920 GtkTreeStore *store;
4921 GtkTreeModel *filter;
4923 GtkTreeIter group_iter;
4924 GtkTreeIter item_iter;
4925 SignalMonitor *monitor;
4927 g_test_bug ("621076");
4929 store = gtk_tree_store_new (1, G_TYPE_STRING);
4930 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
4931 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter),
4932 specific_bug_621076_visible_func,
4935 view = gtk_tree_view_new_with_model (filter);
4936 g_object_ref_sink (view);
4938 monitor = signal_monitor_new (filter);
4940 signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
4941 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
4942 0, "visible-group-0",
4944 signal_monitor_assert_is_empty (monitor);
4946 /* visible-group-0 is not expanded, so ROW_INSERTED should not be emitted
4947 * for its children. However, ROW_HAS_CHILD_TOGGLED should be emitted on
4948 * visible-group-0 to tell the view that row can be expanded. */
4949 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
4950 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "0");
4951 group_iter = item_iter;
4952 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
4955 signal_monitor_assert_is_empty (monitor);
4957 signal_monitor_append_signal (monitor, ROW_INSERTED, "1");
4958 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
4959 0, "visible-group-1",
4961 signal_monitor_assert_is_empty (monitor);
4963 /* We are adding an hidden item inside visible-group-1, so
4964 * ROW_HAS_CHILD_TOGGLED should not be emitted. It is emitted though,
4965 * because the signal originating at TreeStore will be propagated,
4966 * as well a generated signal because the state of the parent *could*
4967 * change by a change in the model.
4969 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
4970 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
4971 group_iter = item_iter;
4972 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
4975 signal_monitor_assert_is_empty (monitor);
4977 /* This group is invisible and its parent too. Nothing should be emitted */
4978 group_iter = item_iter;
4979 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
4982 signal_monitor_assert_is_empty (monitor);
4984 /* Adding a visible item in this group hierarchy will make all nodes
4985 * in this path visible. The first level should simply tell the view
4986 * that it now has a child, and the view will load the tree if needed
4987 * (depends on the expanded state).
4989 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
4990 group_iter = item_iter;
4991 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
4992 0, "visible-1:0:0:0",
4994 signal_monitor_assert_is_empty (monitor);
4996 check_level_length (GTK_TREE_MODEL_FILTER (filter), "1", 1);
4998 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5001 signal_monitor_assert_is_empty (monitor);
5003 /* Parent is invisible, and adding this invisible item won't change that,
5004 * so no signal should be emitted. */
5005 group_iter = item_iter;
5006 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5009 signal_monitor_assert_is_empty (monitor);
5011 /* This makes group-2 visible, so it gets inserted and tells it has
5014 signal_monitor_append_signal (monitor, ROW_INSERTED, "2");
5015 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5016 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5019 signal_monitor_assert_is_empty (monitor);
5021 /* group-2 is already visible, so this time it is a normal insertion */
5022 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5025 signal_monitor_assert_is_empty (monitor);
5028 gtk_tree_store_insert_with_values (store, &item_iter, NULL, -1,
5031 signal_monitor_assert_is_empty (monitor);
5033 /* Parent is invisible, and adding this invisible item won't change that,
5034 * so no signal should be emitted. */
5035 group_iter = item_iter;
5036 gtk_tree_store_insert_with_values (store, NULL, &group_iter, -1,
5039 signal_monitor_assert_is_empty (monitor);
5041 gtk_tree_store_insert_with_values (store, &item_iter, &group_iter, -1,
5044 signal_monitor_assert_is_empty (monitor);
5046 /* This will make group 3 visible. */
5047 signal_monitor_append_signal (monitor, ROW_INSERTED, "3");
5048 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
5049 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "3");
5050 gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
5051 signal_monitor_assert_is_empty (monitor);
5053 /* Make sure all groups are expanded, so the filter has the tree cached */
5054 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
5055 while (gtk_events_pending ())
5056 gtk_main_iteration ();
5058 /* Should only yield a row-changed */
5059 signal_monitor_append_signal (monitor, ROW_CHANGED, "3:0");
5060 gtk_tree_store_set (store, &item_iter, 0, "visible-3:1", -1);
5061 signal_monitor_assert_is_empty (monitor);
5063 /* Now remove/hide some items. If a group loses its last item, the group
5064 * should be deleted instead of the item.
5067 signal_monitor_append_signal (monitor, ROW_DELETED, "2:1");
5068 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:2");
5069 gtk_tree_store_remove (store, &item_iter);
5070 signal_monitor_assert_is_empty (monitor);
5072 signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
5073 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5074 signal_monitor_append_signal (monitor, ROW_DELETED, "2");
5075 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "2:1");
5076 gtk_tree_store_set (store, &item_iter, 0, "invisible-2:1", -1);
5077 signal_monitor_assert_is_empty (monitor);
5079 signal_monitor_append_signal (monitor, ROW_DELETED, "1:0:0:0");
5080 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1:0:0");
5081 signal_monitor_append_signal (monitor, ROW_DELETED, "1:0");
5082 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "1");
5083 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter, "1:0:0:0");
5084 gtk_tree_store_remove (store, &item_iter);
5085 signal_monitor_assert_is_empty (monitor);
5087 /* Hide a group using row-changed instead of row-deleted */
5088 /* Caution: group 2 is gone, so offsets of the signals have moved. */
5089 signal_monitor_append_signal (monitor, ROW_DELETED, "2:0");
5090 signal_monitor_append_signal (monitor, ROW_HAS_CHILD_TOGGLED, "2");
5091 signal_monitor_append_signal (monitor, ROW_DELETED, "2");
5092 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &item_iter,
5094 gtk_tree_store_set (store, &item_iter, 0, "invisible-3:1", -1);
5095 signal_monitor_assert_is_empty (monitor);
5100 GtkTreeViewColumn *col;
5102 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
5104 col = gtk_tree_view_column_new_with_attributes ("foo",
5105 gtk_cell_renderer_text_new (),
5107 gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
5109 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5110 g_signal_connect (window, "delete-event",
5111 G_CALLBACK (gtk_widget_destroy), NULL);
5112 g_signal_connect (window, "destroy",
5113 G_CALLBACK (gtk_main_quit), NULL);
5115 gtk_container_add (GTK_CONTAINER (window), view);
5117 gtk_widget_show (view);
5118 gtk_widget_show (window);
5125 signal_monitor_free (monitor);
5126 g_object_unref (view);
5127 g_object_unref (store);
5128 g_object_unref (filter);
5134 register_filter_model_tests (void)
5136 g_test_add ("/TreeModelFilter/self/verify-test-suite",
5140 filter_test_teardown);
5142 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-1",
5143 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5145 verify_test_suite_vroot,
5146 filter_test_teardown);
5147 g_test_add ("/TreeModelFilter/self/verify-test-suite/vroot/depth-2",
5148 FilterTest, gtk_tree_path_new_from_indices (2, 3, -1),
5150 verify_test_suite_vroot,
5151 filter_test_teardown);
5154 g_test_add ("/TreeModelFilter/filled/hide-root-level",
5157 filled_hide_root_level,
5158 filter_test_teardown);
5159 g_test_add ("/TreeModelFilter/filled/hide-child-levels",
5162 filled_hide_child_levels,
5163 filter_test_teardown);
5164 g_test_add ("/TreeModelFilter/filled/hide-child-levels/root-expanded",
5167 filled_hide_child_levels_root_expanded,
5168 filter_test_teardown);
5170 g_test_add ("/TreeModelFilter/filled/hide-root-level/vroot",
5171 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5173 filled_vroot_hide_root_level,
5174 filter_test_teardown);
5175 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot",
5176 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5178 filled_vroot_hide_child_levels,
5179 filter_test_teardown);
5180 g_test_add ("/TreeModelFilter/filled/hide-child-levels/vroot-root-expanded",
5181 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5183 filled_vroot_hide_child_levels_root_expanded,
5184 filter_test_teardown);
5187 g_test_add ("/TreeModelFilter/empty/show-nodes",
5189 filter_test_setup_empty,
5191 filter_test_teardown);
5192 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes",
5194 filter_test_setup_empty,
5195 empty_show_multiple_nodes,
5196 filter_test_teardown);
5198 g_test_add ("/TreeModelFilter/empty/show-nodes/vroot",
5199 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5200 filter_test_setup_empty,
5201 empty_vroot_show_nodes,
5202 filter_test_teardown);
5203 g_test_add ("/TreeModelFilter/empty/show-multiple-nodes/vroot",
5204 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5205 filter_test_setup_empty,
5206 empty_vroot_show_multiple_nodes,
5207 filter_test_teardown);
5210 g_test_add ("/TreeModelFilter/unfiltered/hide-single",
5212 filter_test_setup_unfiltered,
5213 unfiltered_hide_single,
5214 filter_test_teardown);
5215 g_test_add ("/TreeModelFilter/unfiltered/hide-single/root-expanded",
5217 filter_test_setup_unfiltered_root_expanded,
5218 unfiltered_hide_single_root_expanded,
5219 filter_test_teardown);
5220 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child",
5222 filter_test_setup_unfiltered,
5223 unfiltered_hide_single_child,
5224 filter_test_teardown);
5225 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/root-expanded",
5227 filter_test_setup_unfiltered_root_expanded,
5228 unfiltered_hide_single_child_root_expanded,
5229 filter_test_teardown);
5230 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level",
5232 filter_test_setup_unfiltered,
5233 unfiltered_hide_single_multi_level,
5234 filter_test_teardown);
5235 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/root-expanded",
5237 filter_test_setup_unfiltered_root_expanded,
5238 unfiltered_hide_single_multi_level_root_expanded,
5239 filter_test_teardown);
5241 g_test_add ("/TreeModelFilter/unfiltered/hide-single/vroot",
5242 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5243 filter_test_setup_unfiltered,
5244 unfiltered_vroot_hide_single,
5245 filter_test_teardown);
5246 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot",
5247 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5248 filter_test_setup_unfiltered,
5249 unfiltered_vroot_hide_single_child,
5250 filter_test_teardown);
5251 g_test_add ("/TreeModelFilter/unfiltered/hide-single-child/vroot/root-expanded",
5252 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5253 filter_test_setup_unfiltered_root_expanded,
5254 unfiltered_vroot_hide_single_child_root_expanded,
5255 filter_test_teardown);
5256 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot",
5257 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5258 filter_test_setup_unfiltered,
5259 unfiltered_vroot_hide_single_multi_level,
5260 filter_test_teardown);
5261 g_test_add ("/TreeModelFilter/unfiltered/hide-single-multi-level/vroot/root-expanded",
5262 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5263 filter_test_setup_unfiltered_root_expanded,
5264 unfiltered_vroot_hide_single_multi_level_root_expanded,
5265 filter_test_teardown);
5269 g_test_add ("/TreeModelFilter/unfiltered/show-single",
5271 filter_test_setup_empty_unfiltered,
5272 unfiltered_show_single,
5273 filter_test_teardown);
5274 g_test_add ("/TreeModelFilter/unfiltered/show-single-child",
5276 filter_test_setup_empty_unfiltered,
5277 unfiltered_show_single_child,
5278 filter_test_teardown);
5279 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/root-expanded",
5281 filter_test_setup_empty_unfiltered_root_expanded,
5282 unfiltered_show_single_child_root_expanded,
5283 filter_test_teardown);
5284 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level",
5286 filter_test_setup_empty_unfiltered,
5287 unfiltered_show_single_multi_level,
5288 filter_test_teardown);
5289 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/root-expanded",
5291 filter_test_setup_empty_unfiltered_root_expanded,
5292 unfiltered_show_single_multi_level_root_expanded,
5293 filter_test_teardown);
5295 g_test_add ("/TreeModelFilter/unfiltered/show-single/vroot",
5296 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5297 filter_test_setup_empty_unfiltered,
5298 unfiltered_vroot_show_single,
5299 filter_test_teardown);
5300 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot",
5301 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5302 filter_test_setup_empty_unfiltered,
5303 unfiltered_vroot_show_single_child,
5304 filter_test_teardown);
5305 g_test_add ("/TreeModelFilter/unfiltered/show-single-child/vroot/root-expanded",
5306 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5307 filter_test_setup_empty_unfiltered_root_expanded,
5308 unfiltered_vroot_show_single_child_root_expanded,
5309 filter_test_teardown);
5310 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot",
5311 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5312 filter_test_setup_empty_unfiltered,
5313 unfiltered_vroot_show_single_multi_level,
5314 filter_test_teardown);
5315 g_test_add ("/TreeModelFilter/unfiltered/show-single-multi-level/vroot/root-expanded",
5316 FilterTest, gtk_tree_path_new_from_indices (2, -1),
5317 filter_test_setup_empty_unfiltered_root_expanded,
5318 unfiltered_vroot_show_single_multi_level_root_expanded,
5319 filter_test_teardown);
5322 g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/root-level",
5324 filter_test_setup_unfiltered,
5325 unfiltered_rows_reordered_root_level,
5326 filter_test_teardown);
5327 g_test_add ("/TreeModelFilter/unfiltered/rows-reordered/child-level",
5329 filter_test_setup_unfiltered,
5330 unfiltered_rows_reordered_child_level,
5331 filter_test_teardown);
5333 g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/first-hidden",
5336 filtered_rows_reordered_root_level_first_hidden,
5337 filter_test_teardown);
5338 g_test_add ("/TreeModelFilter/filtered/rows-reordered/root-level/middle-hidden",
5341 filtered_rows_reordered_root_level_middle_hidden,
5342 filter_test_teardown);
5343 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/first-hidden",
5346 filtered_rows_reordered_child_level_first_hidden,
5347 filter_test_teardown);
5348 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/middle-hidden",
5351 filtered_rows_reordered_child_level_middle_hidden,
5352 filter_test_teardown);
5353 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/4-hidden",
5356 filtered_rows_reordered_child_level_4_hidden,
5357 filter_test_teardown);
5358 g_test_add ("/TreeModelFilter/filtered/rows-reordered/child-level/all-hidden",
5361 filtered_rows_reordered_child_level_all_hidden,
5362 filter_test_teardown);
5364 /* Inserts in child models after creation of filter model */
5365 g_test_add_func ("/TreeModelFilter/insert/before",
5367 g_test_add_func ("/TreeModelFilter/insert/child",
5370 /* Removals from child model after creating of filter model */
5371 g_test_add_func ("/TreeModelFilter/remove/node",
5373 g_test_add_func ("/TreeModelFilter/remove/node-vroot",
5375 g_test_add_func ("/TreeModelFilter/remove/vroot-ancestor",
5376 remove_vroot_ancestor);
5378 /* Reference counting */
5379 g_test_add_func ("/TreeModelFilter/ref-count/single-level",
5380 ref_count_single_level);
5381 g_test_add_func ("/TreeModelFilter/ref-count/two-levels",
5382 ref_count_two_levels);
5383 g_test_add_func ("/TreeModelFilter/ref-count/three-levels",
5384 ref_count_three_levels);
5385 g_test_add_func ("/TreeModelFilter/ref-count/delete-row",
5386 ref_count_delete_row);
5387 g_test_add_func ("/TreeModelFilter/ref-count/cleanup",
5389 g_test_add_func ("/TreeModelFilter/ref-count/row-ref",
5392 /* Reference counting, transfer of first reference on
5393 * first node in level. This is a GtkTreeModelFilter-specific
5396 g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/insert",
5397 ref_count_transfer_root_level_insert);
5398 g_test_add_func ("/TreeModelFilter/ref-count/transfer/root-level/reordered",
5399 ref_count_transfer_root_level_reordered);
5400 g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/insert",
5401 ref_count_transfer_child_level_insert);
5402 g_test_add_func ("/TreeModelFilter/ref-count/transfer/child-level/reordered",
5403 ref_count_transfer_child_level_reordered);
5405 g_test_add_func ("/TreeModelFilter/specific/path-dependent-filter",
5406 specific_path_dependent_filter);
5407 g_test_add_func ("/TreeModelFilter/specific/append-after-collapse",
5408 specific_append_after_collapse);
5409 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-node",
5410 specific_sort_filter_remove_node);
5411 g_test_add_func ("/TreeModelFilter/specific/sort-filter-remove-root",
5412 specific_sort_filter_remove_root);
5413 g_test_add_func ("/TreeModelFilter/specific/root-mixed-visibility",
5414 specific_root_mixed_visibility);
5415 g_test_add_func ("/TreeModelFilter/specific/has-child-filter",
5416 specific_has_child_filter);
5417 g_test_add_func ("/TreeModelFilter/specific/has-child-filter-on-sort-model",
5418 specific_has_child_filter_on_sort_model);
5419 g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter",
5420 specific_at_least_2_children_filter);
5421 g_test_add_func ("/TreeModelFilter/specific/at-least-2-children-filter-on-sort-model",
5422 specific_at_least_2_children_filter_on_sort_model);
5423 g_test_add_func ("/TreeModelFilter/specific/root-has-child-filter",
5424 specific_root_has_child_filter);
5425 g_test_add_func ("/TreeModelFilter/specific/filter-add-child",
5426 specific_filter_add_child);
5427 g_test_add_func ("/TreeModelFilter/specific/list-store-clear",
5428 specific_list_store_clear);
5429 g_test_add_func ("/TreeModelFilter/specific/sort-ref-leaf-and-remove-ancestor",
5430 specific_sort_ref_leaf_and_remove_ancestor);
5431 g_test_add_func ("/TreeModelFilter/specific/ref-leaf-and-remove-ancestor",
5432 specific_ref_leaf_and_remove_ancestor);
5433 g_test_add_func ("/TreeModelFilter/specific/virtual-ref-leaf-and-remove-ancestor",
5434 specific_virtual_ref_leaf_and_remove_ancestor);
5436 g_test_add_func ("/TreeModelFilter/specific/bug-301558",
5437 specific_bug_301558);
5438 g_test_add_func ("/TreeModelFilter/specific/bug-311955",
5439 specific_bug_311955);
5440 g_test_add_func ("/TreeModelFilter/specific/bug-311955-clean",
5441 specific_bug_311955_clean);
5442 g_test_add_func ("/TreeModelFilter/specific/bug-346800",
5443 specific_bug_346800);
5444 g_test_add_func ("/TreeModelFilter/specific/bug-464173",
5445 specific_bug_464173);
5446 g_test_add_func ("/TreeModelFilter/specific/bug-540201",
5447 specific_bug_540201);
5448 g_test_add_func ("/TreeModelFilter/specific/bug-549287",
5449 specific_bug_549287);
5450 g_test_add_func ("/TreeModelFilter/specific/bug-621076",
5451 specific_bug_621076);