1 /* gtktreemodelfilter.c
2 * Copyright (C) 2000,2001 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
3 * Copyright (C) 2001-2003 Kristian Rietveld <kris@gtk.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20 #include "gtktreemodelfilter.h"
22 #include "gtktreednd.h"
23 #include "gtkprivate.h"
28 * SECTION:gtktreemodelfilter
29 * @Short_description: A GtkTreeModel which hides parts of an underlying tree model
30 * @Title: GtkTreeModelFilter
31 * @See_also:#GtkTreeModelSort
33 * A #GtkTreeModelFilter is a tree model which wraps another tree model,
34 * and can do the following things:
37 * Filter specific rows, based on data from a "visible column", a column
38 * storing booleans indicating whether the row should be filtered or not,
39 * or based on the return value of a "visible function", which gets a
40 * model, iter and user_data and returns a boolean indicating whether the
41 * row should be filtered or not.
44 * Modify the "appearance" of the model, using a modify function.
45 * This is extremely powerful and allows for just changing
46 * some values and also for creating a completely different model based on
47 * the given child model.
50 * Set a different root node, also known as a "virtual root". You can pass in
51 * a #GtkTreePath indicating the root node for the filter at construction time.
55 * The basic API is similar to #GtkTreeModelSort. For an example on its usage,
56 * see the section on #GtkTreeModelSort.
58 * When using #GtkTreeModelFilter, it is important to realize that
59 * #GtkTreeModelFilter maintains an internal cache of all nodes which are
60 * visible in its clients. The cache is likely to be a subtree of the tree
61 * exposed by the child model. #GtkTreeModelFilter will not cache the entire
62 * child model when unnecessary to not compromise the caching mechanism
63 * that is exposed by the reference counting scheme. If the child model
64 * implements reference counting, unnecessary signals may not be emitted
65 * because of reference counting rule 3, see the #GtkTreeModel
66 * documentation. (Note that e.g. #GtkTreeStore does not implement
67 * reference counting and will always emit all signals, even when
68 * the receiving node is not visible).
70 * Because of this, limitations for possible visible functions do apply.
71 * In general, visible functions should only use data or properties from
72 * the node for which the visibility state must be determined, its siblings
73 * or its parents. Usually, having a dependency on the state of any child
74 * node is not possible, unless references are taken on these explicitly.
75 * When no such reference exists, no signals may be received for these child
76 * nodes (see reference couting rule number 3 in the #GtkTreeModel section).
78 * Determining the visibility state of a given node based on the state
79 * of its child nodes is a frequently occurring use case. Therefore,
80 * #GtkTreeModelFilter explicitly supports this. For example, when a node
81 * does not have any children, you might not want the node to be visible.
82 * As soon as the first row is added to the node's child level (or the
83 * last row removed), the node's visibility should be updated.
85 * This introduces a dependency from the node on its child nodes. In order
86 * to accommodate this, #GtkTreeModelFilter must make sure the necesary
87 * signals are received from the child model. This is achieved by building,
88 * for all nodes which are exposed as visible nodes to #GtkTreeModelFilter's
89 * clients, the child level (if any) and take a reference on the first node
90 * in this level. Furthermore, for every row-inserted, row-changed or
91 * row-deleted signal (also these which were not handled because the node
92 * was not cached), #GtkTreeModelFilter will check if the visibility state
93 * of any parent node has changed.
95 * Beware, however, that this explicit support is limited to these two
96 * cases. For example, if you want a node to be visible only if two nodes
97 * in a child's child level (2 levels deeper) are visible, you are on your
98 * own. In this case, either rely on #GtkTreeStore to emit all signals
99 * because it does not implement reference counting, or for models that
100 * do implement reference counting, obtain references on these child levels
104 /* Notes on this implementation of GtkTreeModelFilter
105 * ==================================================
110 * In this code there is a potential for confusion as to whether an iter,
111 * path or value refers to the GtkTreeModelFilter model, or to the child
112 * model that has been set. As a convention, variables referencing the
113 * child model will have a c_ prefix before them (ie. c_iter, c_value,
114 * c_path). In case the c_ prefixed names are already in use, an f_
115 * prefix is used. Conversion of iterators and paths between
116 * GtkTreeModelFilter and the child model is done through the various
117 * gtk_tree_model_filter_convert_* functions.
119 * Even though the GtkTreeModelSort and GtkTreeModelFilter have very
120 * similar data structures, many assumptions made in the GtkTreeModelSort
121 * code do *not* apply in the GtkTreeModelFilter case. Reference counting
122 * in particular is more complicated in GtkTreeModelFilter, because
123 * we explicitly support reliance on the state of a node's children as
124 * outlined in the public API documentation. Because of these differences,
125 * you are strongly recommended to first read through these notes before
126 * making any modification to the code.
131 * The iterator format of iterators handed out by GtkTreeModelFilter is
134 * iter->stamp = filter->priv->stamp
135 * iter->user_data = FilterLevel
136 * iter->user_data2 = FilterElt
138 * Internal data structure
139 * -----------------------
141 * Using FilterLevel and FilterElt, GtkTreeModelFilter maintains a "cache"
142 * of the mapping from GtkTreeModelFilter nodes to nodes in the child model.
143 * This is to avoid re-creating a level each time (which involves computing
144 * visibility for each node in that level) an operation is requested on
145 * GtkTreeModelFilter, such as get iter, get path and get value.
147 * A FilterElt corresponds to a single node. The FilterElt can either be
148 * visible or invisible in the model that is exposed to the clients of this
149 * GtkTreeModelFilter. The visibility state is stored in the "visible_siter"
150 * field, which is NULL when the node is not visible. The FilterLevel keeps
151 * a reference to the parent FilterElt and its FilterLevel (if any). The
152 * FilterElt can have a "children" pointer set, which points at a child
153 * level (a sub level).
155 * In a FilterLevel, two separate GSequences are maintained. One contains
156 * all nodes of this FilterLevel, regardless of the visibility state of
157 * the node. Another contains only visible nodes. A visible FilterElt
158 * is thus present in both the full and the visible GSequence. The
159 * GSequence allows for fast access, addition and removal of nodes.
161 * It is important to recognize the two different mappings that play
162 * a part in this code:
163 * I. The mapping from the client to this model. The order in which
164 * nodes are stored in the *visible* GSequence is the order in
165 * which the nodes are exposed to clients of the GtkTreeModelFilter.
166 * II. The mapping from this model to its child model. Each FilterElt
167 * contains an "offset" field which is the offset of the
168 * corresponding node in the child model.
170 * Throughout the code, two kinds of paths relative to the GtkTreeModelFilter
171 * (those generated from the sequence positions) are used. There are paths
172 * which take non-visible nodes into account (generated from the full
173 * sequences) and paths which don't (generated from the visible sequences).
174 * Paths which have been generated from the full sequences should only be
175 * used internally and NEVER be passed along with a signal emisson.
180 * GtkTreeModelFilter forwards all reference and unreference operations
181 * to the corresponding node in the child model. In addition,
182 * GtkTreeModelFilter will also add references of its own. The full reference
183 * count of each node (i.e. all forwarded references and these by the
184 * filter model) is maintained internally in the "ref_count" fields in
185 * FilterElt and FilterLevel. Because there is a need to determine whether
186 * a node should be visible for the client, the reference count of only
187 * the forwarded references is maintained as well, in the "ext_ref_count"
190 * In a few cases, GtkTreeModelFilter takes additional references on
191 * nodes. The first case is that a reference is taken on the parent
192 * (if any) of each level. This happens in gtk_tree_model_filter_build_level()
193 * and the reference is released again in gtk_tree_model_filter_free_level().
194 * This ensures that for all references which are taken by the filter
195 * model, all parent nodes are referenced according to reference counting
196 * rule 1 in the GtkTreeModel documentation.
198 * A second case is required to support visible functions which depend on
199 * the state of a node's children (see the public API documentation for
200 * GtkTreeModelFilter above). We build the child level of each node that
201 * could be visible in the client (i.e. the level has an ext_ref_count > 0;
202 * not the elt, because the elt might be invisible and thus unreferenced
203 * by the client). For each node that becomes visible, due to insertion or
204 * changes in visibility state, it is checked whether node has children, if
205 * so the child level is built.
207 * A reference is taken on the first node of each level so that the child
208 * model will emit all signals for this level, due to reference counting
209 * rule 3 in the GtkTreeModel documentation. If due to changes in the level,
210 * another node becomes the first node (e.g. due to insertion or reordering),
211 * this reference is transferred from the old to the new first node.
213 * When a level has an *external* reference count of zero (which means that
214 * none of the nodes in the level is referenced by the clients), the level
215 * has a "zero ref count" on all its parents. As soon as the level reaches
216 * an *external* reference count of zero, the zero ref count value is
217 * incremented by one for all parents of this level. Due to the additional
218 * references taken by the filter model, it is important to base the
219 * zero ref count on the external reference count instead of on the full
220 * reference count of the node.
222 * The zero ref count value aids in determining which portions of the
223 * cache are possibly unused and could be removed. If a FilterElt has
224 * a zero ref count of one, then its child level is unused. However, the
225 * child level can only be removed from the cache if the FilterElt's
226 * parent level has an external ref count of zero. (Not the parent elt,
227 * because an invisible parent elt with external ref count == 0 might still
228 * become visible because of a state change in its child level!). Otherwise,
229 * monitoring this level is necessary to possibly update the visibility state
230 * of the parent. This is an important difference from GtkTreeModelSort!
232 * Signals are only required for levels with an external ref count > 0.
233 * This due to reference counting rule 3, see the GtkTreeModel
234 * documentation. In the GtkTreeModelFilter we try hard to stick to this
235 * rule and not emit redundant signals (though redundant emissions of
236 * row-has-child-toggled could appear frequently; it does happen that
237 * we simply forward the signal emitted by e.g. GtkTreeStore but also
238 * emit our own copy).
242 typedef struct _FilterElt FilterElt;
243 typedef struct _FilterLevel FilterLevel;
248 FilterLevel *children;
253 GSequenceIter *visible_siter; /* iter into visible_seq */
259 GSequence *visible_seq;
263 FilterElt *parent_elt;
264 FilterLevel *parent_level;
268 struct _GtkTreeModelFilterPrivate
270 GtkTreeModel *child_model;
272 GtkTreePath *virtual_root;
279 GtkTreeModelFilterVisibleFunc visible_func;
280 gpointer visible_data;
281 GDestroyNotify visible_destroy;
284 GtkTreeModelFilterModifyFunc modify_func;
285 gpointer modify_data;
286 GDestroyNotify modify_destroy;
287 gint modify_n_columns;
289 guint visible_method_set : 1;
290 guint modify_func_set : 1;
292 guint in_row_deleted : 1;
293 guint virtual_root_deleted : 1;
298 gulong has_child_toggled_id;
311 /* Set this to 0 to disable caching of child iterators. This
312 * allows for more stringent testing. It is recommended to set this
313 * to one when refactoring this code and running the unit tests to
317 # define GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS(filter) \
318 (((GtkTreeModelFilter *)filter)->priv->child_flags & GTK_TREE_MODEL_ITERS_PERSIST)
320 # define GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS(filter) (FALSE)
323 /* Defining this constant enables more assertions, which will be
324 * helpful when debugging the code.
326 #undef MODEL_FILTER_DEBUG
328 #define FILTER_ELT(filter_elt) ((FilterElt *)filter_elt)
329 #define FILTER_LEVEL(filter_level) ((FilterLevel *)filter_level)
330 #define GET_ELT(siter) ((FilterElt*) (siter ? g_sequence_get (siter) : NULL))
332 /* general code (object/interface init, properties, etc) */
333 static void gtk_tree_model_filter_tree_model_init (GtkTreeModelIface *iface);
334 static void gtk_tree_model_filter_drag_source_init (GtkTreeDragSourceIface *iface);
335 static void gtk_tree_model_filter_finalize (GObject *object);
336 static void gtk_tree_model_filter_set_property (GObject *object,
340 static void gtk_tree_model_filter_get_property (GObject *object,
345 /* signal handlers */
346 static void gtk_tree_model_filter_row_changed (GtkTreeModel *c_model,
350 static void gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
354 static void gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *c_model,
358 static void gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model,
361 static void gtk_tree_model_filter_rows_reordered (GtkTreeModel *c_model,
367 /* GtkTreeModel interface */
368 static GtkTreeModelFlags gtk_tree_model_filter_get_flags (GtkTreeModel *model);
369 static gint gtk_tree_model_filter_get_n_columns (GtkTreeModel *model);
370 static GType gtk_tree_model_filter_get_column_type (GtkTreeModel *model,
372 static gboolean gtk_tree_model_filter_get_iter_full (GtkTreeModel *model,
375 static gboolean gtk_tree_model_filter_get_iter (GtkTreeModel *model,
378 static GtkTreePath *gtk_tree_model_filter_get_path (GtkTreeModel *model,
380 static void gtk_tree_model_filter_get_value (GtkTreeModel *model,
384 static gboolean gtk_tree_model_filter_iter_next (GtkTreeModel *model,
386 static gboolean gtk_tree_model_filter_iter_previous (GtkTreeModel *model,
388 static gboolean gtk_tree_model_filter_iter_children (GtkTreeModel *model,
390 GtkTreeIter *parent);
391 static gboolean gtk_tree_model_filter_iter_has_child (GtkTreeModel *model,
393 static gint gtk_tree_model_filter_iter_n_children (GtkTreeModel *model,
395 static gboolean gtk_tree_model_filter_iter_nth_child (GtkTreeModel *model,
399 static gboolean gtk_tree_model_filter_iter_parent (GtkTreeModel *model,
402 static void gtk_tree_model_filter_ref_node (GtkTreeModel *model,
404 static void gtk_tree_model_filter_unref_node (GtkTreeModel *model,
407 /* TreeDragSource interface */
408 static gboolean gtk_tree_model_filter_row_draggable (GtkTreeDragSource *drag_source,
410 static gboolean gtk_tree_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
412 GtkSelectionData *selection_data);
413 static gboolean gtk_tree_model_filter_drag_data_delete (GtkTreeDragSource *drag_source,
416 /* private functions */
417 static void gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter,
418 FilterLevel *parent_level,
419 FilterElt *parent_elt,
420 gboolean emit_inserted);
422 static void gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter,
423 FilterLevel *filter_level,
425 gboolean unref_parent,
426 gboolean unref_external);
428 static GtkTreePath *gtk_tree_model_filter_elt_get_path (FilterLevel *level,
432 static GtkTreePath *gtk_tree_model_filter_add_root (GtkTreePath *src,
434 static GtkTreePath *gtk_tree_model_filter_remove_root (GtkTreePath *src,
437 static void gtk_tree_model_filter_increment_stamp (GtkTreeModelFilter *filter);
439 static void gtk_tree_model_filter_real_modify (GtkTreeModelFilter *self,
440 GtkTreeModel *child_model,
444 static gboolean gtk_tree_model_filter_real_visible (GtkTreeModelFilter *filter,
445 GtkTreeModel *child_model,
446 GtkTreeIter *child_iter);
447 static gboolean gtk_tree_model_filter_visible (GtkTreeModelFilter *filter,
448 GtkTreeIter *child_iter);
449 static void gtk_tree_model_filter_clear_cache_helper (GtkTreeModelFilter *filter,
452 static void gtk_tree_model_filter_real_ref_node (GtkTreeModel *model,
455 static void gtk_tree_model_filter_real_unref_node (GtkTreeModel *model,
458 gboolean propagate_unref);
460 static void gtk_tree_model_filter_set_model (GtkTreeModelFilter *filter,
461 GtkTreeModel *child_model);
462 static void gtk_tree_model_filter_ref_path (GtkTreeModelFilter *filter,
464 static void gtk_tree_model_filter_unref_path (GtkTreeModelFilter *filter,
467 static void gtk_tree_model_filter_set_root (GtkTreeModelFilter *filter,
470 static GtkTreePath *gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filter,
471 GtkTreePath *child_path,
472 gboolean build_levels,
473 gboolean fetch_children);
475 static gboolean gtk_tree_model_filter_elt_is_visible_in_target (FilterLevel *level,
478 static FilterElt *gtk_tree_model_filter_insert_elt_in_level (GtkTreeModelFilter *filter,
483 static FilterElt *gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter,
487 static void gtk_tree_model_filter_remove_elt_from_level (GtkTreeModelFilter *filter,
490 static void gtk_tree_model_filter_update_children (GtkTreeModelFilter *filter,
493 static void gtk_tree_model_filter_emit_row_inserted_for_path (GtkTreeModelFilter *filter,
494 GtkTreeModel *c_model,
496 GtkTreeIter *c_iter);
499 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelFilter, gtk_tree_model_filter, G_TYPE_OBJECT,
500 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
501 gtk_tree_model_filter_tree_model_init)
502 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
503 gtk_tree_model_filter_drag_source_init))
506 gtk_tree_model_filter_init (GtkTreeModelFilter *filter)
508 filter->priv = G_TYPE_INSTANCE_GET_PRIVATE (filter,
509 GTK_TYPE_TREE_MODEL_FILTER,
510 GtkTreeModelFilterPrivate);
512 filter->priv->visible_column = -1;
513 filter->priv->zero_ref_count = 0;
514 filter->priv->visible_method_set = FALSE;
515 filter->priv->modify_func_set = FALSE;
516 filter->priv->in_row_deleted = FALSE;
517 filter->priv->virtual_root_deleted = FALSE;
521 gtk_tree_model_filter_class_init (GtkTreeModelFilterClass *filter_class)
523 GObjectClass *object_class;
525 object_class = (GObjectClass *) filter_class;
527 object_class->set_property = gtk_tree_model_filter_set_property;
528 object_class->get_property = gtk_tree_model_filter_get_property;
530 object_class->finalize = gtk_tree_model_filter_finalize;
532 filter_class->visible = gtk_tree_model_filter_real_visible;
533 filter_class->modify = gtk_tree_model_filter_real_modify;
535 /* Properties -- FIXME: disabled translations for now, until I can come up with a
538 g_object_class_install_property (object_class,
540 g_param_spec_object ("child-model",
542 ("The model for the filtermodel to filter"),
544 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
546 g_object_class_install_property (object_class,
548 g_param_spec_boxed ("virtual-root",
549 ("The virtual root"),
550 ("The virtual root (relative to the child model) for this filtermodel"),
552 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
554 g_type_class_add_private (object_class, sizeof (GtkTreeModelFilterPrivate));
558 gtk_tree_model_filter_tree_model_init (GtkTreeModelIface *iface)
560 iface->get_flags = gtk_tree_model_filter_get_flags;
561 iface->get_n_columns = gtk_tree_model_filter_get_n_columns;
562 iface->get_column_type = gtk_tree_model_filter_get_column_type;
563 iface->get_iter = gtk_tree_model_filter_get_iter;
564 iface->get_path = gtk_tree_model_filter_get_path;
565 iface->get_value = gtk_tree_model_filter_get_value;
566 iface->iter_next = gtk_tree_model_filter_iter_next;
567 iface->iter_previous = gtk_tree_model_filter_iter_previous;
568 iface->iter_children = gtk_tree_model_filter_iter_children;
569 iface->iter_has_child = gtk_tree_model_filter_iter_has_child;
570 iface->iter_n_children = gtk_tree_model_filter_iter_n_children;
571 iface->iter_nth_child = gtk_tree_model_filter_iter_nth_child;
572 iface->iter_parent = gtk_tree_model_filter_iter_parent;
573 iface->ref_node = gtk_tree_model_filter_ref_node;
574 iface->unref_node = gtk_tree_model_filter_unref_node;
578 gtk_tree_model_filter_drag_source_init (GtkTreeDragSourceIface *iface)
580 iface->row_draggable = gtk_tree_model_filter_row_draggable;
581 iface->drag_data_delete = gtk_tree_model_filter_drag_data_delete;
582 iface->drag_data_get = gtk_tree_model_filter_drag_data_get;
587 gtk_tree_model_filter_finalize (GObject *object)
589 GtkTreeModelFilter *filter = (GtkTreeModelFilter *) object;
591 if (filter->priv->virtual_root && !filter->priv->virtual_root_deleted)
593 gtk_tree_model_filter_unref_path (filter, filter->priv->virtual_root,
595 filter->priv->virtual_root_deleted = TRUE;
598 gtk_tree_model_filter_set_model (filter, NULL);
600 if (filter->priv->virtual_root)
601 gtk_tree_path_free (filter->priv->virtual_root);
603 if (filter->priv->root)
604 gtk_tree_model_filter_free_level (filter, filter->priv->root, TRUE, TRUE, FALSE);
606 g_free (filter->priv->modify_types);
608 if (filter->priv->modify_destroy)
609 filter->priv->modify_destroy (filter->priv->modify_data);
611 if (filter->priv->visible_destroy)
612 filter->priv->visible_destroy (filter->priv->visible_data);
615 G_OBJECT_CLASS (gtk_tree_model_filter_parent_class)->finalize (object);
619 gtk_tree_model_filter_set_property (GObject *object,
624 GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (object);
628 case PROP_CHILD_MODEL:
629 gtk_tree_model_filter_set_model (filter, g_value_get_object (value));
631 case PROP_VIRTUAL_ROOT:
632 gtk_tree_model_filter_set_root (filter, g_value_get_boxed (value));
635 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
641 gtk_tree_model_filter_get_property (GObject *object,
646 GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (object);
650 case PROP_CHILD_MODEL:
651 g_value_set_object (value, filter->priv->child_model);
653 case PROP_VIRTUAL_ROOT:
654 g_value_set_boxed (value, filter->priv->virtual_root);
657 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
665 filter_elt_new (void)
667 return g_slice_new (FilterElt);
671 filter_elt_free (gpointer elt)
673 g_slice_free (FilterElt, elt);
677 filter_elt_cmp (gconstpointer a,
681 const FilterElt *elt_a = a;
682 const FilterElt *elt_b = b;
684 if (elt_a->offset > elt_b->offset)
686 else if (elt_a->offset < elt_b->offset)
693 lookup_elt_with_offset (GSequence *seq,
695 GSequenceIter **ret_siter)
697 GSequenceIter *siter;
700 dummy.offset = offset;
701 siter = g_sequence_lookup (seq, &dummy, filter_elt_cmp, NULL);
706 return GET_ELT (siter);
710 increase_offset_iter (gpointer data,
713 FilterElt *elt = data;
714 gint offset = GPOINTER_TO_INT (user_data);
716 if (elt->offset >= offset)
721 decrease_offset_iter (gpointer data,
724 FilterElt *elt = data;
725 gint offset = GPOINTER_TO_INT (user_data);
727 if (elt->offset > offset)
732 gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter,
733 FilterLevel *parent_level,
734 FilterElt *parent_elt,
735 gboolean emit_inserted)
738 GtkTreeIter first_node;
740 FilterLevel *new_level;
741 FilterLevel *tmp_level;
746 gboolean empty = TRUE;
748 g_assert (filter->priv->child_model != NULL);
750 /* Avoid building a level that already exists */
752 g_assert (parent_elt->children == NULL);
754 g_assert (filter->priv->root == NULL);
756 if (filter->priv->in_row_deleted)
761 if (filter->priv->virtual_root)
763 if (gtk_tree_model_get_iter (filter->priv->child_model, &root, filter->priv->virtual_root) == FALSE)
765 length = gtk_tree_model_iter_n_children (filter->priv->child_model, &root);
767 if (gtk_tree_model_iter_children (filter->priv->child_model, &iter, &root) == FALSE)
772 if (!gtk_tree_model_get_iter_first (filter->priv->child_model, &iter))
774 length = gtk_tree_model_iter_n_children (filter->priv->child_model, NULL);
779 GtkTreeIter parent_iter;
780 GtkTreeIter child_parent_iter;
782 parent_iter.stamp = filter->priv->stamp;
783 parent_iter.user_data = parent_level;
784 parent_iter.user_data2 = parent_elt;
786 gtk_tree_model_filter_convert_iter_to_child_iter (filter,
789 if (gtk_tree_model_iter_children (filter->priv->child_model, &iter, &child_parent_iter) == FALSE)
792 /* stamp may have changed */
793 gtk_tree_model_filter_convert_iter_to_child_iter (filter,
796 length = gtk_tree_model_iter_n_children (filter->priv->child_model, &child_parent_iter);
798 /* Take a reference on the parent */
799 gtk_tree_model_filter_real_ref_node (GTK_TREE_MODEL (filter),
800 &parent_iter, FALSE);
803 g_return_if_fail (length > 0);
805 new_level = g_new (FilterLevel, 1);
806 new_level->seq = g_sequence_new (filter_elt_free);
807 new_level->visible_seq = g_sequence_new (NULL);
808 new_level->ref_count = 0;
809 new_level->ext_ref_count = 0;
810 new_level->parent_elt = parent_elt;
811 new_level->parent_level = parent_level;
814 parent_elt->children = new_level;
816 filter->priv->root = new_level;
818 /* increase the count of zero ref_counts */
819 tmp_level = parent_level;
820 tmp_elt = parent_elt;
824 tmp_elt->zero_ref_count++;
826 tmp_elt = tmp_level->parent_elt;
827 tmp_level = tmp_level->parent_level;
829 if (new_level != filter->priv->root)
830 filter->priv->zero_ref_count++;
838 if (gtk_tree_model_filter_visible (filter, &iter))
840 FilterElt *filter_elt;
842 filter_elt = filter_elt_new ();
843 filter_elt->offset = i;
844 filter_elt->zero_ref_count = 0;
845 filter_elt->ref_count = 0;
846 filter_elt->ext_ref_count = 0;
847 filter_elt->children = NULL;
848 filter_elt->visible_siter = NULL;
850 if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
851 filter_elt->iter = iter;
853 g_sequence_append (new_level->seq, filter_elt);
854 filter_elt->visible_siter = g_sequence_append (new_level->visible_seq, filter_elt);
861 GtkTreeIter children;
863 f_iter.stamp = filter->priv->stamp;
864 f_iter.user_data = new_level;
865 f_iter.user_data2 = filter_elt;
867 f_path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter),
869 gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter),
871 gtk_tree_path_free (f_path);
873 if (gtk_tree_model_iter_children (filter->priv->child_model,
875 gtk_tree_model_filter_update_children (filter,
877 FILTER_ELT (f_iter.user_data2));
882 while (gtk_tree_model_iter_next (filter->priv->child_model, &iter));
884 /* The level does not contain any visible nodes. However, changes in
885 * this level might affect the parent node, which can either be visible
886 * or invisible. Therefore, this level can only be removed again,
887 * if the parent level has an external reference count of zero. That is,
888 * if this level changes state, no signals are required in the parent
892 (parent_level && parent_level->ext_ref_count == 0))
894 gtk_tree_model_filter_free_level (filter, new_level, FALSE, TRUE, FALSE);
898 /* If none of the nodes are visible, we will just pull in the
899 * first node of the level.
903 FilterElt *filter_elt;
905 filter_elt = filter_elt_new ();
906 filter_elt->offset = 0;
907 filter_elt->zero_ref_count = 0;
908 filter_elt->ref_count = 0;
909 filter_elt->ext_ref_count = 0;
910 filter_elt->children = NULL;
911 filter_elt->visible_siter = NULL;
913 if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
914 filter_elt->iter = first_node;
916 g_sequence_append (new_level->seq, filter_elt);
919 /* Keep a reference on the first node of this level. We need this
920 * to make sure that we get all signals for this level.
922 f_iter.stamp = filter->priv->stamp;
923 f_iter.user_data = new_level;
924 f_iter.user_data2 = g_sequence_get (g_sequence_get_begin_iter (new_level->seq));
926 gtk_tree_model_filter_real_ref_node (GTK_TREE_MODEL (filter), &f_iter,
931 gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter,
932 FilterLevel *filter_level,
934 gboolean unref_parent,
935 gboolean unref_external)
937 GSequenceIter *siter;
938 GSequenceIter *end_siter;
940 g_assert (filter_level);
942 end_siter = g_sequence_get_end_iter (filter_level->seq);
943 for (siter = g_sequence_get_begin_iter (filter_level->seq);
945 siter = g_sequence_iter_next (siter))
947 FilterElt *elt = g_sequence_get (siter);
951 /* If we recurse and unref_self == FALSE, then unref_parent
952 * must also be FALSE (otherwise a still unref a node in this
955 gtk_tree_model_filter_free_level (filter,
956 FILTER_LEVEL (elt->children),
958 unref_self == FALSE ? FALSE : unref_parent,
966 f_iter.stamp = filter->priv->stamp;
967 f_iter.user_data = filter_level;
968 f_iter.user_data2 = elt;
970 while (elt->ext_ref_count > 0)
971 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
977 /* Release the reference on the first item.
983 f_iter.stamp = filter->priv->stamp;
984 f_iter.user_data = filter_level;
985 f_iter.user_data2 = g_sequence_get (g_sequence_get_begin_iter (filter_level->seq));
987 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
988 &f_iter, FALSE, TRUE);
991 if (filter_level->ext_ref_count == 0)
993 FilterLevel *parent_level = filter_level->parent_level;
994 FilterElt *parent_elt = filter_level->parent_elt;
998 parent_elt->zero_ref_count--;
1000 parent_elt = parent_level->parent_elt;
1001 parent_level = parent_level->parent_level;
1004 if (filter_level != filter->priv->root)
1005 filter->priv->zero_ref_count--;
1008 #ifdef MODEL_FILTER_DEBUG
1009 if (filter_level == filter->priv->root)
1010 g_assert (filter->priv->zero_ref_count == 0);
1013 if (filter_level->parent_elt)
1015 /* Release reference on parent */
1016 GtkTreeIter parent_iter;
1018 parent_iter.stamp = filter->priv->stamp;
1019 parent_iter.user_data = filter_level->parent_level;
1020 parent_iter.user_data2 = filter_level->parent_elt;
1022 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1023 &parent_iter, FALSE, unref_parent);
1025 filter_level->parent_elt->children = NULL;
1028 filter->priv->root = NULL;
1030 g_sequence_free (filter_level->seq);
1031 g_sequence_free (filter_level->visible_seq);
1032 g_free (filter_level);
1035 /* prune_level() is like free_level(), however instead of being fully
1036 * freed, the level is pruned to a level with only the first node used
1037 * for monitoring. For now it is only being called from
1038 * gtk_tree_model_filter_remove_elt_from_level(), which is the reason
1039 * this function is lacking a "gboolean unref" argument.
1042 gtk_tree_model_filter_prune_level (GtkTreeModelFilter *filter,
1045 GSequenceIter *siter;
1046 GSequenceIter *end_siter;
1050 /* This function is called when the parent of level became invisible.
1051 * All external ref counts of the children need to be dropped.
1052 * All children except the first one can be removed.
1055 /* Any child levels can be freed */
1056 end_siter = g_sequence_get_end_iter (level->seq);
1057 for (siter = g_sequence_get_begin_iter (level->seq);
1059 siter = g_sequence_iter_next (siter))
1061 FilterElt *elt = g_sequence_get (siter);
1064 gtk_tree_model_filter_free_level (filter,
1065 FILTER_LEVEL (elt->children),
1069 /* For the first item, only drop the external references */
1070 elt = g_sequence_get (g_sequence_get_begin_iter (level->seq));
1072 f_iter.stamp = filter->priv->stamp;
1073 f_iter.user_data = level;
1074 f_iter.user_data2 = elt;
1076 while (elt->ext_ref_count > 0)
1077 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1078 &f_iter, TRUE, TRUE);
1080 if (elt->visible_siter)
1082 g_sequence_remove (elt->visible_siter);
1083 elt->visible_siter = NULL;
1086 /* Remove the other elts */
1087 end_siter = g_sequence_get_end_iter (level->seq);
1088 siter = g_sequence_get_begin_iter (level->seq);
1089 siter = g_sequence_iter_next (siter);
1090 for (; siter != end_siter; siter = g_sequence_iter_next (siter))
1092 elt = g_sequence_get (siter);
1094 f_iter.stamp = filter->priv->stamp;
1095 f_iter.user_data = level;
1096 f_iter.user_data2 = elt;
1098 while (elt->ext_ref_count > 0)
1099 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1100 &f_iter, TRUE, TRUE);
1101 /* In this case, we do remove reference counts we've added ourselves,
1102 * since the node will be removed from the data structures.
1104 while (elt->ref_count > 0)
1105 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1106 &f_iter, FALSE, TRUE);
1108 if (elt->visible_siter)
1110 g_sequence_remove (elt->visible_siter);
1111 elt->visible_siter = NULL;
1115 /* Remove [begin + 1, end] */
1116 siter = g_sequence_get_begin_iter (level->seq);
1117 siter = g_sequence_iter_next (siter);
1119 g_sequence_remove_range (siter, end_siter);
1121 /* The level must have reached an ext ref count of zero by now, though
1122 * we only assert on this in debugging mode.
1124 #ifdef MODEL_FILTER_DEBUG
1125 g_assert (level->ext_ref_count == 0);
1130 gtk_tree_model_filter_level_transfer_first_ref (GtkTreeModelFilter *filter,
1132 GSequenceIter *from_iter,
1133 GSequenceIter *to_iter)
1137 f_iter.stamp = filter->priv->stamp;
1138 f_iter.user_data = level;
1139 f_iter.user_data2 = g_sequence_get (to_iter);
1141 gtk_tree_model_filter_real_ref_node (GTK_TREE_MODEL (filter),
1144 f_iter.stamp = filter->priv->stamp;
1145 f_iter.user_data = level;
1146 f_iter.user_data2 = g_sequence_get (from_iter);
1148 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1149 &f_iter, FALSE, TRUE);
1153 gtk_tree_model_filter_level_transfer_first_ref_with_index (GtkTreeModelFilter *filter,
1158 gtk_tree_model_filter_level_transfer_first_ref (filter, level,
1159 g_sequence_get_iter_at_pos (level->seq, from_index),
1160 g_sequence_get_iter_at_pos (level->seq, to_index));
1163 /* Creates paths suitable for accessing the child model. */
1164 static GtkTreePath *
1165 gtk_tree_model_filter_elt_get_path (FilterLevel *level,
1169 FilterLevel *walker = level;
1170 FilterElt *walker2 = elt;
1172 GtkTreePath *real_path;
1174 g_return_val_if_fail (level != NULL, NULL);
1175 g_return_val_if_fail (elt != NULL, NULL);
1177 path = gtk_tree_path_new ();
1181 gtk_tree_path_prepend_index (path, walker2->offset);
1183 walker2 = walker->parent_elt;
1184 walker = walker->parent_level;
1189 real_path = gtk_tree_model_filter_add_root (path, root);
1190 gtk_tree_path_free (path);
1197 static GtkTreePath *
1198 gtk_tree_model_filter_add_root (GtkTreePath *src,
1201 GtkTreePath *retval;
1204 retval = gtk_tree_path_copy (root);
1206 for (i = 0; i < gtk_tree_path_get_depth (src); i++)
1207 gtk_tree_path_append_index (retval, gtk_tree_path_get_indices (src)[i]);
1212 static GtkTreePath *
1213 gtk_tree_model_filter_remove_root (GtkTreePath *src,
1216 GtkTreePath *retval;
1221 if (gtk_tree_path_get_depth (src) <= gtk_tree_path_get_depth (root))
1224 depth = gtk_tree_path_get_depth (src);
1225 indices = gtk_tree_path_get_indices (src);
1227 for (i = 0; i < gtk_tree_path_get_depth (root); i++)
1228 if (indices[i] != gtk_tree_path_get_indices (root)[i])
1231 retval = gtk_tree_path_new ();
1233 for (; i < depth; i++)
1234 gtk_tree_path_append_index (retval, indices[i]);
1240 gtk_tree_model_filter_increment_stamp (GtkTreeModelFilter *filter)
1244 filter->priv->stamp++;
1246 while (filter->priv->stamp == 0);
1248 gtk_tree_model_filter_clear_cache (filter);
1252 gtk_tree_model_filter_real_visible (GtkTreeModelFilter *filter,
1253 GtkTreeModel *child_model,
1254 GtkTreeIter *child_iter)
1256 if (filter->priv->visible_func)
1258 return filter->priv->visible_func (child_model,
1260 filter->priv->visible_data)
1263 else if (filter->priv->visible_column >= 0)
1265 GValue val = G_VALUE_INIT;
1267 gtk_tree_model_get_value (child_model, child_iter,
1268 filter->priv->visible_column, &val);
1270 if (g_value_get_boolean (&val))
1272 g_value_unset (&val);
1276 g_value_unset (&val);
1280 /* no visible function set, so always visible */
1285 gtk_tree_model_filter_visible (GtkTreeModelFilter *self,
1286 GtkTreeIter *child_iter)
1288 return GTK_TREE_MODEL_FILTER_GET_CLASS (self)->visible (self,
1289 self->priv->child_model, child_iter);
1293 gtk_tree_model_filter_clear_cache_helper_iter (gpointer data,
1296 GtkTreeModelFilter *filter = user_data;
1297 FilterElt *elt = data;
1299 #ifdef MODEL_FILTER_DEBUG
1300 g_assert (elt->zero_ref_count >= 0);
1303 if (elt->zero_ref_count > 0)
1304 gtk_tree_model_filter_clear_cache_helper (filter, elt->children);
1308 gtk_tree_model_filter_clear_cache_helper (GtkTreeModelFilter *filter,
1313 g_sequence_foreach (level->seq, gtk_tree_model_filter_clear_cache_helper_iter, filter);
1315 /* If the level's ext_ref_count is zero, it means the level is not visible
1316 * and can be removed. But, since we support monitoring a child level
1317 * of a parent for changes (these might affect the parent), we will only
1318 * free the level if the parent level also has an external ref
1319 * count of zero. In that case, changes concerning our parent are
1322 * The root level is always visible, so an exception holds for levels
1323 * with the root level as parent level: these have to remain cached.
1325 if (level->ext_ref_count == 0 && level != filter->priv->root &&
1326 level->parent_level && level->parent_level != filter->priv->root &&
1327 level->parent_level->ext_ref_count == 0)
1329 gtk_tree_model_filter_free_level (filter, level, TRUE, TRUE, FALSE);
1335 gtk_tree_model_filter_elt_is_visible_in_target (FilterLevel *level,
1338 if (!elt->visible_siter)
1341 if (!level->parent_elt)
1346 elt = level->parent_elt;
1347 level = level->parent_level;
1349 if (elt && !elt->visible_siter)
1357 /* If a change has occurred in path (inserted, changed or deleted),
1358 * then this function is used to check all its ancestors. An ancestor
1359 * could have changed state as a result and this needs to be propagated
1360 * to the objects monitoring the filter model.
1363 gtk_tree_model_filter_check_ancestors (GtkTreeModelFilter *filter,
1367 int *indices = gtk_tree_path_get_indices (path);
1370 GtkTreeIter c_iter, tmp_iter;
1372 level = FILTER_LEVEL (filter->priv->root);
1377 if (filter->priv->virtual_root)
1378 gtk_tree_model_get_iter (filter->priv->child_model, &c_iter,
1379 filter->priv->virtual_root);
1382 gtk_tree_model_iter_nth_child (filter->priv->child_model, &c_iter,
1383 filter->priv->virtual_root ? &tmp_iter : NULL,
1386 while (i < gtk_tree_path_get_depth (path) - 1)
1388 gboolean requested_state;
1390 elt = lookup_elt_with_offset (level->seq,
1391 gtk_tree_path_get_indices (path)[i], NULL);
1393 requested_state = gtk_tree_model_filter_visible (filter, &c_iter);
1398 GtkTreePath *c_path;
1400 if (requested_state == FALSE)
1403 /* The elt does not exist in this level (so it is not
1404 * visible), but should now be visible. We emit the
1405 * row-inserted and row-has-child-toggled signals.
1407 elt = gtk_tree_model_filter_insert_elt_in_level (filter,
1413 /* insert_elt_in_level defaults to FALSE */
1414 elt->visible_siter = g_sequence_insert_sorted (level->visible_seq,
1416 filter_elt_cmp, NULL);
1418 c_path = gtk_tree_model_get_path (filter->priv->child_model,
1421 gtk_tree_model_filter_emit_row_inserted_for_path (filter,
1422 filter->priv->child_model,
1426 gtk_tree_path_free (c_path);
1428 /* We can immediately return, because this node was not visible
1429 * before and its children will be checked for in response to
1430 * the emitted row-has-child-toggled signal.
1434 else if (elt->visible_siter)
1436 if (!requested_state)
1438 /* A node has turned invisible. Remove it from the level
1439 * and emit row-deleted. Since this node is being
1440 * deleted. it makes no sense to look further up the
1443 gtk_tree_model_filter_remove_elt_from_level (filter,
1448 /* Otherwise continue up the chain */
1450 else if (!elt->visible_siter)
1452 if (requested_state)
1454 /* A node is already in the cache, but invisible. This
1455 * is usually a node on which a reference is kept by
1456 * the filter model, or a node fetched on the filter's
1457 * request, and thus not shown. Therefore, we will
1458 * not emit row-inserted for this node. Instead,
1459 * we signal to its parent that a change has occurred.
1461 * Exception: root level, in this case, we must emit
1464 if (level->parent_level)
1467 GtkTreePath *f_path;
1469 elt->visible_siter = g_sequence_insert_sorted (level->visible_seq, elt,
1470 filter_elt_cmp, NULL);
1472 f_iter.stamp = filter->priv->stamp;
1473 f_iter.user_data = level->parent_level;
1474 f_iter.user_data2 = level->parent_elt;
1476 f_path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter),
1478 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
1480 gtk_tree_path_free (f_path);
1484 GtkTreePath *c_path;
1486 elt->visible_siter = g_sequence_insert_sorted (level->visible_seq, elt,
1487 filter_elt_cmp, NULL);
1489 c_path = gtk_tree_model_get_path (filter->priv->child_model,
1492 gtk_tree_model_filter_emit_row_inserted_for_path (filter,
1493 filter->priv->child_model,
1497 gtk_tree_path_free (c_path);
1500 /* We can immediately return, because this node was not visible
1501 * before and the parent will check its children, including
1502 * this node, in response to the emitted row-has-child-toggled
1508 /* Not visible, so no need to continue. */
1514 /* If an elt does not have children, these are not visible.
1515 * Therefore, any signals emitted for these children will
1516 * be ignored, so we do not have to emit them.
1521 level = elt->children;
1525 gtk_tree_model_iter_nth_child (filter->priv->child_model, &c_iter,
1526 &tmp_iter, indices[i]);
1531 gtk_tree_model_filter_insert_elt_in_level (GtkTreeModelFilter *filter,
1532 GtkTreeIter *c_iter,
1538 GSequenceIter *siter;
1540 elt = filter_elt_new ();
1542 if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
1543 elt->iter = *c_iter;
1545 elt->offset = offset;
1546 elt->zero_ref_count = 0;
1548 elt->ext_ref_count = 0;
1549 elt->children = NULL;
1551 /* Because we don't emit row_inserted, the node is invisible and thus
1552 * not inserted in visible_seq
1554 elt->visible_siter = NULL;
1556 siter = g_sequence_insert_sorted (level->seq, elt, filter_elt_cmp, NULL);
1557 *index = g_sequence_iter_get_position (siter);
1559 /* If the insert location is zero, we need to move our reference
1560 * on the old first node to the new first node.
1563 gtk_tree_model_filter_level_transfer_first_ref_with_index (filter, level,
1570 gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter,
1576 GtkTreePath *c_path = NULL;
1578 GtkTreePath *c_parent_path = NULL;
1579 GtkTreeIter c_parent_iter;
1581 /* check if child exists and is visible */
1582 if (level->parent_elt)
1585 gtk_tree_model_filter_elt_get_path (level->parent_level,
1587 filter->priv->virtual_root);
1593 if (filter->priv->virtual_root)
1594 c_parent_path = gtk_tree_path_copy (filter->priv->virtual_root);
1596 c_parent_path = NULL;
1601 gtk_tree_model_get_iter (filter->priv->child_model,
1604 len = gtk_tree_model_iter_n_children (filter->priv->child_model,
1607 c_path = gtk_tree_path_copy (c_parent_path);
1608 gtk_tree_path_free (c_parent_path);
1612 len = gtk_tree_model_iter_n_children (filter->priv->child_model, NULL);
1613 c_path = gtk_tree_path_new ();
1616 gtk_tree_path_append_index (c_path, offset);
1617 gtk_tree_model_get_iter (filter->priv->child_model, &c_iter, c_path);
1618 gtk_tree_path_free (c_path);
1620 if (offset >= len || !gtk_tree_model_filter_visible (filter, &c_iter))
1623 return gtk_tree_model_filter_insert_elt_in_level (filter, &c_iter,
1628 /* Note that this function is never called from the row-deleted handler.
1629 * This means that this function is only used for removing elements
1630 * which are still present in the child model. As a result, we must
1631 * take care to properly release the references the filter model has
1632 * on the child model nodes.
1635 gtk_tree_model_filter_remove_elt_from_level (GtkTreeModelFilter *filter,
1640 FilterLevel *parent_level;
1641 gint length, orig_level_ext_ref_count;
1643 GtkTreePath *path = NULL;
1645 gboolean emit_child_toggled = FALSE;
1647 /* We need to know about the level's ext ref count before removal
1650 orig_level_ext_ref_count = level->ext_ref_count;
1652 iter.stamp = filter->priv->stamp;
1653 iter.user_data = level;
1654 iter.user_data2 = elt;
1656 parent = level->parent_elt;
1657 parent_level = level->parent_level;
1659 if (!parent || orig_level_ext_ref_count > 0)
1660 path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
1662 /* If the level is not visible, the parent is potentially invisible
1663 * too. Either way, as no signal will be emitted, there is no use
1668 length = g_sequence_get_length (level->seq);
1670 /* first register the node to be invisible */
1671 g_sequence_remove (elt->visible_siter);
1672 elt->visible_siter = NULL;
1675 * If level != root level and the number of visible nodes is 0 (ie. this
1676 * is the last node to be removed from the level), emit
1677 * row-has-child-toggled.
1680 if (level != filter->priv->root
1681 && g_sequence_get_length (level->visible_seq) == 0
1683 && parent->visible_siter)
1684 emit_child_toggled = TRUE;
1687 * - length > 1: in this case, the node is removed from the level
1688 * and row-deleted is emitted.
1689 * - length == 1: in this case, we need to decide whether to keep
1690 * the level or to free it.
1694 GSequenceIter *siter;
1696 /* We emit row-deleted, and remove the node from the cache.
1697 * If it has any children, these will be removed here as well.
1700 /* FIXME: I am not 100% sure it is always save to fully free the
1701 * level here. Perhaps the state of the parent level, etc. has to
1702 * be checked to make the right decision, like is done below for
1703 * the case length == 1.
1706 gtk_tree_model_filter_free_level (filter, elt->children, TRUE, TRUE, TRUE);
1708 /* If the first node is being removed, transfer, the reference */
1709 if (elt == g_sequence_get (g_sequence_get_begin_iter (level->seq)))
1711 gtk_tree_model_filter_level_transfer_first_ref_with_index (filter, level,
1715 while (elt->ext_ref_count > 0)
1716 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1718 /* In this case, we do remove reference counts we've added ourselves,
1719 * since the node will be removed from the data structures.
1721 while (elt->ref_count > 0)
1722 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1723 &iter, FALSE, TRUE);
1725 /* remove the node */
1726 lookup_elt_with_offset (level->seq, elt->offset, &siter);
1727 g_sequence_remove (siter);
1729 gtk_tree_model_filter_increment_stamp (filter);
1731 /* Only if the node is in the root level (parent == NULL) or
1732 * the level is visible, a row-deleted signal is necessary.
1734 if (!parent || orig_level_ext_ref_count > 0)
1735 gtk_tree_model_row_deleted (GTK_TREE_MODEL (filter), path);
1739 /* There is only one node left in this level */
1740 #ifdef MODEL_FILTER_DEBUG
1741 g_assert (length == 1);
1744 /* The row is signalled as deleted to the client. We have to
1745 * drop the remaining external reference count here, the client
1748 * We keep the reference counts we've obtained ourselves.
1750 while (elt->ext_ref_count > 0)
1751 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1754 /* This level is still required if:
1755 * - it is the root level
1756 * - its parent level is the root level
1757 * - its parent level has an external ref count > 0
1759 if (! (level == filter->priv->root ||
1760 level->parent_level == filter->priv->root ||
1761 level->parent_level->ext_ref_count > 0))
1763 /* Otherwise, the level can be removed */
1764 gtk_tree_model_filter_free_level (filter, level, TRUE, TRUE, TRUE);
1768 /* Level is kept, but we turn our attention to a child level.
1770 * If level is not the root level, it is a child level with
1771 * an ext ref count that is now 0. That means that any child level
1772 * of elt can be removed.
1774 if (level != filter->priv->root)
1776 #ifdef MODEL_FILTER_DEBUG
1777 g_assert (level->ext_ref_count == 0);
1780 gtk_tree_model_filter_free_level (filter, elt->children,
1785 /* In this case, we want to keep the level with the first
1786 * node pulled in to monitor for signals.
1789 gtk_tree_model_filter_prune_level (filter, elt->children);
1793 if (!parent || orig_level_ext_ref_count > 0)
1794 gtk_tree_model_row_deleted (GTK_TREE_MODEL (filter), path);
1797 gtk_tree_path_free (path);
1799 if (emit_child_toggled && parent->ext_ref_count > 0)
1804 piter.stamp = filter->priv->stamp;
1805 piter.user_data = parent_level;
1806 piter.user_data2 = parent;
1808 ppath = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &piter);
1810 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
1812 gtk_tree_path_free (ppath);
1816 /* This function is called after the given node has become visible.
1817 * When the node has children, we should build the level and
1818 * take a reference on the first child.
1821 gtk_tree_model_filter_update_children (GtkTreeModelFilter *filter,
1828 if (!elt->visible_siter)
1831 iter.stamp = filter->priv->stamp;
1832 iter.user_data = level;
1833 iter.user_data2 = elt;
1835 gtk_tree_model_filter_convert_iter_to_child_iter (filter, &c_iter, &iter);
1837 if ((!level->parent_level || level->parent_level->ext_ref_count > 0) &&
1838 gtk_tree_model_iter_has_child (filter->priv->child_model, &c_iter))
1841 gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
1843 if (elt->ext_ref_count > 0 && elt->children &&
1844 g_sequence_get_length (elt->children->seq))
1847 path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
1848 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
1852 gtk_tree_path_free (path);
1857 /* Path is relative to the child model (this is on search on elt offset)
1858 * but with the virtual root already removed if necesssary.
1861 find_elt_with_offset (GtkTreeModelFilter *filter,
1863 FilterLevel **level_,
1868 FilterLevel *parent_level = NULL;
1869 FilterElt *elt = NULL;
1871 level = FILTER_LEVEL (filter->priv->root);
1873 while (i < gtk_tree_path_get_depth (path))
1878 elt = lookup_elt_with_offset (level->seq,
1879 gtk_tree_path_get_indices (path)[i],
1885 parent_level = level;
1886 level = elt->children;
1891 *level_ = parent_level;
1899 /* TreeModel signals */
1901 gtk_tree_model_filter_emit_row_inserted_for_path (GtkTreeModelFilter *filter,
1902 GtkTreeModel *c_model,
1903 GtkTreePath *c_path,
1904 GtkTreeIter *c_iter)
1909 GtkTreeIter iter, children;
1910 gboolean signals_emitted = FALSE;
1912 if (!filter->priv->root)
1914 /* The root level has not been exposed to the view yet, so we
1915 * need to emit signals for any node that is being inserted.
1917 gtk_tree_model_filter_build_level (filter, NULL, NULL, TRUE);
1919 /* Check if the root level was built. Then child levels
1920 * that matter have also been built (due to update_children,
1921 * which triggers iter_n_children).
1923 if (filter->priv->root &&
1924 g_sequence_get_length (FILTER_LEVEL (filter->priv->root)->visible_seq) > 0)
1925 signals_emitted = TRUE;
1928 gtk_tree_model_filter_increment_stamp (filter);
1930 /* We need to disallow to build new levels, because we are then pulling
1931 * in a child in an invisible level. We only want to find path if it
1932 * is in a visible level (and thus has a parent that is visible).
1934 path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
1940 /* parent is probably being filtered out */
1943 gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter), &iter, path);
1945 level = FILTER_LEVEL (iter.user_data);
1946 elt = FILTER_ELT (iter.user_data2);
1948 /* Make sure elt is visible. elt can already be visible in case
1949 * it was pulled in above, so avoid inserted it into visible_seq twice.
1951 if (!elt->visible_siter)
1953 elt->visible_siter = g_sequence_insert_sorted (level->visible_seq,
1954 elt, filter_elt_cmp,
1958 /* Check whether the node and all of its parents are visible */
1959 if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt))
1961 /* visibility changed -- reget path */
1962 gtk_tree_path_free (path);
1963 path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
1965 if (!signals_emitted &&
1966 (!level->parent_level || level->ext_ref_count > 0))
1967 gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter);
1969 if (level->parent_level && level->parent_elt->ext_ref_count > 0 &&
1970 g_sequence_get_length (level->visible_seq) == 1)
1972 /* We know that this is the first visible node in this level, so
1973 * we need to emit row-has-child-toggled on the parent. This
1974 * does not apply to the root level.
1977 gtk_tree_path_up (path);
1978 gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path);
1980 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
1985 if (!signals_emitted
1986 && gtk_tree_model_iter_children (c_model, &children, c_iter))
1987 gtk_tree_model_filter_update_children (filter, level, elt);
1990 gtk_tree_path_free (path);
1994 gtk_tree_model_filter_row_changed (GtkTreeModel *c_model,
1995 GtkTreePath *c_path,
1996 GtkTreeIter *c_iter,
1999 GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2001 GtkTreeIter children;
2002 GtkTreeIter real_c_iter;
2003 GtkTreePath *path = NULL;
2004 GtkTreePath *real_path = NULL;
2009 gboolean requested_state;
2010 gboolean current_state;
2011 gboolean free_c_path = FALSE;
2013 g_return_if_fail (c_path != NULL || c_iter != NULL);
2017 c_path = gtk_tree_model_get_path (c_model, c_iter);
2021 if (filter->priv->virtual_root)
2022 real_path = gtk_tree_model_filter_remove_root (c_path,
2023 filter->priv->virtual_root);
2025 real_path = gtk_tree_path_copy (c_path);
2028 real_c_iter = *c_iter;
2030 gtk_tree_model_get_iter (c_model, &real_c_iter, c_path);
2032 /* is this node above the virtual root? */
2033 if (filter->priv->virtual_root &&
2034 (gtk_tree_path_get_depth (filter->priv->virtual_root)
2035 >= gtk_tree_path_get_depth (c_path)))
2038 /* what's the requested state? */
2039 requested_state = gtk_tree_model_filter_visible (filter, &real_c_iter);
2041 /* now, let's see whether the item is there */
2042 path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
2049 gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter),
2051 current_state = FILTER_ELT (iter.user_data2)->visible_siter != NULL;
2054 current_state = FALSE;
2056 if (current_state == FALSE && requested_state == FALSE)
2057 /* no changes required */
2060 if (current_state == TRUE && requested_state == FALSE)
2062 gtk_tree_model_filter_remove_elt_from_level (filter,
2063 FILTER_LEVEL (iter.user_data),
2064 FILTER_ELT (iter.user_data2));
2067 gtk_tree_model_filter_check_ancestors (filter, real_path);
2072 if (current_state == TRUE && requested_state == TRUE)
2074 level = FILTER_LEVEL (iter.user_data);
2075 elt = FILTER_ELT (iter.user_data2);
2077 if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt))
2079 /* propagate the signal; also get a path taking only visible
2080 * nodes into account.
2082 gtk_tree_path_free (path);
2083 path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
2085 if (level->ext_ref_count > 0)
2086 gtk_tree_model_row_changed (GTK_TREE_MODEL (filter), path, &iter);
2088 /* and update the children */
2089 if (gtk_tree_model_iter_children (c_model, &children, &real_c_iter))
2090 gtk_tree_model_filter_update_children (filter, level, elt);
2094 gtk_tree_model_filter_check_ancestors (filter, real_path);
2099 /* only current == FALSE and requested == TRUE is left,
2102 g_return_if_fail (current_state == FALSE && requested_state == TRUE);
2105 gtk_tree_model_filter_check_ancestors (filter, real_path);
2107 gtk_tree_model_filter_emit_row_inserted_for_path (filter, c_model,
2112 gtk_tree_path_free (path);
2115 gtk_tree_path_free (real_path);
2118 gtk_tree_path_free (c_path);
2122 gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
2123 GtkTreePath *c_path,
2124 GtkTreeIter *c_iter,
2127 GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2128 GtkTreePath *real_path = NULL;
2130 GtkTreeIter real_c_iter;
2132 FilterElt *elt = NULL;
2133 FilterLevel *level = NULL;
2134 FilterLevel *parent_level = NULL;
2135 GSequenceIter *siter;
2140 gboolean free_c_path = FALSE;
2141 gboolean emit_row_inserted = FALSE;
2143 g_return_if_fail (c_path != NULL || c_iter != NULL);
2147 c_path = gtk_tree_model_get_path (c_model, c_iter);
2152 real_c_iter = *c_iter;
2154 gtk_tree_model_get_iter (c_model, &real_c_iter, c_path);
2156 /* the row has already been inserted. so we need to fixup the
2157 * virtual root here first
2159 if (filter->priv->virtual_root)
2161 if (gtk_tree_path_get_depth (filter->priv->virtual_root) >=
2162 gtk_tree_path_get_depth (c_path))
2165 gint *v_indices, *c_indices;
2166 gboolean common_prefix = TRUE;
2168 level = gtk_tree_path_get_depth (c_path) - 1;
2169 v_indices = gtk_tree_path_get_indices (filter->priv->virtual_root);
2170 c_indices = gtk_tree_path_get_indices (c_path);
2172 for (i = 0; i < level; i++)
2173 if (v_indices[i] != c_indices[i])
2175 common_prefix = FALSE;
2179 if (common_prefix && v_indices[level] >= c_indices[level])
2180 (v_indices[level])++;
2184 /* subtract virtual root if necessary */
2185 if (filter->priv->virtual_root)
2187 real_path = gtk_tree_model_filter_remove_root (c_path,
2188 filter->priv->virtual_root);
2194 real_path = gtk_tree_path_copy (c_path);
2196 if (!filter->priv->root)
2198 /* The root level has not been exposed to the view yet, so we
2199 * need to emit signals for any node that is being inserted.
2201 gtk_tree_model_filter_build_level (filter, NULL, NULL, TRUE);
2203 /* Check if the root level was built. Then child levels
2204 * that matter have also been built (due to update_children,
2205 * which triggers iter_n_children).
2207 if (filter->priv->root)
2209 emit_row_inserted = FALSE;
2214 if (gtk_tree_path_get_depth (real_path) - 1 >= 1)
2216 gboolean found = FALSE;
2217 GtkTreePath *parent = gtk_tree_path_copy (real_path);
2218 gtk_tree_path_up (parent);
2220 found = find_elt_with_offset (filter, parent, &parent_level, &elt);
2222 gtk_tree_path_free (parent);
2225 /* Parent is not in the cache and probably being filtered out */
2228 level = elt->children;
2231 level = FILTER_LEVEL (filter->priv->root);
2235 if (elt && elt->visible_siter)
2237 /* The level in which the new node should be inserted does not
2238 * exist, but the parent, elt, does. If elt is visible, emit
2239 * row-has-child-toggled.
2241 GtkTreePath *tmppath;
2242 GtkTreeIter tmpiter;
2244 tmpiter.stamp = filter->priv->stamp;
2245 tmpiter.user_data = parent_level;
2246 tmpiter.user_data2 = elt;
2248 tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (filter),
2253 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
2255 gtk_tree_path_free (tmppath);
2261 /* let's try to insert the value */
2262 offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1];
2264 /* update the offsets, yes if we didn't insert the node above, there will
2265 * be a gap here. This will be filled with the node (via fetch_child) when
2266 * it becomes visible
2268 dummy.offset = offset;
2269 siter = g_sequence_search (level->seq, &dummy, filter_elt_cmp, NULL);
2270 siter = g_sequence_iter_prev (siter);
2271 g_sequence_foreach_range (siter, g_sequence_get_end_iter (level->seq),
2272 increase_offset_iter, GINT_TO_POINTER (offset));
2274 /* only insert when visible */
2275 if (gtk_tree_model_filter_visible (filter, &real_c_iter))
2279 felt = gtk_tree_model_filter_insert_elt_in_level (filter,
2284 /* insert_elt_in_level defaults to FALSE */
2285 felt->visible_siter = g_sequence_insert_sorted (level->visible_seq,
2287 filter_elt_cmp, NULL);
2288 emit_row_inserted = TRUE;
2293 gtk_tree_model_filter_check_ancestors (filter, real_path);
2295 if (emit_row_inserted)
2296 gtk_tree_model_filter_emit_row_inserted_for_path (filter, c_model,
2300 gtk_tree_path_free (real_path);
2303 gtk_tree_path_free (c_path);
2307 gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *c_model,
2308 GtkTreePath *c_path,
2309 GtkTreeIter *c_iter,
2312 GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2317 gboolean requested_state;
2319 g_return_if_fail (c_path != NULL && c_iter != NULL);
2321 /* If we get row-has-child-toggled on the virtual root, and there is
2322 * no root level; try to build it now.
2324 if (filter->priv->virtual_root && !filter->priv->root
2325 && !gtk_tree_path_compare (c_path, filter->priv->virtual_root))
2327 gtk_tree_model_filter_build_level (filter, NULL, NULL, TRUE);
2331 /* For all other levels, there is a chance that the visibility state
2332 * of the parent has changed now.
2335 path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
2342 gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (data), &iter, path);
2344 level = FILTER_LEVEL (iter.user_data);
2345 elt = FILTER_ELT (iter.user_data2);
2347 gtk_tree_path_free (path);
2349 requested_state = gtk_tree_model_filter_visible (filter, c_iter);
2351 if (!elt->visible_siter && !requested_state)
2353 /* The parent node currently is not visible and will not become
2354 * visible, so we will not pass on the row-has-child-toggled event.
2358 else if (elt->visible_siter && !requested_state)
2360 /* The node is no longer visible, so it has to be removed.
2361 * _remove_elt_from_level() takes care of emitting row-has-child-toggled
2364 gtk_tree_model_filter_remove_elt_from_level (filter, level, elt);
2368 else if (!elt->visible_siter && requested_state)
2370 elt->visible_siter = g_sequence_insert_sorted (level->visible_seq,
2371 elt, filter_elt_cmp,
2374 /* Only insert if the parent is visible in the target */
2375 if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt))
2377 path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
2378 gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter);
2379 gtk_tree_path_free (path);
2381 /* We do not update children now, because that will happen
2386 /* For the remaining possibility, elt->visible && requested_state
2387 * no action is required.
2390 /* If this node is referenced and has children, build the level so we
2391 * can monitor it for changes.
2393 if (elt->ref_count > 1 && !elt->children &&
2394 gtk_tree_model_iter_has_child (c_model, c_iter))
2395 gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
2397 /* get a path taking only visible nodes into account */
2398 path = gtk_tree_model_get_path (GTK_TREE_MODEL (data), &iter);
2399 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
2400 gtk_tree_path_free (path);
2404 gtk_tree_model_filter_virtual_root_deleted (GtkTreeModelFilter *filter,
2405 GtkTreePath *c_path)
2409 FilterLevel *level = FILTER_LEVEL (filter->priv->root);
2411 /* The virtual root (or one of its ancestors) has been deleted. This
2412 * means that all content for our model is now gone. We deal with
2413 * this by removing everything in the filter model: we just iterate
2414 * over the root level and emit a row-deleted for each FilterElt.
2415 * (FIXME: Should we emit row-deleted for child nodes as well? This
2416 * has never been fully clear in TreeModel).
2419 /* We unref the path of the virtual root, up to and not including the
2420 * deleted node which can no longer be unreffed.
2422 gtk_tree_model_filter_unref_path (filter, filter->priv->virtual_root,
2423 gtk_tree_path_get_depth (c_path) - 1);
2424 filter->priv->virtual_root_deleted = TRUE;
2429 nodes = g_sequence_get_length (level->visible_seq);
2431 /* We should not propagate the unref here. An unref for any of these
2432 * nodes will fail, since the respective nodes in the child model are
2435 gtk_tree_model_filter_free_level (filter, filter->priv->root, FALSE, TRUE, FALSE);
2437 gtk_tree_model_filter_increment_stamp (filter);
2439 path = gtk_tree_path_new ();
2440 gtk_tree_path_append_index (path, 0);
2442 for (i = 0; i < nodes; i++)
2443 gtk_tree_model_row_deleted (GTK_TREE_MODEL (filter), path);
2445 gtk_tree_path_free (path);
2449 gtk_tree_model_filter_adjust_virtual_root (GtkTreeModelFilter *filter,
2450 GtkTreePath *c_path)
2454 gint *v_indices, *c_indices;
2455 gboolean common_prefix = TRUE;
2457 level = gtk_tree_path_get_depth (c_path) - 1;
2458 v_indices = gtk_tree_path_get_indices (filter->priv->virtual_root);
2459 c_indices = gtk_tree_path_get_indices (c_path);
2461 for (i = 0; i < level; i++)
2462 if (v_indices[i] != c_indices[i])
2464 common_prefix = FALSE;
2468 if (common_prefix && v_indices[level] > c_indices[level])
2469 (v_indices[level])--;
2473 gtk_tree_model_filter_row_deleted_invisible_node (GtkTreeModelFilter *filter,
2474 GtkTreePath *c_path)
2477 GtkTreePath *real_path;
2481 GSequenceIter *siter;
2483 /* The node deleted in the child model is not visible in the
2484 * filter model. We will not emit a signal, just fixup the offsets
2485 * of the other nodes.
2488 if (!filter->priv->root)
2491 level = FILTER_LEVEL (filter->priv->root);
2493 /* subtract vroot if necessary */
2494 if (filter->priv->virtual_root)
2496 real_path = gtk_tree_model_filter_remove_root (c_path,
2497 filter->priv->virtual_root);
2498 /* we don't handle this */
2503 real_path = gtk_tree_path_copy (c_path);
2505 if (gtk_tree_path_get_depth (real_path) - 1 >= 1)
2507 gboolean found = FALSE;
2508 GtkTreePath *parent = gtk_tree_path_copy (real_path);
2509 gtk_tree_path_up (parent);
2511 found = find_elt_with_offset (filter, parent, &level, &elt);
2513 gtk_tree_path_free (parent);
2517 /* parent is filtered out, so no level */
2518 gtk_tree_path_free (real_path);
2522 level = elt->children;
2525 offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1];
2526 gtk_tree_path_free (real_path);
2531 /* decrease offset of all nodes following the deleted node */
2532 dummy.offset = offset;
2533 siter = g_sequence_search (level->seq, &dummy, filter_elt_cmp, NULL);
2534 g_sequence_foreach_range (siter, g_sequence_get_end_iter (level->seq),
2535 decrease_offset_iter, GINT_TO_POINTER (offset));
2539 gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model,
2540 GtkTreePath *c_path,
2543 GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2546 FilterElt *elt, *parent_elt = NULL;
2547 FilterLevel *level, *parent_level = NULL;
2548 GSequenceIter *siter;
2549 gboolean emit_child_toggled = FALSE;
2550 gboolean emit_row_deleted = FALSE;
2552 gint orig_level_ext_ref_count;
2554 g_return_if_fail (c_path != NULL);
2556 /* special case the deletion of an ancestor of the virtual root */
2557 if (filter->priv->virtual_root &&
2558 (gtk_tree_path_is_ancestor (c_path, filter->priv->virtual_root) ||
2559 !gtk_tree_path_compare (c_path, filter->priv->virtual_root)))
2561 gtk_tree_model_filter_virtual_root_deleted (filter, c_path);
2565 /* adjust the virtual root for the deleted row */
2566 if (filter->priv->virtual_root &&
2567 gtk_tree_path_get_depth (filter->priv->virtual_root) >=
2568 gtk_tree_path_get_depth (c_path))
2569 gtk_tree_model_filter_adjust_virtual_root (filter, c_path);
2571 path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
2578 gtk_tree_model_filter_row_deleted_invisible_node (filter, c_path);
2582 /* a node was deleted, which was in our cache */
2583 gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (data), &iter, path);
2585 level = FILTER_LEVEL (iter.user_data);
2586 elt = FILTER_ELT (iter.user_data2);
2587 offset = elt->offset;
2588 orig_level_ext_ref_count = level->ext_ref_count;
2590 if (elt->visible_siter)
2592 /* get a path taking only visible nodes into account */
2593 gtk_tree_path_free (path);
2594 path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
2596 if (g_sequence_get_length (level->visible_seq) == 1)
2598 emit_child_toggled = TRUE;
2599 parent_level = level->parent_level;
2600 parent_elt = level->parent_elt;
2603 emit_row_deleted = TRUE;
2606 /* Release the references on this node, without propagation because
2607 * the node does not exist anymore in the child model. The filter
2608 * model's references on the node in case of level->parent or use
2609 * of a virtual root are automatically destroyed by the child model.
2611 while (elt->ext_ref_count > 0)
2612 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
2616 /* If this last node has children, then the recursion in free_level
2617 * will release this reference.
2619 while (elt->ref_count > 1)
2620 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
2623 while (elt->ref_count > 0)
2624 gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
2628 if (g_sequence_get_length (level->seq) == 1)
2631 gtk_tree_model_filter_free_level (filter, level, FALSE, TRUE, FALSE);
2638 lookup_elt_with_offset (level->seq, elt->offset, &siter);
2639 is_first = g_sequence_get_begin_iter (level->seq) == siter;
2642 gtk_tree_model_filter_free_level (filter, elt->children,
2643 FALSE, FALSE, FALSE);
2645 /* remove the row */
2646 if (elt->visible_siter)
2647 g_sequence_remove (elt->visible_siter);
2648 tmp = g_sequence_iter_next (siter);
2649 g_sequence_remove (siter);
2650 g_sequence_foreach_range (tmp, g_sequence_get_end_iter (level->seq),
2651 decrease_offset_iter, GINT_TO_POINTER (offset));
2653 /* Take a reference on the new first node. The first node previously
2654 * keeping this reference has been removed above.
2660 f_iter.stamp = filter->priv->stamp;
2661 f_iter.user_data = level;
2662 f_iter.user_data2 = g_sequence_get (g_sequence_get_begin_iter (level->seq));
2664 gtk_tree_model_filter_real_ref_node (GTK_TREE_MODEL (filter),
2669 if (emit_row_deleted)
2671 /* emit row_deleted */
2672 gtk_tree_model_filter_increment_stamp (filter);
2674 if (!parent_elt || orig_level_ext_ref_count > 0)
2675 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
2678 if (emit_child_toggled && parent_level)
2683 iter2.stamp = filter->priv->stamp;
2684 iter2.user_data = parent_level;
2685 iter2.user_data2 = parent_elt;
2687 /* We set in_row_deleted to TRUE to avoid a level build triggered
2688 * by row-has-child-toggled (parent model could call iter_has_child
2691 filter->priv->in_row_deleted = TRUE;
2692 path2 = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter2);
2693 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
2695 gtk_tree_path_free (path2);
2696 filter->priv->in_row_deleted = FALSE;
2699 if (filter->priv->virtual_root)
2701 GtkTreePath *real_path;
2703 real_path = gtk_tree_model_filter_remove_root (c_path,
2704 filter->priv->root);
2707 gtk_tree_model_filter_check_ancestors (filter, real_path);
2708 gtk_tree_path_free (real_path);
2712 gtk_tree_model_filter_check_ancestors (filter, c_path);
2714 gtk_tree_path_free (path);
2718 gtk_tree_model_filter_rows_reordered (GtkTreeModel *c_model,
2719 GtkTreePath *c_path,
2720 GtkTreeIter *c_iter,
2726 GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2732 GSequenceIter *tmp_end_iter;
2733 GSequenceIter *old_first_siter = NULL;
2738 g_return_if_fail (new_order != NULL);
2740 if (c_path == NULL || gtk_tree_path_get_depth (c_path) == 0)
2742 length = gtk_tree_model_iter_n_children (c_model, NULL);
2744 if (filter->priv->virtual_root)
2748 /* reorder root level of path */
2749 for (i = 0; i < length; i++)
2750 if (new_order[i] == gtk_tree_path_get_indices (filter->priv->virtual_root)[0])
2756 gtk_tree_path_get_indices (filter->priv->virtual_root)[0] = new_pos;
2760 path = gtk_tree_path_new ();
2761 level = FILTER_LEVEL (filter->priv->root);
2765 GtkTreeIter child_iter;
2767 /* virtual root anchor reordering */
2768 if (filter->priv->virtual_root &&
2769 gtk_tree_path_is_ancestor (c_path, filter->priv->virtual_root))
2774 GtkTreeIter real_c_iter;
2776 level = gtk_tree_path_get_depth (c_path);
2779 real_c_iter = *c_iter;
2781 gtk_tree_model_get_iter (c_model, &real_c_iter, c_path);
2783 length = gtk_tree_model_iter_n_children (c_model, &real_c_iter);
2785 for (i = 0; i < length; i++)
2786 if (new_order[i] == gtk_tree_path_get_indices (filter->priv->virtual_root)[level])
2792 gtk_tree_path_get_indices (filter->priv->virtual_root)[level] = new_pos;
2796 path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
2801 if (!path && filter->priv->virtual_root &&
2802 gtk_tree_path_compare (c_path, filter->priv->virtual_root))
2805 if (!path && !filter->priv->virtual_root)
2810 /* root level mode */
2812 gtk_tree_model_get_iter (c_model, c_iter, c_path);
2813 length = gtk_tree_model_iter_n_children (c_model, c_iter);
2814 path = gtk_tree_path_new ();
2815 level = FILTER_LEVEL (filter->priv->root);
2819 gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (data),
2822 elt = FILTER_ELT (iter.user_data2);
2826 gtk_tree_path_free (path);
2830 level = elt->children;
2832 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (filter), &child_iter, &iter);
2833 length = gtk_tree_model_iter_n_children (c_model, &child_iter);
2837 if (!level || g_sequence_get_length (level->seq) < 1)
2839 gtk_tree_path_free (path);
2843 /* NOTE: we do not bail out here if level->seq->len < 2 like
2844 * GtkTreeModelSort does. This because we do some special tricky
2848 tmp_seq = g_sequence_new (filter_elt_free);
2849 tmp_end_iter = g_sequence_get_end_iter (tmp_seq);
2850 tmp_array = g_new (gint, g_sequence_get_length (level->visible_seq));
2853 old_first_siter = g_sequence_get_iter_at_pos (level->seq, 0);
2855 for (i = 0; i < length; i++)
2858 GSequenceIter *siter;
2860 elt = lookup_elt_with_offset (level->seq, new_order[i], &siter);
2864 /* Only for visible items an entry should be present in the order array
2867 if (elt->visible_siter)
2868 tmp_array[elt_count++] = g_sequence_iter_get_position (elt->visible_siter);
2870 /* Steal elt from level->seq and append it to tmp_seq */
2871 g_sequence_move (siter, tmp_end_iter);
2875 g_warn_if_fail (g_sequence_get_length (level->seq) == 0);
2876 g_sequence_free (level->seq);
2877 level->seq = tmp_seq;
2878 g_sequence_sort (level->visible_seq, filter_elt_cmp, NULL);
2880 /* Transfer the reference from the old item at position 0 to the
2881 * new item at position 0, unless the old item at position 0 is also
2882 * at position 0 in the new sequence.
2884 if (g_sequence_iter_get_position (old_first_siter) != 0)
2885 gtk_tree_model_filter_level_transfer_first_ref (filter,
2888 g_sequence_get_iter_at_pos (level->seq, 0));
2890 /* emit rows_reordered */
2891 if (g_sequence_get_length (level->visible_seq) > 0)
2893 if (!gtk_tree_path_get_indices (path))
2894 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (data), path, NULL,
2898 /* get a path taking only visible nodes into account */
2899 gtk_tree_path_free (path);
2900 path = gtk_tree_model_get_path (GTK_TREE_MODEL (data), &iter);
2902 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (data), path, &iter,
2909 gtk_tree_path_free (path);
2912 /* TreeModelIface implementation */
2913 static GtkTreeModelFlags
2914 gtk_tree_model_filter_get_flags (GtkTreeModel *model)
2916 GtkTreeModelFlags flags;
2918 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), 0);
2919 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, 0);
2921 flags = gtk_tree_model_get_flags (GTK_TREE_MODEL_FILTER (model)->priv->child_model);
2923 if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
2924 return GTK_TREE_MODEL_LIST_ONLY;
2930 gtk_tree_model_filter_get_n_columns (GtkTreeModel *model)
2932 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
2934 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), 0);
2935 g_return_val_if_fail (filter->priv->child_model != NULL, 0);
2937 if (filter->priv->child_model == NULL)
2940 /* so we can't modify the modify func after this ... */
2941 filter->priv->modify_func_set = TRUE;
2943 if (filter->priv->modify_n_columns > 0)
2944 return filter->priv->modify_n_columns;
2946 return gtk_tree_model_get_n_columns (filter->priv->child_model);
2950 gtk_tree_model_filter_get_column_type (GtkTreeModel *model,
2953 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
2955 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), G_TYPE_INVALID);
2956 g_return_val_if_fail (filter->priv->child_model != NULL, G_TYPE_INVALID);
2958 /* so we can't modify the modify func after this ... */
2959 filter->priv->modify_func_set = TRUE;
2961 if (filter->priv->modify_types)
2963 g_return_val_if_fail (index < filter->priv->modify_n_columns, G_TYPE_INVALID);
2965 return filter->priv->modify_types[index];
2968 return gtk_tree_model_get_column_type (filter->priv->child_model, index);
2971 /* A special case of _get_iter; this function can also get iters which
2972 * are not visible. These iters should ONLY be passed internally, never
2973 * pass those along with a signal emission.
2976 gtk_tree_model_filter_get_iter_full (GtkTreeModel *model,
2980 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
2985 GSequenceIter *siter;
2987 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
2988 g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
2990 indices = gtk_tree_path_get_indices (path);
2992 if (filter->priv->root == NULL)
2993 gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
2994 level = FILTER_LEVEL (filter->priv->root);
2996 depth = gtk_tree_path_get_depth (path);
3003 for (i = 0; i < depth - 1; i++)
3005 if (!level || indices[i] >= g_sequence_get_length (level->seq))
3011 siter = g_sequence_get_iter_at_pos (level->seq, indices[i]);
3012 if (g_sequence_iter_is_end (siter))
3018 elt = GET_ELT (siter);
3021 gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
3022 level = elt->children;
3025 if (!level || indices[i] >= g_sequence_get_length (level->seq))
3031 iter->stamp = filter->priv->stamp;
3032 iter->user_data = level;
3034 siter = g_sequence_get_iter_at_pos (level->seq, indices[depth - 1]);
3035 if (g_sequence_iter_is_end (siter))
3040 iter->user_data2 = GET_ELT (siter);
3046 gtk_tree_model_filter_get_iter (GtkTreeModel *model,
3050 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3054 GSequenceIter *siter;
3057 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3058 g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
3060 indices = gtk_tree_path_get_indices (path);
3062 if (filter->priv->root == NULL)
3063 gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
3064 level = FILTER_LEVEL (filter->priv->root);
3066 depth = gtk_tree_path_get_depth (path);
3073 for (i = 0; i < depth - 1; i++)
3075 if (!level || indices[i] >= g_sequence_get_length (level->visible_seq))
3081 siter = g_sequence_get_iter_at_pos (level->visible_seq, indices[i]);
3082 if (g_sequence_iter_is_end (siter))
3088 elt = GET_ELT (siter);
3090 gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
3091 level = elt->children;
3094 if (!level || indices[i] >= g_sequence_get_length (level->visible_seq))
3100 iter->stamp = filter->priv->stamp;
3101 iter->user_data = level;
3103 siter = g_sequence_get_iter_at_pos (level->visible_seq, indices[depth - 1]);
3104 if (g_sequence_iter_is_end (siter))
3109 iter->user_data2 = GET_ELT (siter);
3114 static GtkTreePath *
3115 gtk_tree_model_filter_get_path (GtkTreeModel *model,
3118 GtkTreePath *retval;
3122 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), NULL);
3123 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, NULL);
3124 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp, NULL);
3126 level = iter->user_data;
3127 elt = iter->user_data2;
3129 if (!elt->visible_siter)
3132 retval = gtk_tree_path_new ();
3138 index = g_sequence_iter_get_position (elt->visible_siter);
3139 gtk_tree_path_prepend_index (retval, index);
3141 elt = level->parent_elt;
3142 level = level->parent_level;
3149 gtk_tree_model_filter_real_modify (GtkTreeModelFilter *self,
3150 GtkTreeModel *child_model,
3155 if (self->priv->modify_func)
3157 g_return_if_fail (column < self->priv->modify_n_columns);
3159 g_value_init (value, self->priv->modify_types[column]);
3160 self->priv->modify_func (GTK_TREE_MODEL (self),
3164 self->priv->modify_data);
3168 GtkTreeIter child_iter;
3170 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (self),
3172 gtk_tree_model_get_value (child_model, &child_iter, column, value);
3177 gtk_tree_model_filter_get_value (GtkTreeModel *model,
3182 GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (model);
3184 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (model));
3185 g_return_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL);
3186 g_return_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp);
3188 GTK_TREE_MODEL_FILTER_GET_CLASS (model)->modify (filter,
3189 filter->priv->child_model, iter, value, column);
3193 gtk_tree_model_filter_iter_next (GtkTreeModel *model,
3197 GSequenceIter *siter;
3199 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3200 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, FALSE);
3201 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp, FALSE);
3203 elt = iter->user_data2;
3205 siter = g_sequence_iter_next (elt->visible_siter);
3206 if (g_sequence_iter_is_end (siter))
3212 iter->user_data2 = GET_ELT (siter);
3218 gtk_tree_model_filter_iter_previous (GtkTreeModel *model,
3222 GSequenceIter *siter;
3224 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3225 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, FALSE);
3226 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp, FALSE);
3228 elt = iter->user_data2;
3230 if (g_sequence_iter_is_begin (elt->visible_siter))
3235 siter = g_sequence_iter_prev (elt->visible_siter);
3237 iter->user_data2 = GET_ELT (siter);
3243 gtk_tree_model_filter_iter_children (GtkTreeModel *model,
3245 GtkTreeIter *parent)
3247 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3249 GSequenceIter *siter;
3252 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3253 g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
3255 g_return_val_if_fail (filter->priv->stamp == parent->stamp, FALSE);
3259 if (!filter->priv->root)
3260 gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
3261 if (!filter->priv->root)
3264 level = filter->priv->root;
3265 siter = g_sequence_get_begin_iter (level->visible_seq);
3266 if (g_sequence_iter_is_end (siter))
3272 iter->stamp = filter->priv->stamp;
3273 iter->user_data = level;
3274 iter->user_data2 = GET_ELT (siter);
3280 if (FILTER_ELT (parent->user_data2)->children == NULL)
3281 gtk_tree_model_filter_build_level (filter,
3282 FILTER_LEVEL (parent->user_data),
3283 FILTER_ELT (parent->user_data2),
3285 if (FILTER_ELT (parent->user_data2)->children == NULL)
3288 level = FILTER_ELT (parent->user_data2)->children;
3289 siter = g_sequence_get_begin_iter (level->visible_seq);
3290 if (g_sequence_iter_is_end (siter))
3296 iter->stamp = filter->priv->stamp;
3297 iter->user_data = level;
3298 iter->user_data2 = GET_ELT (siter);
3308 gtk_tree_model_filter_iter_has_child (GtkTreeModel *model,
3311 GtkTreeIter child_iter;
3312 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3315 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3316 g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
3317 g_return_val_if_fail (filter->priv->stamp == iter->stamp, FALSE);
3319 filter = GTK_TREE_MODEL_FILTER (model);
3321 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, iter);
3322 elt = FILTER_ELT (iter->user_data2);
3324 if (!elt->visible_siter)
3327 /* we need to build the level to check if not all children are filtered
3331 && gtk_tree_model_iter_has_child (filter->priv->child_model, &child_iter))
3332 gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (iter->user_data),
3335 if (elt->children && g_sequence_get_length (elt->children->visible_seq) > 0)
3342 gtk_tree_model_filter_iter_n_children (GtkTreeModel *model,
3345 GtkTreeIter child_iter;
3346 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3349 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), 0);
3350 g_return_val_if_fail (filter->priv->child_model != NULL, 0);
3352 g_return_val_if_fail (filter->priv->stamp == iter->stamp, 0);
3356 if (!filter->priv->root)
3357 gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
3359 if (filter->priv->root)
3360 return g_sequence_get_length (FILTER_LEVEL (filter->priv->root)->visible_seq);
3365 elt = FILTER_ELT (iter->user_data2);
3367 if (!elt->visible_siter)
3370 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, iter);
3372 if (!elt->children &&
3373 gtk_tree_model_iter_has_child (filter->priv->child_model, &child_iter))
3374 gtk_tree_model_filter_build_level (filter,
3375 FILTER_LEVEL (iter->user_data),
3379 return g_sequence_get_length (elt->children->visible_seq);
3385 gtk_tree_model_filter_iter_nth_child (GtkTreeModel *model,
3387 GtkTreeIter *parent,
3391 GtkTreeIter children;
3392 GSequenceIter *siter;
3394 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3396 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == parent->stamp, FALSE);
3398 /* use this instead of has_child to force us to build the level, if needed */
3399 if (gtk_tree_model_filter_iter_children (model, &children, parent) == FALSE)
3405 level = children.user_data;
3406 siter = g_sequence_get_iter_at_pos (level->visible_seq, n);
3407 if (g_sequence_iter_is_end (siter))
3410 iter->stamp = GTK_TREE_MODEL_FILTER (model)->priv->stamp;
3411 iter->user_data = level;
3412 iter->user_data2 = GET_ELT (siter);
3418 gtk_tree_model_filter_iter_parent (GtkTreeModel *model,
3425 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3426 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, FALSE);
3427 g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == child->stamp, FALSE);
3429 level = child->user_data;
3431 if (level->parent_level)
3433 iter->stamp = GTK_TREE_MODEL_FILTER (model)->priv->stamp;
3434 iter->user_data = level->parent_level;
3435 iter->user_data2 = level->parent_elt;
3444 gtk_tree_model_filter_ref_node (GtkTreeModel *model,
3447 gtk_tree_model_filter_real_ref_node (model, iter, TRUE);
3451 gtk_tree_model_filter_real_ref_node (GtkTreeModel *model,
3455 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3456 GtkTreeIter child_iter;
3460 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (model));
3461 g_return_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL);
3462 g_return_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp);
3464 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, iter);
3466 gtk_tree_model_ref_node (filter->priv->child_model, &child_iter);
3468 level = iter->user_data;
3469 elt = iter->user_data2;
3476 elt->ext_ref_count++;
3477 level->ext_ref_count++;
3479 if (level->ext_ref_count == 1)
3481 FilterLevel *parent_level = level->parent_level;
3482 FilterElt *parent_elt = level->parent_elt;
3484 /* we were at zero -- time to decrease the zero_ref_count val */
3485 while (parent_level)
3487 parent_elt->zero_ref_count--;
3489 parent_elt = parent_level->parent_elt;
3490 parent_level = parent_level->parent_level;
3493 if (filter->priv->root != level)
3494 filter->priv->zero_ref_count--;
3496 #ifdef MODEL_FILTER_DEBUG
3497 g_assert (filter->priv->zero_ref_count >= 0);
3498 if (filter->priv->zero_ref_count > 0)
3499 g_assert (filter->priv->root != NULL);
3504 #ifdef MODEL_FILTER_DEBUG
3505 g_assert (elt->ref_count >= elt->ext_ref_count);
3506 g_assert (elt->ref_count >= 0);
3507 g_assert (elt->ext_ref_count >= 0);
3512 gtk_tree_model_filter_unref_node (GtkTreeModel *model,
3515 gtk_tree_model_filter_real_unref_node (model, iter, TRUE, TRUE);
3519 gtk_tree_model_filter_real_unref_node (GtkTreeModel *model,
3522 gboolean propagate_unref)
3524 GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3528 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (model));
3529 g_return_if_fail (filter->priv->child_model != NULL);
3530 g_return_if_fail (filter->priv->stamp == iter->stamp);
3532 if (propagate_unref)
3534 GtkTreeIter child_iter;
3535 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, iter);
3536 gtk_tree_model_unref_node (filter->priv->child_model, &child_iter);
3539 level = iter->user_data;
3540 elt = iter->user_data2;
3542 g_return_if_fail (elt->ref_count > 0);
3543 #ifdef MODEL_FILTER_DEBUG
3544 g_assert (elt->ref_count >= elt->ext_ref_count);
3545 g_assert (elt->ref_count >= 0);
3546 g_assert (elt->ext_ref_count >= 0);
3554 elt->ext_ref_count--;
3555 level->ext_ref_count--;
3557 if (level->ext_ref_count == 0)
3559 FilterLevel *parent_level = level->parent_level;
3560 FilterElt *parent_elt = level->parent_elt;
3562 /* we are at zero -- time to increase the zero_ref_count val */
3563 while (parent_level)
3565 parent_elt->zero_ref_count++;
3567 parent_elt = parent_level->parent_elt;
3568 parent_level = parent_level->parent_level;
3571 if (filter->priv->root != level)
3572 filter->priv->zero_ref_count++;
3574 #ifdef MODEL_FILTER_DEBUG
3575 g_assert (filter->priv->zero_ref_count >= 0);
3576 if (filter->priv->zero_ref_count > 0)
3577 g_assert (filter->priv->root != NULL);
3582 #ifdef MODEL_FILTER_DEBUG
3583 g_assert (elt->ref_count >= elt->ext_ref_count);
3584 g_assert (elt->ref_count >= 0);
3585 g_assert (elt->ext_ref_count >= 0);
3589 /* TreeDragSource interface implementation */
3591 gtk_tree_model_filter_row_draggable (GtkTreeDragSource *drag_source,
3594 GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *)drag_source;
3595 GtkTreePath *child_path;
3598 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (drag_source), FALSE);
3599 g_return_val_if_fail (path != NULL, FALSE);
3601 child_path = gtk_tree_model_filter_convert_path_to_child_path (tree_model_filter, path);
3602 draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_filter->priv->child_model), child_path);
3603 gtk_tree_path_free (child_path);
3609 gtk_tree_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
3611 GtkSelectionData *selection_data)
3613 GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *)drag_source;
3614 GtkTreePath *child_path;
3617 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (drag_source), FALSE);
3618 g_return_val_if_fail (path != NULL, FALSE);
3620 child_path = gtk_tree_model_filter_convert_path_to_child_path (tree_model_filter, path);
3621 gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_filter->priv->child_model), child_path, selection_data);
3622 gtk_tree_path_free (child_path);
3628 gtk_tree_model_filter_drag_data_delete (GtkTreeDragSource *drag_source,
3631 GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *)drag_source;
3632 GtkTreePath *child_path;
3635 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (drag_source), FALSE);
3636 g_return_val_if_fail (path != NULL, FALSE);
3638 child_path = gtk_tree_model_filter_convert_path_to_child_path (tree_model_filter, path);
3639 deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_filter->priv->child_model), child_path);
3640 gtk_tree_path_free (child_path);
3645 /* bits and pieces */
3647 gtk_tree_model_filter_set_model (GtkTreeModelFilter *filter,
3648 GtkTreeModel *child_model)
3650 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3652 if (filter->priv->child_model)
3654 g_signal_handler_disconnect (filter->priv->child_model,
3655 filter->priv->changed_id);
3656 g_signal_handler_disconnect (filter->priv->child_model,
3657 filter->priv->inserted_id);
3658 g_signal_handler_disconnect (filter->priv->child_model,
3659 filter->priv->has_child_toggled_id);
3660 g_signal_handler_disconnect (filter->priv->child_model,
3661 filter->priv->deleted_id);
3662 g_signal_handler_disconnect (filter->priv->child_model,
3663 filter->priv->reordered_id);
3665 /* reset our state */
3666 if (filter->priv->root)
3667 gtk_tree_model_filter_free_level (filter, filter->priv->root,
3670 filter->priv->root = NULL;
3671 g_object_unref (filter->priv->child_model);
3672 filter->priv->visible_column = -1;
3674 /* FIXME: do we need to destroy more here? */
3677 filter->priv->child_model = child_model;
3681 g_object_ref (filter->priv->child_model);
3682 filter->priv->changed_id =
3683 g_signal_connect (child_model, "row-changed",
3684 G_CALLBACK (gtk_tree_model_filter_row_changed),
3686 filter->priv->inserted_id =
3687 g_signal_connect (child_model, "row-inserted",
3688 G_CALLBACK (gtk_tree_model_filter_row_inserted),
3690 filter->priv->has_child_toggled_id =
3691 g_signal_connect (child_model, "row-has-child-toggled",
3692 G_CALLBACK (gtk_tree_model_filter_row_has_child_toggled),
3694 filter->priv->deleted_id =
3695 g_signal_connect (child_model, "row-deleted",
3696 G_CALLBACK (gtk_tree_model_filter_row_deleted),
3698 filter->priv->reordered_id =
3699 g_signal_connect (child_model, "rows-reordered",
3700 G_CALLBACK (gtk_tree_model_filter_rows_reordered),
3703 filter->priv->child_flags = gtk_tree_model_get_flags (child_model);
3704 filter->priv->stamp = g_random_int ();
3709 gtk_tree_model_filter_ref_path (GtkTreeModelFilter *filter,
3715 len = gtk_tree_path_get_depth (path);
3716 p = gtk_tree_path_copy (path);
3721 gtk_tree_model_get_iter (GTK_TREE_MODEL (filter->priv->child_model), &iter, p);
3722 gtk_tree_model_ref_node (GTK_TREE_MODEL (filter->priv->child_model), &iter);
3723 gtk_tree_path_up (p);
3726 gtk_tree_path_free (p);
3730 gtk_tree_model_filter_unref_path (GtkTreeModelFilter *filter,
3740 len = gtk_tree_path_get_depth (path);
3742 p = gtk_tree_path_copy (path);
3747 gtk_tree_model_get_iter (GTK_TREE_MODEL (filter->priv->child_model), &iter, p);
3748 gtk_tree_model_unref_node (GTK_TREE_MODEL (filter->priv->child_model), &iter);
3749 gtk_tree_path_up (p);
3752 gtk_tree_path_free (p);
3756 gtk_tree_model_filter_set_root (GtkTreeModelFilter *filter,
3759 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3763 filter->priv->virtual_root = gtk_tree_path_copy (root);
3764 gtk_tree_model_filter_ref_path (filter, filter->priv->virtual_root);
3765 filter->priv->virtual_root_deleted = FALSE;
3768 filter->priv->virtual_root = NULL;
3774 * gtk_tree_model_filter_new:
3775 * @child_model: A #GtkTreeModel.
3776 * @root: (allow-none): A #GtkTreePath or %NULL.
3778 * Creates a new #GtkTreeModel, with @child_model as the child_model
3779 * and @root as the virtual root.
3781 * Return value: (transfer full): A new #GtkTreeModel.
3786 gtk_tree_model_filter_new (GtkTreeModel *child_model,
3789 g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
3791 return g_object_new (GTK_TYPE_TREE_MODEL_FILTER,
3792 "child-model", child_model,
3793 "virtual-root", root,
3798 * gtk_tree_model_filter_get_model:
3799 * @filter: A #GtkTreeModelFilter.
3801 * Returns a pointer to the child model of @filter.
3803 * Return value: (transfer none): A pointer to a #GtkTreeModel.
3808 gtk_tree_model_filter_get_model (GtkTreeModelFilter *filter)
3810 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), NULL);
3812 return filter->priv->child_model;
3816 * gtk_tree_model_filter_set_visible_func:
3817 * @filter: A #GtkTreeModelFilter.
3818 * @func: A #GtkTreeModelFilterVisibleFunc, the visible function.
3819 * @data: (allow-none): User data to pass to the visible function, or %NULL.
3820 * @destroy: (allow-none): Destroy notifier of @data, or %NULL.
3822 * Sets the visible function used when filtering the @filter to be @func. The
3823 * function should return %TRUE if the given row should be visible and
3826 * If the condition calculated by the function changes over time (e.g. because
3827 * it depends on some global parameters), you must call
3828 * gtk_tree_model_filter_refilter() to keep the visibility information of
3829 * the model uptodate.
3831 * Note that @func is called whenever a row is inserted, when it may still be
3832 * empty. The visible function should therefore take special care of empty
3833 * rows, like in the example below.
3835 * <informalexample><programlisting>
3837 * visible_func (GtkTreeModel *model,
3838 * GtkTreeIter *iter,
3841 * /* Visible if row is non-empty and first column is "HI" */
3843 * gboolean visible = FALSE;
3845 * gtk_tree_model_get (model, iter, 0, &str, -1);
3846 * if (str && strcmp (str, "HI") == 0)
3852 * </programlisting></informalexample>
3857 gtk_tree_model_filter_set_visible_func (GtkTreeModelFilter *filter,
3858 GtkTreeModelFilterVisibleFunc func,
3860 GDestroyNotify destroy)
3862 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3863 g_return_if_fail (func != NULL);
3864 g_return_if_fail (filter->priv->visible_method_set == FALSE);
3866 filter->priv->visible_func = func;
3867 filter->priv->visible_data = data;
3868 filter->priv->visible_destroy = destroy;
3870 filter->priv->visible_method_set = TRUE;
3874 * gtk_tree_model_filter_set_modify_func:
3875 * @filter: A #GtkTreeModelFilter.
3876 * @n_columns: The number of columns in the filter model.
3877 * @types: (array length=n_columns): The #GType<!-- -->s of the columns.
3878 * @func: A #GtkTreeModelFilterModifyFunc
3879 * @data: (allow-none): User data to pass to the modify function, or %NULL.
3880 * @destroy: (allow-none): Destroy notifier of @data, or %NULL.
3882 * With the @n_columns and @types parameters, you give an array of column
3883 * types for this model (which will be exposed to the parent model/view).
3884 * The @func, @data and @destroy parameters are for specifying the modify
3885 * function. The modify function will get called for <emphasis>each</emphasis>
3886 * data access, the goal of the modify function is to return the data which
3887 * should be displayed at the location specified using the parameters of the
3893 gtk_tree_model_filter_set_modify_func (GtkTreeModelFilter *filter,
3896 GtkTreeModelFilterModifyFunc func,
3898 GDestroyNotify destroy)
3900 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3901 g_return_if_fail (func != NULL);
3902 g_return_if_fail (filter->priv->modify_func_set == FALSE);
3904 if (filter->priv->modify_destroy)
3906 GDestroyNotify d = filter->priv->modify_destroy;
3908 filter->priv->modify_destroy = NULL;
3909 d (filter->priv->modify_data);
3912 filter->priv->modify_n_columns = n_columns;
3913 filter->priv->modify_types = g_new0 (GType, n_columns);
3914 memcpy (filter->priv->modify_types, types, sizeof (GType) * n_columns);
3915 filter->priv->modify_func = func;
3916 filter->priv->modify_data = data;
3917 filter->priv->modify_destroy = destroy;
3919 filter->priv->modify_func_set = TRUE;
3923 * gtk_tree_model_filter_set_visible_column:
3924 * @filter: A #GtkTreeModelFilter.
3925 * @column: A #gint which is the column containing the visible information.
3927 * Sets @column of the child_model to be the column where @filter should
3928 * look for visibility information. @columns should be a column of type
3929 * %G_TYPE_BOOLEAN, where %TRUE means that a row is visible, and %FALSE
3935 gtk_tree_model_filter_set_visible_column (GtkTreeModelFilter *filter,
3938 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3939 g_return_if_fail (column >= 0);
3940 g_return_if_fail (filter->priv->visible_method_set == FALSE);
3942 filter->priv->visible_column = column;
3944 filter->priv->visible_method_set = TRUE;
3950 * gtk_tree_model_filter_convert_child_iter_to_iter:
3951 * @filter: A #GtkTreeModelFilter.
3952 * @filter_iter: (out): An uninitialized #GtkTreeIter.
3953 * @child_iter: A valid #GtkTreeIter pointing to a row on the child model.
3955 * Sets @filter_iter to point to the row in @filter that corresponds to the
3956 * row pointed at by @child_iter. If @filter_iter was not set, %FALSE is
3959 * Return value: %TRUE, if @filter_iter was set, i.e. if @child_iter is a
3960 * valid iterator pointing to a visible row in child model.
3965 gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *filter,
3966 GtkTreeIter *filter_iter,
3967 GtkTreeIter *child_iter)
3970 GtkTreePath *child_path, *path;
3972 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), FALSE);
3973 g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
3974 g_return_val_if_fail (filter_iter != NULL, FALSE);
3975 g_return_val_if_fail (child_iter != NULL, FALSE);
3976 g_return_val_if_fail (filter_iter != child_iter, FALSE);
3978 filter_iter->stamp = 0;
3980 child_path = gtk_tree_model_get_path (filter->priv->child_model, child_iter);
3981 g_return_val_if_fail (child_path != NULL, FALSE);
3983 path = gtk_tree_model_filter_convert_child_path_to_path (filter,
3985 gtk_tree_path_free (child_path);
3990 ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), filter_iter, path);
3991 gtk_tree_path_free (path);
3997 * gtk_tree_model_filter_convert_iter_to_child_iter:
3998 * @filter: A #GtkTreeModelFilter.
3999 * @child_iter: (out): An uninitialized #GtkTreeIter.
4000 * @filter_iter: A valid #GtkTreeIter pointing to a row on @filter.
4002 * Sets @child_iter to point to the row pointed to by @filter_iter.
4007 gtk_tree_model_filter_convert_iter_to_child_iter (GtkTreeModelFilter *filter,
4008 GtkTreeIter *child_iter,
4009 GtkTreeIter *filter_iter)
4011 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
4012 g_return_if_fail (filter->priv->child_model != NULL);
4013 g_return_if_fail (child_iter != NULL);
4014 g_return_if_fail (filter_iter != NULL);
4015 g_return_if_fail (filter_iter->stamp == filter->priv->stamp);
4016 g_return_if_fail (filter_iter != child_iter);
4018 if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
4020 *child_iter = FILTER_ELT (filter_iter->user_data2)->iter;
4025 gboolean valid = FALSE;
4027 path = gtk_tree_model_filter_elt_get_path (filter_iter->user_data,
4028 filter_iter->user_data2,
4029 filter->priv->virtual_root);
4030 valid = gtk_tree_model_get_iter (filter->priv->child_model, child_iter,
4032 gtk_tree_path_free (path);
4034 g_return_if_fail (valid == TRUE);
4038 /* The path returned can only be used internally in the filter model. */
4039 static GtkTreePath *
4040 gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filter,
4041 GtkTreePath *child_path,
4042 gboolean build_levels,
4043 gboolean fetch_children)
4045 gint *child_indices;
4046 GtkTreePath *retval;
4047 GtkTreePath *real_path;
4052 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), NULL);
4053 g_return_val_if_fail (filter->priv->child_model != NULL, NULL);
4054 g_return_val_if_fail (child_path != NULL, NULL);
4056 if (!filter->priv->virtual_root)
4057 real_path = gtk_tree_path_copy (child_path);
4059 real_path = gtk_tree_model_filter_remove_root (child_path,
4060 filter->priv->virtual_root);
4065 retval = gtk_tree_path_new ();
4066 child_indices = gtk_tree_path_get_indices (real_path);
4068 if (filter->priv->root == NULL && build_levels)
4069 gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
4070 level = FILTER_LEVEL (filter->priv->root);
4072 for (i = 0; i < gtk_tree_path_get_depth (real_path); i++)
4074 GSequenceIter *siter;
4075 gboolean found_child = FALSE;
4079 gtk_tree_path_free (real_path);
4080 gtk_tree_path_free (retval);
4084 tmp = lookup_elt_with_offset (level->seq, child_indices[i], &siter);
4087 gtk_tree_path_append_index (retval, g_sequence_iter_get_position (siter));
4088 if (!tmp->children && build_levels)
4089 gtk_tree_model_filter_build_level (filter, level, tmp, FALSE);
4090 level = tmp->children;
4094 if (!found_child && fetch_children)
4098 tmp = gtk_tree_model_filter_fetch_child (filter, level,
4102 /* didn't find the child, let's try to bring it back */
4103 if (!tmp || tmp->offset != child_indices[i])
4106 gtk_tree_path_free (real_path);
4107 gtk_tree_path_free (retval);
4111 gtk_tree_path_append_index (retval, j);
4112 if (!tmp->children && build_levels)
4113 gtk_tree_model_filter_build_level (filter, level, tmp, FALSE);
4114 level = tmp->children;
4117 else if (!found_child && !fetch_children)
4120 gtk_tree_path_free (real_path);
4121 gtk_tree_path_free (retval);
4126 gtk_tree_path_free (real_path);
4131 * gtk_tree_model_filter_convert_child_path_to_path:
4132 * @filter: A #GtkTreeModelFilter.
4133 * @child_path: A #GtkTreePath to convert.
4135 * Converts @child_path to a path relative to @filter. That is, @child_path
4136 * points to a path in the child model. The rerturned path will point to the
4137 * same row in the filtered model. If @child_path isn't a valid path on the
4138 * child model or points to a row which is not visible in @filter, then %NULL
4141 * Return value: A newly allocated #GtkTreePath, or %NULL.
4146 gtk_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filter,
4147 GtkTreePath *child_path)
4152 /* this function does the sanity checks */
4153 path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
4161 /* get a new path which only takes visible nodes into account.
4162 * -- if this gives any performance issues, we can write a special
4163 * version of convert_child_path_to_path immediately returning
4164 * a visible-nodes-only path.
4166 gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter), &iter, path);
4168 gtk_tree_path_free (path);
4169 path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
4175 * gtk_tree_model_filter_convert_path_to_child_path:
4176 * @filter: A #GtkTreeModelFilter.
4177 * @filter_path: A #GtkTreePath to convert.
4179 * Converts @filter_path to a path on the child model of @filter. That is,
4180 * @filter_path points to a location in @filter. The returned path will
4181 * point to the same location in the model not being filtered. If @filter_path
4182 * does not point to a location in the child model, %NULL is returned.
4184 * Return value: A newly allocated #GtkTreePath, or %NULL.
4189 gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *filter,
4190 GtkTreePath *filter_path)
4192 gint *filter_indices;
4193 GtkTreePath *retval;
4197 g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), NULL);
4198 g_return_val_if_fail (filter->priv->child_model != NULL, NULL);
4199 g_return_val_if_fail (filter_path != NULL, NULL);
4202 retval = gtk_tree_path_new ();
4203 filter_indices = gtk_tree_path_get_indices (filter_path);
4204 if (!filter->priv->root)
4205 gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
4206 level = FILTER_LEVEL (filter->priv->root);
4208 for (i = 0; i < gtk_tree_path_get_depth (filter_path); i++)
4211 GSequenceIter *siter;
4215 gtk_tree_path_free (retval);
4219 siter = g_sequence_get_iter_at_pos (level->visible_seq, filter_indices[i]);
4220 if (g_sequence_iter_is_end (siter))
4222 gtk_tree_path_free (retval);
4226 elt = GET_ELT (siter);
4227 if (elt->children == NULL)
4228 gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
4230 gtk_tree_path_append_index (retval, elt->offset);
4231 level = elt->children;
4236 if (filter->priv->virtual_root)
4238 GtkTreePath *real_retval;
4240 real_retval = gtk_tree_model_filter_add_root (retval,
4241 filter->priv->virtual_root);
4242 gtk_tree_path_free (retval);
4251 gtk_tree_model_filter_refilter_helper (GtkTreeModel *model,
4256 /* evil, don't try this at home, but certainly speeds things up */
4257 gtk_tree_model_filter_row_changed (model, path, iter, data);
4263 * gtk_tree_model_filter_refilter:
4264 * @filter: A #GtkTreeModelFilter.
4266 * Emits ::row_changed for each row in the child model, which causes
4267 * the filter to re-evaluate whether a row is visible or not.
4272 gtk_tree_model_filter_refilter (GtkTreeModelFilter *filter)
4274 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
4277 gtk_tree_model_foreach (filter->priv->child_model,
4278 gtk_tree_model_filter_refilter_helper,
4283 * gtk_tree_model_filter_clear_cache:
4284 * @filter: A #GtkTreeModelFilter.
4286 * This function should almost never be called. It clears the @filter
4287 * of any cached iterators that haven't been reffed with
4288 * gtk_tree_model_ref_node(). This might be useful if the child model
4289 * being filtered is static (and doesn't change often) and there has been
4290 * a lot of unreffed access to nodes. As a side effect of this function,
4291 * all unreffed iters will be invalid.
4296 gtk_tree_model_filter_clear_cache (GtkTreeModelFilter *filter)
4298 g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
4300 if (filter->priv->zero_ref_count > 0)
4301 gtk_tree_model_filter_clear_cache_helper (filter,
4302 FILTER_LEVEL (filter->priv->root));