]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodelfilter.c
gtktreemodelfilter: child levels of the root level must remain cached
[~andy/gtk] / gtk / gtktreemodelfilter.c
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>
4  *
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.
9  *
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.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22 #include "gtktreemodelfilter.h"
23 #include "gtkintl.h"
24 #include "gtktreednd.h"
25 #include "gtkprivate.h"
26 #include <string.h>
27
28
29 /**
30  * SECTION:gtktreemodelfilter
31  * @Short_description: A GtkTreeModel which hides parts of an underlying tree model
32  * @Title: GtkTreeModelFilter
33  * @See_also:#GtkTreeModelSort
34  *
35  * A #GtkTreeModelFilter is a tree model which wraps another tree model,
36  * and can do the following things:
37  * <itemizedlist>
38  * <listitem><para>
39  * Filter specific rows, based on data from a "visible column", a column
40  * storing booleans indicating whether the row should be filtered or not,
41  * or based on the return value of a "visible function", which gets a
42  * model, iter and user_data and returns a boolean indicating whether the
43  * row should be filtered or not.
44  * </para></listitem>
45  * <listitem><para>
46  * Modify the "appearance" of the model, using a modify function.
47  * This is extremely powerful and allows for just changing
48  * some values and also for creating a completely different model based on
49  * the given child model.
50  * </para></listitem>
51  * <listitem><para>
52  * Set a different root node, also known as a "virtual root". You can pass in
53  * a #GtkTreePath indicating the root node for the filter at construction time.
54  * </para></listitem>
55  * </itemizedlist>
56  *
57  * The basic API is similar to #GtkTreeModelSort. For an example on its usage,
58  * see the section on #GtkTreeModelSort.
59  *
60  * When using #GtkTreeModelFilter, it is important to realize that
61  * #GtkTreeModelFilter maintains an internal cache of all nodes which are
62  * visible in its clients. The cache is likely to be a subtree of the tree
63  * exposed by the child model. #GtkTreeModelFilter will not cache the entire
64  * child model when unnecessary to not compromise the caching mechanism
65  * that is exposed by the reference counting scheme. If the child model
66  * implements reference counting, unnecessary signals may not be emitted
67  * because of reference counting rule 3, see the #GtkTreeModel
68  * documentation. (Note that e.g. #GtkTreeStore does not implement
69  * reference counting and will always emit all signals, even when
70  * the receiving node is not visible).
71  *
72  * Because of this, limitations for possible visible functions do apply.
73  * In general, visible functions should only use data or properties from
74  * the node for which the visibility state must be determined, its siblings
75  * or its parents. Usually, having a dependency on the state of any child
76  * node is not possible, unless references are taken on these explicitly.
77  * When no such reference exists, no signals may be received for these child
78  * nodes (see reference couting rule number 3 in the #GtkTreeModel section).
79  *
80  * Determining the visibility state of a given node based on the state
81  * of its child nodes is a frequently occurring use case. Therefore,
82  * #GtkTreeModelFilter explicitly supports this. For example, when a node
83  * does not have any children, you might not want the node to be visible.
84  * As soon as the first row is added to the node's child level (or the
85  * last row removed), the node's visibility should be updated.
86  *
87  * This introduces a dependency from the node on its child nodes. In order
88  * to accommodate this, #GtkTreeModelFilter must make sure the necesary
89  * signals are received from the child model. This is achieved by building,
90  * for all nodes which are exposed as visible nodes to #GtkTreeModelFilter's
91  * clients, the child level (if any) and take a reference on the first node
92  * in this level. Furthermore, for every row-inserted, row-changed or
93  * row-deleted signal (also these which were not handled because the node
94  * was not cached), #GtkTreeModelFilter will check if the visibility state
95  * of any parent node has changed.
96  *
97  * Beware, however, that this explicit support is limited to these two
98  * cases. For example, if you want a node to be visible only if two nodes
99  * in a child's child level (2 levels deeper) are visible, you are on your
100  * own. In this case, either rely on #GtkTreeStore to emit all signals
101  * because it does not implement reference counting, or for models that
102  * do implement reference counting, obtain references on these child levels
103  * yourself.
104  */
105
106 /* Notes on this implementation of GtkTreeModelFilter
107  * ==================================================
108  *
109  * Warnings
110  * --------
111  *
112  * In this code there is a potential for confusion as to whether an iter,
113  * path or value refers to the GtkTreeModelFilter model, or to the child
114  * model that has been set. As a convention, variables referencing the
115  * child model will have a c_ prefix before them (ie. c_iter, c_value,
116  * c_path). In case the c_ prefixed names are already in use, an f_
117  * prefix is used. Conversion of iterators and paths between
118  * GtkTreeModelFilter and the child model is done through the various
119  * gtk_tree_model_filter_convert_* functions.
120  *
121  * Even though the GtkTreeModelSort and GtkTreeModelFilter have very
122  * similar data structures, many assumptions made in the GtkTreeModelSort
123  * code do *not* apply in the GtkTreeModelFilter case. Reference counting
124  * in particular is more complicated in GtkTreeModelFilter, because
125  * we explicitly support reliance on the state of a node's children as
126  * outlined in the public API documentation. Because of these differences,
127  * you are strongly recommended to first read through these notes before
128  * making any modification to the code.
129  *
130  * Iterator format
131  * ---------------
132  *
133  * The iterator format of iterators handed out by GtkTreeModelFilter is
134  * as follows:
135  *
136  *     iter->stamp = filter->priv->stamp
137  *     iter->user_data = FilterLevel
138  *     iter->user_data2 = FilterElt
139  *
140  * Internal data structure
141  * -----------------------
142  *
143  * Using FilterLevel and FilterElt, GtkTreeModelFilter maintains a "cache"
144  * of the mapping from GtkTreeModelFilter nodes to nodes in the child model.
145  * This is to avoid re-creating a level each time (which involves computing
146  * visibility for each node in that level) an operation is requested on
147  * GtkTreeModelFilter, such as get iter, get path and get value.
148  *
149  * A FilterElt corresponds to a single node. The FilterElt can either be
150  * visible or invisible in the model that is exposed to the clients of this
151  * GtkTreeModelFilter. The visibility state is stored in the "visible_siter"
152  * field, which is NULL when the node is not visible. The FilterLevel keeps
153  * a reference to the parent FilterElt and its FilterLevel (if any). The
154  * FilterElt can have a "children" pointer set, which points at a child
155  * level (a sub level).
156  *
157  * In a FilterLevel, two separate GSequences are maintained. One contains
158  * all nodes of this FilterLevel, regardless of the visibility state of
159  * the node. Another contains only visible nodes. A visible FilterElt
160  * is thus present in both the full and the visible GSequence. The
161  * GSequence allows for fast access, addition and removal of nodes.
162  *
163  * It is important to recognize the two different mappings that play
164  * a part in this code:
165  *   I.  The mapping from the client to this model. The order in which
166  *       nodes are stored in the *visible* GSequence is the order in
167  *       which the nodes are exposed to clients of the GtkTreeModelFilter.
168  *   II. The mapping from this model to its child model. Each FilterElt
169  *       contains an "offset" field which is the offset of the
170  *       corresponding node in the child model.
171  *
172  * Throughout the code, two kinds of paths relative to the GtkTreeModelFilter
173  * (those generated from the sequence positions) are used. There are paths
174  * which take non-visible nodes into account (generated from the full
175  * sequences) and paths which don't (generated from the visible sequences).
176  * Paths which have been generated from the full sequences should only be
177  * used internally and NEVER be passed along with a signal emisson.
178  *
179  * Reference counting
180  * ------------------
181  *
182  * GtkTreeModelFilter forwards all reference and unreference operations
183  * to the corresponding node in the child model. In addition,
184  * GtkTreeModelFilter will also add references of its own. The full reference
185  * count of each node (i.e. all forwarded references and these by the
186  * filter model) is maintained internally in the "ref_count" fields in
187  * FilterElt and FilterLevel. Because there is a need to determine whether
188  * a node should be visible for the client, the reference count of only
189  * the forwarded references is maintained as well, in the "ext_ref_count"
190  * fields.
191  *
192  * In a few cases, GtkTreeModelFilter takes additional references on
193  * nodes. The first case is that a reference is taken on the parent
194  * (if any) of each level. This happens in gtk_tree_model_filter_build_level()
195  * and the reference is released again in gtk_tree_model_filter_free_level().
196  * This ensures that for all references which are taken by the filter
197  * model, all parent nodes are referenced according to reference counting
198  * rule 1 in the GtkTreeModel documentation.
199  *
200  * A second case is required to support visible functions which depend on
201  * the state of a node's children (see the public API documentation for
202  * GtkTreeModelFilter above). We build the child level of each node that
203  * could be visible in the client (i.e. the level has an ext_ref_count > 0;
204  * not the elt, because the elt might be invisible and thus unreferenced
205  * by the client). For each node that becomes visible, due to insertion or
206  * changes in visibility state, it is checked whether node has children, if
207  * so the child level is built.
208  *
209  * A reference is taken on the first node of each level so that the child
210  * model will emit all signals for this level, due to reference counting
211  * rule 3 in the GtkTreeModel documentation. If due to changes in the level,
212  * another node becomes the first node (e.g. due to insertion or reordering),
213  * this reference is transferred from the old to the new first node.
214  *
215  * When a level has an *external* reference count of zero (which means that
216  * none of the nodes in the level is referenced by the clients), the level
217  * has a "zero ref count" on all its parents. As soon as the level reaches
218  * an *external* reference count of zero, the zero ref count value is
219  * incremented by one for all parents of this level. Due to the additional
220  * references taken by the filter model, it is important to base the
221  * zero ref count on the external reference count instead of on the full
222  * reference count of the node.
223  *
224  * The zero ref count value aids in determining which portions of the
225  * cache are possibly unused and could be removed. If a FilterElt has
226  * a zero ref count of one, then its child level is unused. However, the
227  * child level can only be removed from the cache if the FilterElt's
228  * parent level has an external ref count of zero. (Not the parent elt,
229  * because an invisible parent elt with external ref count == 0 might still
230  * become visible because of a state change in its child level!).  Otherwise,
231  * monitoring this level is necessary to possibly update the visibility state
232  * of the parent. This is an important difference from GtkTreeModelSort!
233  *
234  * Signals are only required for levels with an external ref count > 0.
235  * This due to reference counting rule 3, see the GtkTreeModel
236  * documentation. In the GtkTreeModelFilter we try hard to stick to this
237  * rule and not emit redundant signals (though redundant emissions of
238  * row-has-child-toggled could appear frequently; it does happen that
239  * we simply forward the signal emitted by e.g. GtkTreeStore but also
240  * emit our own copy).
241  */
242
243
244 typedef struct _FilterElt FilterElt;
245 typedef struct _FilterLevel FilterLevel;
246
247 struct _FilterElt
248 {
249   GtkTreeIter iter;
250   FilterLevel *children;
251   gint offset;
252   gint ref_count;
253   gint ext_ref_count;
254   gint zero_ref_count;
255   GSequenceIter *visible_siter; /* iter into visible_seq */
256 };
257
258 struct _FilterLevel
259 {
260   GSequence *seq;
261   GSequence *visible_seq;
262   gint ref_count;
263   gint ext_ref_count;
264
265   FilterElt *parent_elt;
266   FilterLevel *parent_level;
267 };
268
269
270 struct _GtkTreeModelFilterPrivate
271 {
272   GtkTreeModel *child_model;
273   gpointer root;
274   GtkTreePath *virtual_root;
275
276   gint stamp;
277   guint child_flags;
278   gint zero_ref_count;
279   gint visible_column;
280
281   GtkTreeModelFilterVisibleFunc visible_func;
282   gpointer visible_data;
283   GDestroyNotify visible_destroy;
284
285   GType *modify_types;
286   GtkTreeModelFilterModifyFunc modify_func;
287   gpointer modify_data;
288   GDestroyNotify modify_destroy;
289   gint modify_n_columns;
290
291   guint visible_method_set   : 1;
292   guint modify_func_set      : 1;
293
294   guint in_row_deleted       : 1;
295   guint virtual_root_deleted : 1;
296
297   /* signal ids */
298   gulong changed_id;
299   gulong inserted_id;
300   gulong has_child_toggled_id;
301   gulong deleted_id;
302   gulong reordered_id;
303 };
304
305 /* properties */
306 enum
307 {
308   PROP_0,
309   PROP_CHILD_MODEL,
310   PROP_VIRTUAL_ROOT
311 };
312
313 /* Set this to 0 to disable caching of child iterators.  This
314  * allows for more stringent testing.  It is recommended to set this
315  * to one when refactoring this code and running the unit tests to
316  * catch more errors.
317  */
318 #if 1
319 #  define GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS(filter) \
320         (((GtkTreeModelFilter *)filter)->priv->child_flags & GTK_TREE_MODEL_ITERS_PERSIST)
321 #else
322 #  define GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS(filter) (FALSE)
323 #endif
324
325 /* Defining this constant enables more assertions, which will be
326  * helpful when debugging the code.
327  */
328 #undef MODEL_FILTER_DEBUG
329
330 #define FILTER_ELT(filter_elt) ((FilterElt *)filter_elt)
331 #define FILTER_LEVEL(filter_level) ((FilterLevel *)filter_level)
332 #define GET_ELT(siter) ((FilterElt*) (siter ? g_sequence_get (siter) : NULL))
333
334 /* general code (object/interface init, properties, etc) */
335 static void         gtk_tree_model_filter_tree_model_init                 (GtkTreeModelIface       *iface);
336 static void         gtk_tree_model_filter_drag_source_init                (GtkTreeDragSourceIface  *iface);
337 static void         gtk_tree_model_filter_finalize                        (GObject                 *object);
338 static void         gtk_tree_model_filter_set_property                    (GObject                 *object,
339                                                                            guint                    prop_id,
340                                                                            const GValue            *value,
341                                                                            GParamSpec              *pspec);
342 static void         gtk_tree_model_filter_get_property                    (GObject                 *object,
343                                                                            guint                    prop_id,
344                                                                            GValue                 *value,
345                                                                            GParamSpec             *pspec);
346
347 /* signal handlers */
348 static void         gtk_tree_model_filter_row_changed                     (GtkTreeModel           *c_model,
349                                                                            GtkTreePath            *c_path,
350                                                                            GtkTreeIter            *c_iter,
351                                                                            gpointer                data);
352 static void         gtk_tree_model_filter_row_inserted                    (GtkTreeModel           *c_model,
353                                                                            GtkTreePath            *c_path,
354                                                                            GtkTreeIter            *c_iter,
355                                                                            gpointer                data);
356 static void         gtk_tree_model_filter_row_has_child_toggled           (GtkTreeModel           *c_model,
357                                                                            GtkTreePath            *c_path,
358                                                                            GtkTreeIter            *c_iter,
359                                                                            gpointer                data);
360 static void         gtk_tree_model_filter_row_deleted                     (GtkTreeModel           *c_model,
361                                                                            GtkTreePath            *c_path,
362                                                                            gpointer                data);
363 static void         gtk_tree_model_filter_rows_reordered                  (GtkTreeModel           *c_model,
364                                                                            GtkTreePath            *c_path,
365                                                                            GtkTreeIter            *c_iter,
366                                                                            gint                   *new_order,
367                                                                            gpointer                data);
368
369 /* GtkTreeModel interface */
370 static GtkTreeModelFlags gtk_tree_model_filter_get_flags                       (GtkTreeModel           *model);
371 static gint         gtk_tree_model_filter_get_n_columns                   (GtkTreeModel           *model);
372 static GType        gtk_tree_model_filter_get_column_type                 (GtkTreeModel           *model,
373                                                                            gint                    index);
374 static gboolean     gtk_tree_model_filter_get_iter_full                   (GtkTreeModel           *model,
375                                                                            GtkTreeIter            *iter,
376                                                                            GtkTreePath            *path);
377 static gboolean     gtk_tree_model_filter_get_iter                        (GtkTreeModel           *model,
378                                                                            GtkTreeIter            *iter,
379                                                                            GtkTreePath            *path);
380 static GtkTreePath *gtk_tree_model_filter_get_path                        (GtkTreeModel           *model,
381                                                                            GtkTreeIter            *iter);
382 static void         gtk_tree_model_filter_get_value                       (GtkTreeModel           *model,
383                                                                            GtkTreeIter            *iter,
384                                                                            gint                    column,
385                                                                            GValue                 *value);
386 static gboolean     gtk_tree_model_filter_iter_next                       (GtkTreeModel           *model,
387                                                                            GtkTreeIter            *iter);
388 static gboolean     gtk_tree_model_filter_iter_previous                   (GtkTreeModel           *model,
389                                                                            GtkTreeIter            *iter);
390 static gboolean     gtk_tree_model_filter_iter_children                   (GtkTreeModel           *model,
391                                                                            GtkTreeIter            *iter,
392                                                                            GtkTreeIter            *parent);
393 static gboolean     gtk_tree_model_filter_iter_has_child                  (GtkTreeModel           *model,
394                                                                            GtkTreeIter            *iter);
395 static gint         gtk_tree_model_filter_iter_n_children                 (GtkTreeModel           *model,
396                                                                            GtkTreeIter            *iter);
397 static gboolean     gtk_tree_model_filter_iter_nth_child                  (GtkTreeModel           *model,
398                                                                            GtkTreeIter            *iter,
399                                                                            GtkTreeIter            *parent,
400                                                                            gint                    n);
401 static gboolean     gtk_tree_model_filter_iter_parent                     (GtkTreeModel           *model,
402                                                                            GtkTreeIter            *iter,
403                                                                            GtkTreeIter            *child);
404 static void         gtk_tree_model_filter_ref_node                        (GtkTreeModel           *model,
405                                                                            GtkTreeIter            *iter);
406 static void         gtk_tree_model_filter_unref_node                      (GtkTreeModel           *model,
407                                                                            GtkTreeIter            *iter);
408
409 /* TreeDragSource interface */
410 static gboolean    gtk_tree_model_filter_row_draggable                    (GtkTreeDragSource      *drag_source,
411                                                                            GtkTreePath            *path);
412 static gboolean    gtk_tree_model_filter_drag_data_get                    (GtkTreeDragSource      *drag_source,
413                                                                            GtkTreePath            *path,
414                                                                            GtkSelectionData       *selection_data);
415 static gboolean    gtk_tree_model_filter_drag_data_delete                 (GtkTreeDragSource      *drag_source,
416                                                                            GtkTreePath            *path);
417
418 /* private functions */
419 static void        gtk_tree_model_filter_build_level                      (GtkTreeModelFilter     *filter,
420                                                                            FilterLevel            *parent_level,
421                                                                            FilterElt              *parent_elt,
422                                                                            gboolean                emit_inserted);
423
424 static void        gtk_tree_model_filter_free_level                       (GtkTreeModelFilter     *filter,
425                                                                            FilterLevel            *filter_level,
426                                                                            gboolean                unref,
427                                                                            gboolean                unref_external);
428
429 static GtkTreePath *gtk_tree_model_filter_elt_get_path                    (FilterLevel            *level,
430                                                                            FilterElt              *elt,
431                                                                            GtkTreePath            *root);
432
433 static GtkTreePath *gtk_tree_model_filter_add_root                        (GtkTreePath            *src,
434                                                                            GtkTreePath            *root);
435 static GtkTreePath *gtk_tree_model_filter_remove_root                     (GtkTreePath            *src,
436                                                                            GtkTreePath            *root);
437
438 static void         gtk_tree_model_filter_increment_stamp                 (GtkTreeModelFilter     *filter);
439
440 static void         gtk_tree_model_filter_real_modify                     (GtkTreeModelFilter     *self,
441                                                                            GtkTreeModel           *child_model,
442                                                                            GtkTreeIter            *iter,
443                                                                            GValue                 *value,
444                                                                            gint                    column);
445 static gboolean     gtk_tree_model_filter_real_visible                    (GtkTreeModelFilter     *filter,
446                                                                            GtkTreeModel           *child_model,
447                                                                            GtkTreeIter            *child_iter);
448 static gboolean     gtk_tree_model_filter_visible                         (GtkTreeModelFilter     *filter,
449                                                                            GtkTreeIter            *child_iter);
450 static void         gtk_tree_model_filter_clear_cache_helper              (GtkTreeModelFilter     *filter,
451                                                                            FilterLevel            *level);
452
453 static void         gtk_tree_model_filter_real_ref_node                   (GtkTreeModel           *model,
454                                                                            GtkTreeIter            *iter,
455                                                                            gboolean                external);
456 static void         gtk_tree_model_filter_real_unref_node                 (GtkTreeModel           *model,
457                                                                            GtkTreeIter            *iter,
458                                                                            gboolean                external,
459                                                                            gboolean                propagate_unref);
460
461 static void         gtk_tree_model_filter_set_model                       (GtkTreeModelFilter     *filter,
462                                                                            GtkTreeModel           *child_model);
463 static void         gtk_tree_model_filter_ref_path                        (GtkTreeModelFilter     *filter,
464                                                                            GtkTreePath            *path);
465 static void         gtk_tree_model_filter_unref_path                      (GtkTreeModelFilter     *filter,
466                                                                            GtkTreePath            *path,
467                                                                            int                     depth);
468 static void         gtk_tree_model_filter_set_root                        (GtkTreeModelFilter     *filter,
469                                                                            GtkTreePath            *root);
470
471 static GtkTreePath *gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter     *filter,
472                                                                            GtkTreePath            *child_path,
473                                                                            gboolean                build_levels,
474                                                                            gboolean                fetch_children);
475
476 static gboolean    gtk_tree_model_filter_elt_is_visible_in_target         (FilterLevel            *level,
477                                                                            FilterElt              *elt);
478
479 static FilterElt   *gtk_tree_model_filter_insert_elt_in_level             (GtkTreeModelFilter     *filter,
480                                                                            GtkTreeIter            *c_iter,
481                                                                            FilterLevel            *level,
482                                                                            gint                    offset,
483                                                                            gint                   *index);
484 static FilterElt   *gtk_tree_model_filter_fetch_child                     (GtkTreeModelFilter     *filter,
485                                                                            FilterLevel            *level,
486                                                                            gint                    offset,
487                                                                            gint                   *index);
488 static void         gtk_tree_model_filter_remove_elt_from_level           (GtkTreeModelFilter     *filter,
489                                                                            FilterLevel            *level,
490                                                                            FilterElt              *elt);
491 static void         gtk_tree_model_filter_update_children                 (GtkTreeModelFilter     *filter,
492                                                                            FilterLevel            *level,
493                                                                            FilterElt              *elt);
494 static void         gtk_tree_model_filter_emit_row_inserted_for_path      (GtkTreeModelFilter     *filter,
495                                                                            GtkTreeModel           *c_model,
496                                                                            GtkTreePath            *c_path,
497                                                                            GtkTreeIter            *c_iter);
498
499
500 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelFilter, gtk_tree_model_filter, G_TYPE_OBJECT,
501                          G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
502                                                 gtk_tree_model_filter_tree_model_init)
503                          G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
504                                                 gtk_tree_model_filter_drag_source_init))
505
506 static void
507 gtk_tree_model_filter_init (GtkTreeModelFilter *filter)
508 {
509   filter->priv = G_TYPE_INSTANCE_GET_PRIVATE (filter,
510                                               GTK_TYPE_TREE_MODEL_FILTER,
511                                               GtkTreeModelFilterPrivate);
512
513   filter->priv->visible_column = -1;
514   filter->priv->zero_ref_count = 0;
515   filter->priv->visible_method_set = FALSE;
516   filter->priv->modify_func_set = FALSE;
517   filter->priv->in_row_deleted = FALSE;
518   filter->priv->virtual_root_deleted = FALSE;
519 }
520
521 static void
522 gtk_tree_model_filter_class_init (GtkTreeModelFilterClass *filter_class)
523 {
524   GObjectClass *object_class;
525
526   object_class = (GObjectClass *) filter_class;
527
528   object_class->set_property = gtk_tree_model_filter_set_property;
529   object_class->get_property = gtk_tree_model_filter_get_property;
530
531   object_class->finalize = gtk_tree_model_filter_finalize;
532
533   filter_class->visible = gtk_tree_model_filter_real_visible;
534   filter_class->modify  = gtk_tree_model_filter_real_modify;
535
536   /* Properties -- FIXME: disabled translations for now, until I can come up with a
537    * better description
538    */
539   g_object_class_install_property (object_class,
540                                    PROP_CHILD_MODEL,
541                                    g_param_spec_object ("child-model",
542                                                         ("The child model"),
543                                                         ("The model for the filtermodel to filter"),
544                                                         GTK_TYPE_TREE_MODEL,
545                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
546
547   g_object_class_install_property (object_class,
548                                    PROP_VIRTUAL_ROOT,
549                                    g_param_spec_boxed ("virtual-root",
550                                                        ("The virtual root"),
551                                                        ("The virtual root (relative to the child model) for this filtermodel"),
552                                                        GTK_TYPE_TREE_PATH,
553                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
554
555   g_type_class_add_private (object_class, sizeof (GtkTreeModelFilterPrivate));
556 }
557
558 static void
559 gtk_tree_model_filter_tree_model_init (GtkTreeModelIface *iface)
560 {
561   iface->get_flags = gtk_tree_model_filter_get_flags;
562   iface->get_n_columns = gtk_tree_model_filter_get_n_columns;
563   iface->get_column_type = gtk_tree_model_filter_get_column_type;
564   iface->get_iter = gtk_tree_model_filter_get_iter;
565   iface->get_path = gtk_tree_model_filter_get_path;
566   iface->get_value = gtk_tree_model_filter_get_value;
567   iface->iter_next = gtk_tree_model_filter_iter_next;
568   iface->iter_previous = gtk_tree_model_filter_iter_previous;
569   iface->iter_children = gtk_tree_model_filter_iter_children;
570   iface->iter_has_child = gtk_tree_model_filter_iter_has_child;
571   iface->iter_n_children = gtk_tree_model_filter_iter_n_children;
572   iface->iter_nth_child = gtk_tree_model_filter_iter_nth_child;
573   iface->iter_parent = gtk_tree_model_filter_iter_parent;
574   iface->ref_node = gtk_tree_model_filter_ref_node;
575   iface->unref_node = gtk_tree_model_filter_unref_node;
576 }
577
578 static void
579 gtk_tree_model_filter_drag_source_init (GtkTreeDragSourceIface *iface)
580 {
581   iface->row_draggable = gtk_tree_model_filter_row_draggable;
582   iface->drag_data_delete = gtk_tree_model_filter_drag_data_delete;
583   iface->drag_data_get = gtk_tree_model_filter_drag_data_get;
584 }
585
586
587 static void
588 gtk_tree_model_filter_finalize (GObject *object)
589 {
590   GtkTreeModelFilter *filter = (GtkTreeModelFilter *) object;
591
592   if (filter->priv->virtual_root && !filter->priv->virtual_root_deleted)
593     {
594       gtk_tree_model_filter_unref_path (filter, filter->priv->virtual_root,
595                                         -1);
596       filter->priv->virtual_root_deleted = TRUE;
597     }
598
599   gtk_tree_model_filter_set_model (filter, NULL);
600
601   if (filter->priv->virtual_root)
602     gtk_tree_path_free (filter->priv->virtual_root);
603
604   if (filter->priv->root)
605     gtk_tree_model_filter_free_level (filter, filter->priv->root, TRUE, FALSE);
606
607   g_free (filter->priv->modify_types);
608   
609   if (filter->priv->modify_destroy)
610     filter->priv->modify_destroy (filter->priv->modify_data);
611
612   if (filter->priv->visible_destroy)
613     filter->priv->visible_destroy (filter->priv->visible_data);
614
615   /* must chain up */
616   G_OBJECT_CLASS (gtk_tree_model_filter_parent_class)->finalize (object);
617 }
618
619 static void
620 gtk_tree_model_filter_set_property (GObject      *object,
621                                     guint         prop_id,
622                                     const GValue *value,
623                                     GParamSpec   *pspec)
624 {
625   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (object);
626
627   switch (prop_id)
628     {
629       case PROP_CHILD_MODEL:
630         gtk_tree_model_filter_set_model (filter, g_value_get_object (value));
631         break;
632       case PROP_VIRTUAL_ROOT:
633         gtk_tree_model_filter_set_root (filter, g_value_get_boxed (value));
634         break;
635       default:
636         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
637         break;
638     }
639 }
640
641 static void
642 gtk_tree_model_filter_get_property (GObject    *object,
643                                     guint       prop_id,
644                                     GValue     *value,
645                                     GParamSpec *pspec)
646 {
647   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (object);
648
649   switch (prop_id)
650     {
651       case PROP_CHILD_MODEL:
652         g_value_set_object (value, filter->priv->child_model);
653         break;
654       case PROP_VIRTUAL_ROOT:
655         g_value_set_boxed (value, filter->priv->virtual_root);
656         break;
657       default:
658         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
659         break;
660     }
661 }
662
663 /* helpers */
664
665 static FilterElt *
666 filter_elt_new (void)
667 {
668   return g_slice_new (FilterElt);
669 }
670
671 static void
672 filter_elt_free (gpointer elt)
673 {
674   g_slice_free (FilterElt, elt);
675 }
676
677 static gint
678 filter_elt_cmp (gconstpointer a,
679                 gconstpointer b,
680                 gpointer      user_data)
681 {
682   const FilterElt *elt_a = a;
683   const FilterElt *elt_b = b;
684
685   if (elt_a->offset > elt_b->offset)
686     return +1;
687   else if (elt_a->offset < elt_b->offset)
688     return -1;
689   else
690     return 0;
691 }
692
693 static FilterElt *
694 lookup_elt_with_offset (GSequence      *seq,
695                         gint            offset,
696                         GSequenceIter **ret_siter)
697 {
698   GSequenceIter *siter;
699   FilterElt dummy;
700
701   dummy.offset = offset;
702   siter = g_sequence_lookup (seq, &dummy, filter_elt_cmp, NULL);
703
704   if (ret_siter)
705     *ret_siter = siter;
706
707   return GET_ELT (siter);
708 }
709
710 static void
711 increase_offset_iter (gpointer data,
712                       gpointer user_data)
713 {
714   FilterElt *elt = data;
715   gint offset = GPOINTER_TO_INT (user_data);
716
717   if (elt->offset >= offset)
718     elt->offset++;
719 }
720
721 static void
722 decrease_offset_iter (gpointer data,
723                       gpointer user_data)
724 {
725   FilterElt *elt = data;
726   gint offset = GPOINTER_TO_INT (user_data);
727
728   if (elt->offset > offset)
729     elt->offset--;
730 }
731
732 static void
733 gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter,
734                                    FilterLevel        *parent_level,
735                                    FilterElt          *parent_elt,
736                                    gboolean            emit_inserted)
737 {
738   GtkTreeIter iter;
739   GtkTreeIter first_node;
740   GtkTreeIter root;
741   FilterLevel *new_level;
742   FilterLevel *tmp_level;
743   FilterElt *tmp_elt;
744   GtkTreeIter f_iter;
745   gint length = 0;
746   gint i;
747   gboolean empty = TRUE;
748
749   g_assert (filter->priv->child_model != NULL);
750
751   /* Avoid building a level that already exists */
752   if (parent_level)
753     g_assert (parent_elt->children == NULL);
754   else
755     g_assert (filter->priv->root == NULL);
756
757   if (filter->priv->in_row_deleted)
758     return;
759
760   if (!parent_level)
761     {
762       if (filter->priv->virtual_root)
763         {
764           if (gtk_tree_model_get_iter (filter->priv->child_model, &root, filter->priv->virtual_root) == FALSE)
765             return;
766           length = gtk_tree_model_iter_n_children (filter->priv->child_model, &root);
767
768           if (gtk_tree_model_iter_children (filter->priv->child_model, &iter, &root) == FALSE)
769             return;
770         }
771       else
772         {
773           if (!gtk_tree_model_get_iter_first (filter->priv->child_model, &iter))
774             return;
775           length = gtk_tree_model_iter_n_children (filter->priv->child_model, NULL);
776         }
777     }
778   else
779     {
780       GtkTreeIter parent_iter;
781       GtkTreeIter child_parent_iter;
782
783       parent_iter.stamp = filter->priv->stamp;
784       parent_iter.user_data = parent_level;
785       parent_iter.user_data2 = parent_elt;
786
787       gtk_tree_model_filter_convert_iter_to_child_iter (filter,
788                                                         &child_parent_iter,
789                                                         &parent_iter);
790       if (gtk_tree_model_iter_children (filter->priv->child_model, &iter, &child_parent_iter) == FALSE)
791         return;
792
793       /* stamp may have changed */
794       gtk_tree_model_filter_convert_iter_to_child_iter (filter,
795                                                         &child_parent_iter,
796                                                         &parent_iter);
797       length = gtk_tree_model_iter_n_children (filter->priv->child_model, &child_parent_iter);
798
799       /* Take a reference on the parent */
800       gtk_tree_model_filter_real_ref_node (GTK_TREE_MODEL (filter),
801                                            &parent_iter, FALSE);
802     }
803
804   g_return_if_fail (length > 0);
805
806   new_level = g_new (FilterLevel, 1);
807   new_level->seq = g_sequence_new (filter_elt_free);
808   new_level->visible_seq = g_sequence_new (NULL);
809   new_level->ref_count = 0;
810   new_level->ext_ref_count = 0;
811   new_level->parent_elt = parent_elt;
812   new_level->parent_level = parent_level;
813
814   if (parent_elt)
815     parent_elt->children = new_level;
816   else
817     filter->priv->root = new_level;
818
819   /* increase the count of zero ref_counts */
820   tmp_level = parent_level;
821   tmp_elt = parent_elt;
822
823   while (tmp_level)
824     {
825       tmp_elt->zero_ref_count++;
826
827       tmp_elt = tmp_level->parent_elt;
828       tmp_level = tmp_level->parent_level;
829     }
830   if (new_level != filter->priv->root)
831     filter->priv->zero_ref_count++;
832
833   i = 0;
834
835   first_node = iter;
836
837   do
838     {
839       if (gtk_tree_model_filter_visible (filter, &iter))
840         {
841           FilterElt *filter_elt;
842
843           filter_elt = filter_elt_new ();
844           filter_elt->offset = i;
845           filter_elt->zero_ref_count = 0;
846           filter_elt->ref_count = 0;
847           filter_elt->ext_ref_count = 0;
848           filter_elt->children = NULL;
849           filter_elt->visible_siter = NULL;
850
851           if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
852             filter_elt->iter = iter;
853
854           g_sequence_append (new_level->seq, filter_elt);
855           filter_elt->visible_siter = g_sequence_append (new_level->visible_seq, filter_elt);
856           empty = FALSE;
857
858           if (emit_inserted)
859             {
860               GtkTreePath *f_path;
861               GtkTreeIter f_iter;
862               GtkTreeIter children;
863
864               f_iter.stamp = filter->priv->stamp;
865               f_iter.user_data = new_level;
866               f_iter.user_data2 = filter_elt;
867
868               f_path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter),
869                                                 &f_iter);
870               gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter),
871                                            f_path, &f_iter);
872               gtk_tree_path_free (f_path);
873
874               if (gtk_tree_model_iter_children (filter->priv->child_model,
875                                                 &children, &iter))
876                 gtk_tree_model_filter_update_children (filter,
877                                                        new_level,
878                                                        FILTER_ELT (f_iter.user_data2));
879             }
880         }
881       i++;
882     }
883   while (gtk_tree_model_iter_next (filter->priv->child_model, &iter));
884
885   /* The level does not contain any visible nodes.  However, changes in
886    * this level might affect the parent node, which can either be visible
887    * or invisible.  Therefore, this level can only be removed again,
888    * if the parent level has an external reference count of zero.  That is,
889    * if this level changes state, no signals are required in the parent
890    * level.
891    */
892   if (empty &&
893        (parent_level && parent_level->ext_ref_count == 0))
894     {
895       gtk_tree_model_filter_free_level (filter, new_level, FALSE, FALSE);
896       return;
897     }
898
899   /* If none of the nodes are visible, we will just pull in the
900    * first node of the level.
901    */
902   if (empty)
903     {
904       FilterElt *filter_elt;
905
906       filter_elt = filter_elt_new ();
907       filter_elt->offset = 0;
908       filter_elt->zero_ref_count = 0;
909       filter_elt->ref_count = 0;
910       filter_elt->ext_ref_count = 0;
911       filter_elt->children = NULL;
912       filter_elt->visible_siter = NULL;
913
914       if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
915         filter_elt->iter = first_node;
916
917       g_sequence_append (new_level->seq, filter_elt);
918     }
919
920   /* Keep a reference on the first node of this level.  We need this
921    * to make sure that we get all signals for this level.
922    */
923   f_iter.stamp = filter->priv->stamp;
924   f_iter.user_data = new_level;
925   f_iter.user_data2 = g_sequence_get (g_sequence_get_begin_iter (new_level->seq));
926
927   gtk_tree_model_filter_real_ref_node (GTK_TREE_MODEL (filter), &f_iter,
928                                        FALSE);
929 }
930
931 static void
932 gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter,
933                                   FilterLevel        *filter_level,
934                                   gboolean            unref,
935                                   gboolean            unref_external)
936 {
937   GSequenceIter *siter;
938   GSequenceIter *end_siter;
939
940   g_assert (filter_level);
941
942   end_siter = g_sequence_get_end_iter (filter_level->seq);
943   for (siter = g_sequence_get_begin_iter (filter_level->seq);
944        siter != end_siter;
945        siter = g_sequence_iter_next (siter))
946     {
947       FilterElt *elt = g_sequence_get (siter);
948
949       if (elt->children)
950         gtk_tree_model_filter_free_level (filter,
951                                           FILTER_LEVEL (elt->children),
952                                           unref, unref_external);
953
954       if (unref_external)
955         {
956           GtkTreeIter f_iter;
957
958           f_iter.stamp = filter->priv->stamp;
959           f_iter.user_data = filter_level;
960           f_iter.user_data2 = elt;
961
962           while (elt->ext_ref_count > 0)
963             gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
964                                                    &f_iter,
965                                                    TRUE, unref);
966         }
967     }
968
969   /* Release the reference on the first item.
970    */
971   if (unref)
972     {
973       GtkTreeIter f_iter;
974
975       f_iter.stamp = filter->priv->stamp;
976       f_iter.user_data = filter_level;
977       f_iter.user_data2 = g_sequence_get (g_sequence_get_begin_iter (filter_level->seq));
978
979       gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
980                                              &f_iter, FALSE, TRUE);
981     }
982
983   if (filter_level->ext_ref_count == 0)
984     {
985       FilterLevel *parent_level = filter_level->parent_level;
986       FilterElt *parent_elt = filter_level->parent_elt;
987
988       while (parent_level)
989         {
990           parent_elt->zero_ref_count--;
991
992           parent_elt = parent_level->parent_elt;
993           parent_level = parent_level->parent_level;
994         }
995
996       if (filter_level != filter->priv->root)
997         filter->priv->zero_ref_count--;
998     }
999
1000   if (filter_level->parent_elt)
1001     {
1002       /* Release reference on parent */
1003       if (unref)
1004         {
1005           GtkTreeIter parent_iter;
1006
1007           parent_iter.stamp = filter->priv->stamp;
1008           parent_iter.user_data = filter_level->parent_level;
1009           parent_iter.user_data2 = filter_level->parent_elt;
1010
1011           gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1012                                                  &parent_iter, FALSE, TRUE);
1013         }
1014
1015       filter_level->parent_elt->children = NULL;
1016     }
1017   else
1018     filter->priv->root = NULL;
1019
1020   g_sequence_free (filter_level->seq);
1021   g_sequence_free (filter_level->visible_seq);
1022   g_free (filter_level);
1023 }
1024
1025 /* prune_level() is like free_level(), however instead of being fully
1026  * freed, the level is pruned to a level with only the first node used
1027  * for monitoring.  For now it is only being called from
1028  * gtk_tree_model_filter_remove_elt_from_level(), which is the reason
1029  * this function is lacking a "gboolean unref" argument.
1030  */
1031 static void
1032 gtk_tree_model_filter_prune_level (GtkTreeModelFilter *filter,
1033                                    FilterLevel        *level)
1034 {
1035   GSequenceIter *siter;
1036   GSequenceIter *end_siter;
1037   FilterElt *elt;
1038   GtkTreeIter f_iter;
1039
1040   /* This function is called when the parent of level became invisible.
1041    * All external ref counts of the children need to be dropped.
1042    * All children except the first one can be removed.
1043    */
1044
1045   /* Any child levels can be freed */
1046   end_siter = g_sequence_get_end_iter (level->seq);
1047   for (siter = g_sequence_get_begin_iter (level->seq);
1048        siter != end_siter;
1049        siter = g_sequence_iter_next (siter))
1050     {
1051       FilterElt *elt = g_sequence_get (siter);
1052
1053       if (elt->children)
1054         gtk_tree_model_filter_free_level (filter,
1055                                           FILTER_LEVEL (elt->children), TRUE,
1056                                           TRUE);
1057     }
1058
1059   /* For the first item, only drop the external references */
1060   elt = g_sequence_get (g_sequence_get_begin_iter (level->seq));
1061
1062   f_iter.stamp = filter->priv->stamp;
1063   f_iter.user_data = level;
1064   f_iter.user_data2 = elt;
1065
1066   while (elt->ext_ref_count > 0)
1067     gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1068                                            &f_iter, TRUE, TRUE);
1069
1070   if (elt->visible_siter)
1071     {
1072       g_sequence_remove (elt->visible_siter);
1073       elt->visible_siter = NULL;
1074     }
1075
1076   /* Remove the other elts */
1077   end_siter = g_sequence_get_end_iter (level->seq);
1078   siter = g_sequence_get_begin_iter (level->seq);
1079   siter = g_sequence_iter_next (siter);
1080   for (; siter != end_siter; siter = g_sequence_iter_next (siter))
1081     {
1082       elt = g_sequence_get (siter);
1083
1084       f_iter.stamp = filter->priv->stamp;
1085       f_iter.user_data = level;
1086       f_iter.user_data2 = elt;
1087
1088       while (elt->ext_ref_count > 0)
1089         gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1090                                                &f_iter, TRUE, TRUE);
1091
1092       if (elt->visible_siter)
1093         {
1094           g_sequence_remove (elt->visible_siter);
1095           elt->visible_siter = NULL;
1096         }
1097     }
1098
1099   /* Remove [begin + 1, end] */
1100   siter = g_sequence_get_begin_iter (level->seq);
1101   siter = g_sequence_iter_next (siter);
1102
1103   g_sequence_remove_range (siter, end_siter);
1104
1105   /* The level must have reached an ext ref count of zero by now, though
1106    * we only assert on this in debugging mode.
1107    */
1108 #ifdef MODEL_FILTER_DEBUG
1109   g_assert (level->ext_ref_count == 0);
1110 #endif
1111 }
1112
1113 static void
1114 gtk_tree_model_filter_level_transfer_first_ref (GtkTreeModelFilter *filter,
1115                                                 FilterLevel        *level,
1116                                                 GSequenceIter      *from_iter,
1117                                                 GSequenceIter      *to_iter)
1118 {
1119   GtkTreeIter f_iter;
1120
1121   f_iter.stamp = filter->priv->stamp;
1122   f_iter.user_data = level;
1123   f_iter.user_data2 = g_sequence_get (to_iter);
1124
1125   gtk_tree_model_filter_real_ref_node (GTK_TREE_MODEL (filter),
1126                                        &f_iter, FALSE);
1127
1128   f_iter.stamp = filter->priv->stamp;
1129   f_iter.user_data = level;
1130   f_iter.user_data2 = g_sequence_get (from_iter);
1131
1132   gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1133                                          &f_iter, FALSE, TRUE);
1134 }
1135
1136 static void
1137 gtk_tree_model_filter_level_transfer_first_ref_with_index (GtkTreeModelFilter *filter,
1138                                                            FilterLevel        *level,
1139                                                            gint                from_index,
1140                                                            gint                to_index)
1141 {
1142   gtk_tree_model_filter_level_transfer_first_ref (filter, level,
1143                                                   g_sequence_get_iter_at_pos (level->seq, from_index),
1144                                                   g_sequence_get_iter_at_pos (level->seq, to_index));
1145 }
1146
1147 /* Creates paths suitable for accessing the child model. */
1148 static GtkTreePath *
1149 gtk_tree_model_filter_elt_get_path (FilterLevel *level,
1150                                     FilterElt   *elt,
1151                                     GtkTreePath *root)
1152 {
1153   FilterLevel *walker = level;
1154   FilterElt *walker2 = elt;
1155   GtkTreePath *path;
1156   GtkTreePath *real_path;
1157
1158   g_return_val_if_fail (level != NULL, NULL);
1159   g_return_val_if_fail (elt != NULL, NULL);
1160
1161   path = gtk_tree_path_new ();
1162
1163   while (walker)
1164     {
1165       gtk_tree_path_prepend_index (path, walker2->offset);
1166
1167       walker2 = walker->parent_elt;
1168       walker = walker->parent_level;
1169     }
1170
1171   if (root)
1172     {
1173       real_path = gtk_tree_model_filter_add_root (path, root);
1174       gtk_tree_path_free (path);
1175       return real_path;
1176     }
1177
1178   return path;
1179 }
1180
1181 static GtkTreePath *
1182 gtk_tree_model_filter_add_root (GtkTreePath *src,
1183                                 GtkTreePath *root)
1184 {
1185   GtkTreePath *retval;
1186   gint i;
1187
1188   retval = gtk_tree_path_copy (root);
1189
1190   for (i = 0; i < gtk_tree_path_get_depth (src); i++)
1191     gtk_tree_path_append_index (retval, gtk_tree_path_get_indices (src)[i]);
1192
1193   return retval;
1194 }
1195
1196 static GtkTreePath *
1197 gtk_tree_model_filter_remove_root (GtkTreePath *src,
1198                                    GtkTreePath *root)
1199 {
1200   GtkTreePath *retval;
1201   gint i;
1202   gint depth;
1203   gint *indices;
1204
1205   if (gtk_tree_path_get_depth (src) <= gtk_tree_path_get_depth (root))
1206     return NULL;
1207
1208   depth = gtk_tree_path_get_depth (src);
1209   indices = gtk_tree_path_get_indices (src);
1210
1211   for (i = 0; i < gtk_tree_path_get_depth (root); i++)
1212     if (indices[i] != gtk_tree_path_get_indices (root)[i])
1213       return NULL;
1214
1215   retval = gtk_tree_path_new ();
1216
1217   for (; i < depth; i++)
1218     gtk_tree_path_append_index (retval, indices[i]);
1219
1220   return retval;
1221 }
1222
1223 static void
1224 gtk_tree_model_filter_increment_stamp (GtkTreeModelFilter *filter)
1225 {
1226   do
1227     {
1228       filter->priv->stamp++;
1229     }
1230   while (filter->priv->stamp == 0);
1231
1232   gtk_tree_model_filter_clear_cache (filter);
1233 }
1234
1235 static gboolean
1236 gtk_tree_model_filter_real_visible (GtkTreeModelFilter *filter,
1237                                     GtkTreeModel       *child_model,
1238                                     GtkTreeIter        *child_iter)
1239 {
1240   if (filter->priv->visible_func)
1241     {
1242       return filter->priv->visible_func (child_model,
1243                                          child_iter,
1244                                          filter->priv->visible_data)
1245         ? TRUE : FALSE;
1246     }
1247   else if (filter->priv->visible_column >= 0)
1248    {
1249      GValue val = {0, };
1250
1251      gtk_tree_model_get_value (child_model, child_iter,
1252                                filter->priv->visible_column, &val);
1253
1254      if (g_value_get_boolean (&val))
1255        {
1256          g_value_unset (&val);
1257          return TRUE;
1258        }
1259
1260      g_value_unset (&val);
1261      return FALSE;
1262    }
1263
1264   /* no visible function set, so always visible */
1265   return TRUE;
1266 }
1267
1268 static gboolean
1269 gtk_tree_model_filter_visible (GtkTreeModelFilter *self,
1270                                GtkTreeIter        *child_iter)
1271 {
1272   return GTK_TREE_MODEL_FILTER_GET_CLASS (self)->visible (self,
1273       self->priv->child_model, child_iter);
1274 }
1275
1276 static void
1277 gtk_tree_model_filter_clear_cache_helper_iter (gpointer data,
1278                                                gpointer user_data)
1279 {
1280   GtkTreeModelFilter *filter = user_data;
1281   FilterElt *elt = data;
1282
1283 #ifdef MODEL_FILTER_DEBUG
1284   g_assert (elt->zero_ref_count >= 0);
1285 #endif
1286
1287   if (elt->zero_ref_count > 0)
1288     gtk_tree_model_filter_clear_cache_helper (filter, elt->children);
1289 }
1290
1291 static void
1292 gtk_tree_model_filter_clear_cache_helper (GtkTreeModelFilter *filter,
1293                                           FilterLevel        *level)
1294 {
1295   g_assert (level);
1296
1297   g_sequence_foreach (level->seq, gtk_tree_model_filter_clear_cache_helper_iter, filter);
1298
1299   /* If the level's ext_ref_count is zero, it means the level is not visible
1300    * and can be removed.  But, since we support monitoring a child level
1301    * of a parent for changes (these might affect the parent), we will only
1302    * free the level if the parent level also has an external ref
1303    * count of zero.  In that case, changes concerning our parent are
1304    * not requested.
1305    *
1306    * The root level is always visible, so an exception holds for levels
1307    * with the root level as parent level: these have to remain cached.
1308    */
1309   if (level->ext_ref_count == 0 && level != filter->priv->root &&
1310       level->parent_level && level->parent_level != filter->priv->root &&
1311       level->parent_level->ext_ref_count == 0)
1312     {
1313       gtk_tree_model_filter_free_level (filter, level, TRUE, FALSE);
1314       return;
1315     }
1316 }
1317
1318 static gboolean
1319 gtk_tree_model_filter_elt_is_visible_in_target (FilterLevel *level,
1320                                                 FilterElt   *elt)
1321 {
1322   if (!elt->visible_siter)
1323     return FALSE;
1324
1325   if (!level->parent_elt)
1326     return TRUE;
1327
1328   do
1329     {
1330       elt = level->parent_elt;
1331       level = level->parent_level;
1332
1333       if (elt && !elt->visible_siter)
1334         return FALSE;
1335     }
1336   while (level);
1337
1338   return TRUE;
1339 }
1340
1341 /* If a change has occurred in path (inserted, changed or deleted),
1342  * then this function is used to check all its ancestors.  An ancestor
1343  * could have changed state as a result and this needs to be propagated
1344  * to the objects monitoring the filter model.
1345  */
1346 static void
1347 gtk_tree_model_filter_check_ancestors (GtkTreeModelFilter *filter,
1348                                        GtkTreePath        *path)
1349 {
1350   int i = 0;
1351   int *indices = gtk_tree_path_get_indices (path);
1352   FilterElt *elt;
1353   FilterLevel *level;
1354   GtkTreeIter c_iter, tmp_iter;
1355
1356   level = FILTER_LEVEL (filter->priv->root);
1357
1358   if (!level)
1359     return;
1360
1361   if (filter->priv->virtual_root)
1362     gtk_tree_model_get_iter (filter->priv->child_model, &c_iter,
1363                              filter->priv->virtual_root);
1364
1365   tmp_iter = c_iter;
1366   gtk_tree_model_iter_nth_child (filter->priv->child_model, &c_iter,
1367                                  filter->priv->virtual_root ? &tmp_iter : NULL,
1368                                  indices[i]);
1369
1370   while (i < gtk_tree_path_get_depth (path) - 1)
1371     {
1372       gboolean requested_state;
1373
1374       elt = lookup_elt_with_offset (level->seq,
1375                                     gtk_tree_path_get_indices (path)[i], NULL);
1376
1377       requested_state = gtk_tree_model_filter_visible (filter, &c_iter);
1378
1379       if (!elt)
1380         {
1381           int index;
1382           GtkTreePath *c_path;
1383
1384           if (requested_state == FALSE)
1385             return;
1386
1387           /* The elt does not exist in this level (so it is not
1388            * visible), but should now be visible.  We emit the
1389            * row-inserted and row-has-child-toggled signals.
1390            */
1391           elt = gtk_tree_model_filter_insert_elt_in_level (filter,
1392                                                            &c_iter,
1393                                                            level,
1394                                                            indices[i],
1395                                                            &index);
1396
1397           /* insert_elt_in_level defaults to FALSE */
1398           elt->visible_siter = g_sequence_insert_sorted (level->visible_seq,
1399                                                          elt,
1400                                                          filter_elt_cmp, NULL);
1401
1402           c_path = gtk_tree_model_get_path (filter->priv->child_model,
1403                                             &c_iter);
1404
1405           gtk_tree_model_filter_emit_row_inserted_for_path (filter,
1406                                                             filter->priv->child_model,
1407                                                             c_path,
1408                                                             &c_iter);
1409
1410           gtk_tree_path_free (c_path);
1411
1412           /* We can immediately return, because this node was not visible
1413            * before and its children will be checked for in response to
1414            * the emitted row-has-child-toggled signal.
1415            */
1416           return;
1417         }
1418       else if (elt->visible_siter)
1419         {
1420           if (!requested_state)
1421             {
1422               /* A node has turned invisible.  Remove it from the level
1423                * and emit row-deleted.  Since this node is being
1424                * deleted. it makes no sense to look further up the
1425                * chain.
1426                */
1427               gtk_tree_model_filter_remove_elt_from_level (filter,
1428                                                            level, elt);
1429               return;
1430             }
1431
1432           /* Otherwise continue up the chain */
1433         }
1434       else if (!elt->visible_siter)
1435         {
1436           if (requested_state)
1437             {
1438               /* A node is already in the cache, but invisible.  This
1439                * is usually a node on which a reference is kept by
1440                * the filter model, or a node fetched on the filter's
1441                * request, and thus not shown.  Therefore, we will
1442                * not emit row-inserted for this node.  Instead,
1443                * we signal to its parent that a change has occurred.
1444                *
1445                * Exception: root level, in this case, we must emit
1446                * row-inserted.
1447                */
1448               if (level->parent_level)
1449                 {
1450                   GtkTreeIter f_iter;
1451                   GtkTreePath *f_path;
1452
1453                   elt->visible_siter = g_sequence_insert_sorted (level->visible_seq, elt,
1454                                                                  filter_elt_cmp, NULL);
1455
1456                   f_iter.stamp = filter->priv->stamp;
1457                   f_iter.user_data = level->parent_level;
1458                   f_iter.user_data2 = level->parent_elt;
1459
1460                   f_path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter),
1461                                                     &f_iter);
1462                   gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
1463                                                         f_path, &f_iter);
1464                   gtk_tree_path_free (f_path);
1465                 }
1466               else
1467                 {
1468                   GtkTreePath *c_path;
1469
1470                   elt->visible_siter = g_sequence_insert_sorted (level->visible_seq, elt,
1471                                                                  filter_elt_cmp, NULL);
1472
1473                   c_path = gtk_tree_model_get_path (filter->priv->child_model,
1474                                                     &c_iter);
1475
1476                   gtk_tree_model_filter_emit_row_inserted_for_path (filter,
1477                                                                     filter->priv->child_model,
1478                                                                     c_path,
1479                                                                     &c_iter);
1480
1481                   gtk_tree_path_free (c_path);
1482                 }
1483
1484               /* We can immediately return, because this node was not visible
1485                * before and the parent will check its children, including
1486                * this node, in response to the emitted row-has-child-toggled
1487                * signal.
1488                */
1489               return;
1490             }
1491
1492           /* Not visible, so no need to continue. */
1493           return;
1494         }
1495
1496       if (!elt->children)
1497         {
1498           /* If an elt does not have children, these are not visible.
1499            * Therefore, any signals emitted for these children will
1500            * be ignored, so we do not have to emit them.
1501            */
1502           return;
1503         }
1504
1505       level = elt->children;
1506       i++;
1507
1508       tmp_iter = c_iter;
1509       gtk_tree_model_iter_nth_child (filter->priv->child_model, &c_iter,
1510                                      &tmp_iter, indices[i]);
1511     }
1512 }
1513
1514 static FilterElt *
1515 gtk_tree_model_filter_insert_elt_in_level (GtkTreeModelFilter *filter,
1516                                            GtkTreeIter        *c_iter,
1517                                            FilterLevel        *level,
1518                                            gint                offset,
1519                                            gint               *index)
1520 {
1521   FilterElt *elt;
1522   GSequenceIter *siter;
1523
1524   elt = filter_elt_new ();
1525
1526   if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
1527     elt->iter = *c_iter;
1528
1529   elt->offset = offset;
1530   elt->zero_ref_count = 0;
1531   elt->ref_count = 0;
1532   elt->ext_ref_count = 0;
1533   elt->children = NULL;
1534
1535   /* Because we don't emit row_inserted, the node is invisible and thus
1536    * not inserted in visible_seq
1537    */
1538   elt->visible_siter = NULL;
1539
1540   siter = g_sequence_insert_sorted (level->seq, elt, filter_elt_cmp, NULL);
1541   *index = g_sequence_iter_get_position (siter);
1542
1543   /* If the insert location is zero, we need to move our reference
1544    * on the old first node to the new first node.
1545    */
1546   if (*index == 0)
1547     gtk_tree_model_filter_level_transfer_first_ref_with_index (filter, level,
1548                                                                1, 0);
1549
1550   return elt;
1551 }
1552
1553 static FilterElt *
1554 gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter,
1555                                    FilterLevel        *level,
1556                                    gint                offset,
1557                                    gint               *index)
1558 {
1559   gint len;
1560   GtkTreePath *c_path = NULL;
1561   GtkTreeIter c_iter;
1562   GtkTreePath *c_parent_path = NULL;
1563   GtkTreeIter c_parent_iter;
1564
1565   /* check if child exists and is visible */
1566   if (level->parent_elt)
1567     {
1568       c_parent_path =
1569         gtk_tree_model_filter_elt_get_path (level->parent_level,
1570                                             level->parent_elt,
1571                                             filter->priv->virtual_root);
1572       if (!c_parent_path)
1573         return NULL;
1574     }
1575   else
1576     {
1577       if (filter->priv->virtual_root)
1578         c_parent_path = gtk_tree_path_copy (filter->priv->virtual_root);
1579       else
1580         c_parent_path = NULL;
1581     }
1582
1583   if (c_parent_path)
1584     {
1585       gtk_tree_model_get_iter (filter->priv->child_model,
1586                                &c_parent_iter,
1587                                c_parent_path);
1588       len = gtk_tree_model_iter_n_children (filter->priv->child_model,
1589                                             &c_parent_iter);
1590
1591       c_path = gtk_tree_path_copy (c_parent_path);
1592       gtk_tree_path_free (c_parent_path);
1593     }
1594   else
1595     {
1596       len = gtk_tree_model_iter_n_children (filter->priv->child_model, NULL);
1597       c_path = gtk_tree_path_new ();
1598     }
1599
1600   gtk_tree_path_append_index (c_path, offset);
1601   gtk_tree_model_get_iter (filter->priv->child_model, &c_iter, c_path);
1602   gtk_tree_path_free (c_path);
1603
1604   if (offset >= len || !gtk_tree_model_filter_visible (filter, &c_iter))
1605     return NULL;
1606
1607   return gtk_tree_model_filter_insert_elt_in_level (filter, &c_iter,
1608                                                     level, offset,
1609                                                     index);
1610 }
1611
1612 /* Note that this function is never called from the row-deleted handler.
1613  * This means that this function is only used for removing elements
1614  * which are still present in the child model.  As a result, we must
1615  * take care to properly release the references the filter model has
1616  * on the child model nodes.
1617  */
1618 static void
1619 gtk_tree_model_filter_remove_elt_from_level (GtkTreeModelFilter *filter,
1620                                              FilterLevel        *level,
1621                                              FilterElt          *elt)
1622 {
1623   FilterElt *parent;
1624   FilterLevel *parent_level;
1625   gint length, orig_level_ext_ref_count;
1626   GtkTreeIter iter;
1627   GtkTreePath *path = NULL;
1628
1629   gboolean emit_child_toggled = FALSE;
1630
1631   /* We need to know about the level's ext ref count before removal
1632    * of this node.
1633    */
1634   orig_level_ext_ref_count = level->ext_ref_count;
1635
1636   iter.stamp = filter->priv->stamp;
1637   iter.user_data = level;
1638   iter.user_data2 = elt;
1639
1640   if (orig_level_ext_ref_count > 0)
1641     path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
1642   else
1643     /* If the level is not visible, the parent is potentially invisible
1644      * too.  Either way, as no signal will be emitted, there is no use
1645      * for a path.
1646      */
1647     path = NULL;
1648
1649   parent = level->parent_elt;
1650   parent_level = level->parent_level;
1651
1652   length = g_sequence_get_length (level->seq);
1653
1654   /* first register the node to be invisible */
1655   g_sequence_remove (elt->visible_siter);
1656   elt->visible_siter = NULL;
1657
1658   /*
1659    * If level != root level and the number of visible nodes is 0 (ie. this
1660    * is the last node to be removed from the level), emit
1661    * row-has-child-toggled.
1662    */
1663
1664   if (level != filter->priv->root
1665       && g_sequence_get_length (level->visible_seq) == 0
1666       && parent
1667       && parent->visible_siter)
1668     emit_child_toggled = TRUE;
1669
1670   /* Distinguish:
1671    *   - length > 1: in this case, the node is removed from the level
1672    *                 and row-deleted is emitted.
1673    *   - length == 1: in this case, we need to decide whether to keep
1674    *                  the level or to free it.
1675    */
1676   if (length > 1)
1677     {
1678       GSequenceIter *siter;
1679
1680       /* We emit row-deleted, and remove the node from the cache.
1681        * If it has any children, these will be removed here as well.
1682        */
1683
1684       /* FIXME: I am not 100% sure it is always save to fully free the
1685        * level here.  Perhaps the state of the parent level, etc. has to
1686        * be checked to make the right decision, like is done below for
1687        * the case length == 1.
1688        */
1689       if (elt->children)
1690         gtk_tree_model_filter_free_level (filter, elt->children, TRUE, TRUE);
1691
1692       /* If the first node is being removed, transfer, the reference */
1693       if (elt == g_sequence_get (g_sequence_get_begin_iter (level->seq)))
1694         {
1695           gtk_tree_model_filter_level_transfer_first_ref_with_index (filter, level,
1696                                                                      0, 1);
1697         }
1698
1699       while (elt->ext_ref_count > 0)
1700         gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1701                                                &iter, TRUE, TRUE);
1702       /* In this case, we do remove reference counts we've added ourselves,
1703        * since the node will be removed from the data structures.
1704        */
1705       while (elt->ref_count > 0)
1706         gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1707                                                &iter, FALSE, TRUE);
1708
1709       /* remove the node */
1710       lookup_elt_with_offset (level->seq, elt->offset, &siter);
1711       g_sequence_remove (siter);
1712
1713       gtk_tree_model_filter_increment_stamp (filter);
1714
1715       /* Only if the node is in the root level (parent == NULL) or
1716        * the level is visible, a row-deleted signal is necessary.
1717        */
1718       if (!parent || orig_level_ext_ref_count > 0)
1719         gtk_tree_model_row_deleted (GTK_TREE_MODEL (filter), path);
1720     }
1721   else
1722     {
1723       /* There is only one node left in this level */
1724 #ifdef MODEL_FILTER_DEBUG
1725       g_assert (length == 1);
1726 #endif
1727
1728       /* The row is signalled as deleted to the client.  We have to
1729        * drop the remaining external reference count here, the client
1730        * will not do it.
1731        *
1732        * We keep the reference counts we've obtained ourselves.
1733        */
1734       while (elt->ext_ref_count > 0)
1735         gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (filter),
1736                                                &iter, TRUE, TRUE);
1737
1738       /* This level is still required if:
1739        * - it is the root level
1740        * - its parent level is the root level
1741        * - its parent level has an external ref count > 0
1742        */
1743       if (! (level == filter->priv->root ||
1744              level->parent_level == filter->priv->root ||
1745              level->parent_level->ext_ref_count > 0))
1746         {
1747           /* Otherwise, the level can be removed */
1748           gtk_tree_model_filter_free_level (filter, level, TRUE, TRUE);
1749         }
1750       else
1751         {
1752           /* Level is kept, but we turn our attention to a child level.
1753            *
1754            * If level is not the root level, it is a child level with
1755            * an ext ref count that is now 0.  That means that any child level
1756            * of elt can be removed.
1757            */
1758           if (level != filter->priv->root)
1759             {
1760 #ifdef MODEL_FILTER_DEBUG
1761               g_assert (level->ext_ref_count == 0);
1762 #endif
1763               if (elt->children)
1764                 gtk_tree_model_filter_free_level (filter, elt->children,
1765                                                   TRUE, TRUE);
1766             }
1767           else
1768             {
1769               /* In this case, we want to keep the level with the first
1770                * node pulled in to monitor for signals.
1771                */
1772               if (elt->children)
1773                 gtk_tree_model_filter_prune_level (filter, elt->children);
1774             }
1775         }
1776
1777       if (!parent || orig_level_ext_ref_count > 0)
1778         gtk_tree_model_row_deleted (GTK_TREE_MODEL (filter), path);
1779     }
1780
1781   gtk_tree_path_free (path);
1782
1783   if (emit_child_toggled && parent->ext_ref_count > 0)
1784     {
1785       GtkTreeIter piter;
1786       GtkTreePath *ppath;
1787
1788       piter.stamp = filter->priv->stamp;
1789       piter.user_data = parent_level;
1790       piter.user_data2 = parent;
1791
1792       ppath = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &piter);
1793
1794       gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
1795                                             ppath, &piter);
1796       gtk_tree_path_free (ppath);
1797     }
1798 }
1799
1800 /* This function is called after the given node has become visible.
1801  * When the node has children, we should build the level and
1802  * take a reference on the first child.
1803  */
1804 static void
1805 gtk_tree_model_filter_update_children (GtkTreeModelFilter *filter,
1806                                        FilterLevel        *level,
1807                                        FilterElt          *elt)
1808 {
1809   GtkTreeIter c_iter;
1810   GtkTreeIter iter;
1811
1812   if (!elt->visible_siter)
1813     return;
1814
1815   iter.stamp = filter->priv->stamp;
1816   iter.user_data = level;
1817   iter.user_data2 = elt;
1818
1819   gtk_tree_model_filter_convert_iter_to_child_iter (filter, &c_iter, &iter);
1820
1821   if ((!level->parent_level || level->parent_level->ext_ref_count > 0) &&
1822       gtk_tree_model_iter_has_child (filter->priv->child_model, &c_iter))
1823     {
1824       if (!elt->children)
1825         gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
1826
1827       if (elt->ext_ref_count > 0 && elt->children &&
1828           g_sequence_get_length (elt->children->seq))
1829         {
1830           GtkTreePath *path;
1831           path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
1832           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
1833                                                 path,
1834                                                 &iter);
1835           if (path)
1836             gtk_tree_path_free (path);
1837         }
1838     }
1839 }
1840
1841 /* Path is relative to the child model (this is on search on elt offset)
1842  * but with the virtual root already removed if necesssary.
1843  */
1844 static gboolean
1845 find_elt_with_offset (GtkTreeModelFilter *filter,
1846                       GtkTreePath        *path,
1847                       FilterLevel       **level_,
1848                       FilterElt         **elt_)
1849 {
1850   int i = 0;
1851   FilterLevel *level;
1852   FilterLevel *parent_level = NULL;
1853   FilterElt *elt = NULL;
1854
1855   level = FILTER_LEVEL (filter->priv->root);
1856
1857   while (i < gtk_tree_path_get_depth (path))
1858     {
1859       if (!level)
1860         return FALSE;
1861
1862       elt = lookup_elt_with_offset (level->seq,
1863                                     gtk_tree_path_get_indices (path)[i],
1864                                     NULL);
1865
1866       if (!elt)
1867         return FALSE;
1868
1869       parent_level = level;
1870       level = elt->children;
1871       i++;
1872     }
1873
1874   if (level_)
1875     *level_ = parent_level;
1876
1877   if (elt_)
1878     *elt_ = elt;
1879
1880   return TRUE;
1881 }
1882
1883 /* TreeModel signals */
1884 static void
1885 gtk_tree_model_filter_emit_row_inserted_for_path (GtkTreeModelFilter *filter,
1886                                                   GtkTreeModel       *c_model,
1887                                                   GtkTreePath        *c_path,
1888                                                   GtkTreeIter        *c_iter)
1889 {
1890   FilterLevel *level;
1891   FilterElt *elt;
1892   GtkTreePath *path;
1893   GtkTreeIter iter, children;
1894   gboolean signals_emitted = FALSE;
1895
1896   if (!filter->priv->root)
1897     {
1898       /* The root level has not been exposed to the view yet, so we
1899        * need to emit signals for any node that is being inserted.
1900        */
1901       gtk_tree_model_filter_build_level (filter, NULL, NULL, TRUE);
1902
1903       /* Check if the root level was built.  Then child levels
1904        * that matter have also been built (due to update_children,
1905        * which triggers iter_n_children).
1906        */
1907       if (filter->priv->root &&
1908           g_sequence_get_length (FILTER_LEVEL (filter->priv->root)->visible_seq) > 0)
1909         signals_emitted = TRUE;
1910     }
1911
1912   gtk_tree_model_filter_increment_stamp (filter);
1913
1914   /* We need to disallow to build new levels, because we are then pulling
1915    * in a child in an invisible level.  We only want to find path if it
1916    * is in a visible level (and thus has a parent that is visible).
1917    */
1918   path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
1919                                                                 c_path,
1920                                                                 FALSE,
1921                                                                 TRUE);
1922
1923   if (!path)
1924     /* parent is probably being filtered out */
1925     return;
1926
1927   gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter), &iter, path);
1928
1929   level = FILTER_LEVEL (iter.user_data);
1930   elt = FILTER_ELT (iter.user_data2);
1931
1932   /* Make sure elt is visible.  elt can already be visible in case
1933    * it was pulled in above, so avoid inserted it into visible_seq twice.
1934    */
1935   if (!elt->visible_siter)
1936     {
1937       elt->visible_siter = g_sequence_insert_sorted (level->visible_seq,
1938                                                      elt, filter_elt_cmp,
1939                                                      NULL);
1940     }
1941
1942   /* Check whether the node and all of its parents are visible */
1943   if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt))
1944     {
1945       /* visibility changed -- reget path */
1946       gtk_tree_path_free (path);
1947       path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
1948
1949       if (!signals_emitted &&
1950           (!level->parent_level || level->ext_ref_count > 0))
1951         gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter);
1952
1953       if (level->parent_level && level->parent_elt->ext_ref_count > 0 &&
1954           g_sequence_get_length (level->visible_seq) == 1)
1955         {
1956           /* We know that this is the first visible node in this level, so
1957            * we need to emit row-has-child-toggled on the parent.  This
1958            * does not apply to the root level.
1959            */
1960
1961           gtk_tree_path_up (path);
1962           gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path);
1963
1964           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
1965                                                 path,
1966                                                 &iter);
1967         }
1968
1969       if (!signals_emitted
1970           && gtk_tree_model_iter_children (c_model, &children, c_iter))
1971         gtk_tree_model_filter_update_children (filter, level, elt);
1972     }
1973
1974   gtk_tree_path_free (path);
1975 }
1976
1977 static void
1978 gtk_tree_model_filter_row_changed (GtkTreeModel *c_model,
1979                                    GtkTreePath  *c_path,
1980                                    GtkTreeIter  *c_iter,
1981                                    gpointer      data)
1982 {
1983   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
1984   GtkTreeIter iter;
1985   GtkTreeIter children;
1986   GtkTreeIter real_c_iter;
1987   GtkTreePath *path = NULL;
1988   GtkTreePath *real_path = NULL;
1989
1990   FilterElt *elt;
1991   FilterLevel *level;
1992
1993   gboolean requested_state;
1994   gboolean current_state;
1995   gboolean free_c_path = FALSE;
1996
1997   g_return_if_fail (c_path != NULL || c_iter != NULL);
1998
1999   if (!c_path)
2000     {
2001       c_path = gtk_tree_model_get_path (c_model, c_iter);
2002       free_c_path = TRUE;
2003     }
2004
2005   if (filter->priv->virtual_root)
2006     real_path = gtk_tree_model_filter_remove_root (c_path,
2007                                                    filter->priv->virtual_root);
2008   else
2009     real_path = gtk_tree_path_copy (c_path);
2010
2011   if (c_iter)
2012     real_c_iter = *c_iter;
2013   else
2014     gtk_tree_model_get_iter (c_model, &real_c_iter, c_path);
2015
2016   /* is this node above the virtual root? */
2017   if (filter->priv->virtual_root &&
2018       (gtk_tree_path_get_depth (filter->priv->virtual_root)
2019           >= gtk_tree_path_get_depth (c_path)))
2020     goto done;
2021
2022   /* what's the requested state? */
2023   requested_state = gtk_tree_model_filter_visible (filter, &real_c_iter);
2024
2025   /* now, let's see whether the item is there */
2026   path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
2027                                                                 c_path,
2028                                                                 FALSE,
2029                                                                 FALSE);
2030
2031   if (path)
2032     {
2033       gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter),
2034                                            &iter, path);
2035       current_state = FILTER_ELT (iter.user_data2)->visible_siter != NULL;
2036     }
2037   else
2038     current_state = FALSE;
2039
2040   if (current_state == FALSE && requested_state == FALSE)
2041     /* no changes required */
2042     goto done;
2043
2044   if (current_state == TRUE && requested_state == FALSE)
2045     {
2046       gtk_tree_model_filter_remove_elt_from_level (filter,
2047                                                    FILTER_LEVEL (iter.user_data),
2048                                                    FILTER_ELT (iter.user_data2));
2049
2050       if (real_path)
2051         gtk_tree_model_filter_check_ancestors (filter, real_path);
2052
2053       goto done;
2054     }
2055
2056   if (current_state == TRUE && requested_state == TRUE)
2057     {
2058       /* propagate the signal; also get a path taking only visible
2059        * nodes into account.
2060        */
2061       gtk_tree_path_free (path);
2062       path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
2063
2064       level = FILTER_LEVEL (iter.user_data);
2065       elt = FILTER_ELT (iter.user_data2);
2066
2067       if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt))
2068         {
2069           if (level->ext_ref_count > 0)
2070             gtk_tree_model_row_changed (GTK_TREE_MODEL (filter), path, &iter);
2071
2072           /* and update the children */
2073           if (gtk_tree_model_iter_children (c_model, &children, &real_c_iter))
2074             gtk_tree_model_filter_update_children (filter, level, elt);
2075         }
2076
2077       if (real_path)
2078         gtk_tree_model_filter_check_ancestors (filter, real_path);
2079
2080       goto done;
2081     }
2082
2083   /* only current == FALSE and requested == TRUE is left,
2084    * pull in the child
2085    */
2086   g_return_if_fail (current_state == FALSE && requested_state == TRUE);
2087
2088   if (real_path)
2089     gtk_tree_model_filter_check_ancestors (filter, real_path);
2090
2091   gtk_tree_model_filter_emit_row_inserted_for_path (filter, c_model,
2092                                                     c_path, c_iter);
2093
2094 done:
2095   if (path)
2096     gtk_tree_path_free (path);
2097
2098   if (real_path)
2099     gtk_tree_path_free (real_path);
2100
2101   if (free_c_path)
2102     gtk_tree_path_free (c_path);
2103 }
2104
2105 static void
2106 gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model,
2107                                     GtkTreePath  *c_path,
2108                                     GtkTreeIter  *c_iter,
2109                                     gpointer      data)
2110 {
2111   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2112   GtkTreePath *real_path = NULL;
2113
2114   GtkTreeIter real_c_iter;
2115
2116   FilterElt *elt = NULL;
2117   FilterLevel *level = NULL;
2118   FilterLevel *parent_level = NULL;
2119   GSequenceIter *siter;
2120   FilterElt dummy;
2121
2122   gint i = 0, offset;
2123
2124   gboolean free_c_path = FALSE;
2125   gboolean emit_row_inserted = FALSE;
2126
2127   g_return_if_fail (c_path != NULL || c_iter != NULL);
2128
2129   if (!c_path)
2130     {
2131       c_path = gtk_tree_model_get_path (c_model, c_iter);
2132       free_c_path = TRUE;
2133     }
2134
2135   if (c_iter)
2136     real_c_iter = *c_iter;
2137   else
2138     gtk_tree_model_get_iter (c_model, &real_c_iter, c_path);
2139
2140   /* the row has already been inserted. so we need to fixup the
2141    * virtual root here first
2142    */
2143   if (filter->priv->virtual_root)
2144     {
2145       if (gtk_tree_path_get_depth (filter->priv->virtual_root) >=
2146           gtk_tree_path_get_depth (c_path))
2147         {
2148           gint level;
2149           gint *v_indices, *c_indices;
2150           gboolean common_prefix = TRUE;
2151
2152           level = gtk_tree_path_get_depth (c_path) - 1;
2153           v_indices = gtk_tree_path_get_indices (filter->priv->virtual_root);
2154           c_indices = gtk_tree_path_get_indices (c_path);
2155
2156           for (i = 0; i < level; i++)
2157             if (v_indices[i] != c_indices[i])
2158               {
2159                 common_prefix = FALSE;
2160                 break;
2161               }
2162
2163           if (common_prefix && v_indices[level] >= c_indices[level])
2164             (v_indices[level])++;
2165         }
2166     }
2167
2168   /* subtract virtual root if necessary */
2169   if (filter->priv->virtual_root)
2170     {
2171       real_path = gtk_tree_model_filter_remove_root (c_path,
2172                                                      filter->priv->virtual_root);
2173       /* not our child */
2174       if (!real_path)
2175         goto done;
2176     }
2177   else
2178     real_path = gtk_tree_path_copy (c_path);
2179
2180   if (!filter->priv->root)
2181     {
2182       /* The root level has not been exposed to the view yet, so we
2183        * need to emit signals for any node that is being inserted.
2184        */
2185       gtk_tree_model_filter_build_level (filter, NULL, NULL, TRUE);
2186
2187       /* Check if the root level was built.  Then child levels
2188        * that matter have also been built (due to update_children,
2189        * which triggers iter_n_children).
2190        */
2191       if (filter->priv->root)
2192         {
2193           emit_row_inserted = FALSE;
2194           goto done;
2195         }
2196     }
2197
2198   if (gtk_tree_path_get_depth (real_path) - 1 >= 1)
2199     {
2200       gboolean found = FALSE;
2201       GtkTreePath *parent = gtk_tree_path_copy (real_path);
2202       gtk_tree_path_up (parent);
2203
2204       found = find_elt_with_offset (filter, parent, &parent_level, &elt);
2205
2206       gtk_tree_path_free (parent);
2207
2208       if (!found)
2209         /* Parent is not in the cache and probably being filtered out */
2210         goto done;
2211
2212       level = elt->children;
2213     }
2214   else
2215     level = FILTER_LEVEL (filter->priv->root);
2216
2217   if (!level)
2218     {
2219       if (elt && elt->visible_siter)
2220         {
2221           /* The level in which the new node should be inserted does not
2222            * exist, but the parent, elt, does.  If elt is visible, emit
2223            * row-has-child-toggled.
2224            */
2225           GtkTreePath *tmppath;
2226           GtkTreeIter  tmpiter;
2227
2228           tmpiter.stamp = filter->priv->stamp;
2229           tmpiter.user_data = parent_level;
2230           tmpiter.user_data2 = elt;
2231
2232           tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (filter),
2233                                              &tmpiter);
2234
2235           if (tmppath)
2236             {
2237               gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
2238                                                     tmppath, &tmpiter);
2239               gtk_tree_path_free (tmppath);
2240             }
2241         }
2242       goto done;
2243     }
2244
2245   /* let's try to insert the value */
2246   offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1];
2247
2248   /* update the offsets, yes if we didn't insert the node above, there will
2249    * be a gap here. This will be filled with the node (via fetch_child) when
2250    * it becomes visible
2251    */
2252   dummy.offset = offset;
2253   siter = g_sequence_search (level->seq, &dummy, filter_elt_cmp, NULL);
2254   siter = g_sequence_iter_prev (siter);
2255   g_sequence_foreach_range (siter, g_sequence_get_end_iter (level->seq),
2256                             increase_offset_iter, GINT_TO_POINTER (offset));
2257
2258   /* only insert when visible */
2259   if (gtk_tree_model_filter_visible (filter, &real_c_iter))
2260     {
2261       FilterElt *felt;
2262
2263       felt = gtk_tree_model_filter_insert_elt_in_level (filter,
2264                                                         &real_c_iter,
2265                                                         level, offset,
2266                                                         &i);
2267
2268       /* insert_elt_in_level defaults to FALSE */
2269       felt->visible_siter = g_sequence_insert_sorted (level->visible_seq,
2270                                                       felt,
2271                                                       filter_elt_cmp, NULL);
2272       emit_row_inserted = TRUE;
2273     }
2274
2275 done:
2276   gtk_tree_model_filter_check_ancestors (filter, real_path);
2277
2278   if (emit_row_inserted)
2279     gtk_tree_model_filter_emit_row_inserted_for_path (filter, c_model,
2280                                                       c_path, c_iter);
2281
2282   if (real_path)
2283     gtk_tree_path_free (real_path);
2284
2285   if (free_c_path)
2286     gtk_tree_path_free (c_path);
2287 }
2288
2289 static void
2290 gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *c_model,
2291                                              GtkTreePath  *c_path,
2292                                              GtkTreeIter  *c_iter,
2293                                              gpointer      data)
2294 {
2295   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2296   GtkTreePath *path;
2297   GtkTreeIter iter;
2298   FilterLevel *level;
2299   FilterElt *elt;
2300   gboolean requested_state;
2301
2302   g_return_if_fail (c_path != NULL && c_iter != NULL);
2303
2304   /* If we get row-has-child-toggled on the virtual root, and there is
2305    * no root level; try to build it now.
2306    */
2307   if (filter->priv->virtual_root && !filter->priv->root
2308       && !gtk_tree_path_compare (c_path, filter->priv->virtual_root))
2309     {
2310       gtk_tree_model_filter_build_level (filter, NULL, NULL, TRUE);
2311       return;
2312     }
2313
2314   /* For all other levels, there is a chance that the visibility state
2315    * of the parent has changed now.
2316    */
2317
2318   path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
2319                                                                 c_path,
2320                                                                 FALSE,
2321                                                                 TRUE);
2322   if (!path)
2323     return;
2324
2325   gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (data), &iter, path);
2326
2327   level = FILTER_LEVEL (iter.user_data);
2328   elt = FILTER_ELT (iter.user_data2);
2329
2330   gtk_tree_path_free (path);
2331
2332   requested_state = gtk_tree_model_filter_visible (filter, c_iter);
2333
2334   if (!elt->visible_siter && !requested_state)
2335     {
2336       /* The parent node currently is not visible and will not become
2337        * visible, so we will not pass on the row-has-child-toggled event.
2338        */
2339       return;
2340     }
2341   else if (elt->visible_siter && !requested_state)
2342     {
2343       /* The node is no longer visible, so it has to be removed.
2344        * _remove_elt_from_level() takes care of emitting row-has-child-toggled
2345        * when required.
2346        */
2347       gtk_tree_model_filter_remove_elt_from_level (filter, level, elt);
2348
2349       return;
2350     }
2351   else if (!elt->visible_siter && requested_state)
2352     {
2353       elt->visible_siter = g_sequence_insert_sorted (level->visible_seq,
2354                                                      elt, filter_elt_cmp,
2355                                                      NULL);
2356
2357       /* Only insert if the parent is visible in the target */
2358       if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt))
2359         {
2360           path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
2361           gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter);
2362           gtk_tree_path_free (path);
2363
2364           /* We do not update children now, because that will happen
2365            * below.
2366            */
2367         }
2368     }
2369   /* For the remaining possibility, elt->visible && requested_state
2370    * no action is required.
2371    */
2372
2373   /* If this node is referenced and has children, build the level so we
2374    * can monitor it for changes.
2375    */
2376   if (elt->ref_count > 1 && !elt->children &&
2377       gtk_tree_model_iter_has_child (c_model, c_iter))
2378     gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
2379
2380   /* get a path taking only visible nodes into account */
2381   path = gtk_tree_model_get_path (GTK_TREE_MODEL (data), &iter);
2382   gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
2383   gtk_tree_path_free (path);
2384 }
2385
2386 static void
2387 gtk_tree_model_filter_virtual_root_deleted (GtkTreeModelFilter *filter,
2388                                             GtkTreePath        *c_path)
2389 {
2390   gint i, nodes;
2391   GtkTreePath *path;
2392   FilterLevel *level = FILTER_LEVEL (filter->priv->root);
2393
2394   /* The virtual root (or one of its ancestors) has been deleted.  This
2395    * means that all content for our model is now gone.  We deal with
2396    * this by removing everything in the filter model: we just iterate
2397    * over the root level and emit a row-deleted for each FilterElt.
2398    * (FIXME: Should we emit row-deleted for child nodes as well? This
2399    * has never been fully clear in TreeModel).
2400    */
2401
2402   /* We unref the path of the virtual root, up to and not including the
2403    * deleted node which can no longer be unreffed.
2404    */
2405   gtk_tree_model_filter_unref_path (filter, filter->priv->virtual_root,
2406                                     gtk_tree_path_get_depth (c_path) - 1);
2407   filter->priv->virtual_root_deleted = TRUE;
2408
2409   if (!level)
2410     return;
2411
2412   nodes = g_sequence_get_length (level->visible_seq);
2413
2414   /* We should not propagate the unref here.  An unref for any of these
2415    * nodes will fail, since the respective nodes in the child model are
2416    * no longer there.
2417    */
2418   gtk_tree_model_filter_free_level (filter, filter->priv->root, FALSE, FALSE);
2419
2420   gtk_tree_model_filter_increment_stamp (filter);
2421
2422   path = gtk_tree_path_new ();
2423   gtk_tree_path_append_index (path, 0);
2424
2425   for (i = 0; i < nodes; i++)
2426     gtk_tree_model_row_deleted (GTK_TREE_MODEL (filter), path);
2427
2428   gtk_tree_path_free (path);
2429 }
2430
2431 static void
2432 gtk_tree_model_filter_adjust_virtual_root (GtkTreeModelFilter *filter,
2433                                            GtkTreePath        *c_path)
2434 {
2435   gint i;
2436   gint level;
2437   gint *v_indices, *c_indices;
2438   gboolean common_prefix = TRUE;
2439
2440   level = gtk_tree_path_get_depth (c_path) - 1;
2441   v_indices = gtk_tree_path_get_indices (filter->priv->virtual_root);
2442   c_indices = gtk_tree_path_get_indices (c_path);
2443
2444   for (i = 0; i < level; i++)
2445     if (v_indices[i] != c_indices[i])
2446       {
2447         common_prefix = FALSE;
2448         break;
2449       }
2450
2451   if (common_prefix && v_indices[level] > c_indices[level])
2452     (v_indices[level])--;
2453 }
2454
2455 static void
2456 gtk_tree_model_filter_row_deleted_invisible_node (GtkTreeModelFilter *filter,
2457                                                   GtkTreePath        *c_path)
2458 {
2459   int offset;
2460   GtkTreePath *real_path;
2461   FilterLevel *level;
2462   FilterElt *elt;
2463   FilterElt dummy;
2464   GSequenceIter *siter;
2465
2466   /* The node deleted in the child model is not visible in the
2467    * filter model.  We will not emit a signal, just fixup the offsets
2468    * of the other nodes.
2469    */
2470
2471   if (!filter->priv->root)
2472     return;
2473
2474   level = FILTER_LEVEL (filter->priv->root);
2475
2476   /* subtract vroot if necessary */
2477   if (filter->priv->virtual_root)
2478     {
2479       real_path = gtk_tree_model_filter_remove_root (c_path,
2480                                                      filter->priv->virtual_root);
2481       /* we don't handle this */
2482       if (!real_path)
2483         return;
2484     }
2485   else
2486     real_path = gtk_tree_path_copy (c_path);
2487
2488   if (gtk_tree_path_get_depth (real_path) - 1 >= 1)
2489     {
2490       gboolean found = FALSE;
2491       GtkTreePath *parent = gtk_tree_path_copy (real_path);
2492       gtk_tree_path_up (parent);
2493
2494       found = find_elt_with_offset (filter, parent, &level, &elt);
2495
2496       gtk_tree_path_free (parent);
2497
2498       if (!found)
2499         {
2500           /* parent is filtered out, so no level */
2501           gtk_tree_path_free (real_path);
2502           return;
2503         }
2504
2505       level = elt->children;
2506     }
2507
2508   offset = gtk_tree_path_get_indices (real_path)[gtk_tree_path_get_depth (real_path) - 1];
2509   gtk_tree_path_free (real_path);
2510
2511   if (!level)
2512     return;
2513
2514   /* decrease offset of all nodes following the deleted node */
2515   dummy.offset = offset;
2516   siter = g_sequence_search (level->seq, &dummy, filter_elt_cmp, NULL);
2517   g_sequence_foreach_range (siter, g_sequence_get_end_iter (level->seq),
2518                             decrease_offset_iter, GINT_TO_POINTER (offset));
2519 }
2520
2521 static void
2522 gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model,
2523                                    GtkTreePath  *c_path,
2524                                    gpointer      data)
2525 {
2526   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2527   GtkTreePath *path;
2528   GtkTreeIter iter;
2529   FilterElt *elt, *parent_elt = NULL;
2530   FilterLevel *level, *parent_level = NULL;
2531   GSequenceIter *siter;
2532   gboolean emit_child_toggled = FALSE;
2533   gboolean emit_row_deleted = FALSE;
2534   gint offset;
2535   gint orig_level_ext_ref_count;
2536
2537   g_return_if_fail (c_path != NULL);
2538
2539   /* special case the deletion of an ancestor of the virtual root */
2540   if (filter->priv->virtual_root &&
2541       (gtk_tree_path_is_ancestor (c_path, filter->priv->virtual_root) ||
2542        !gtk_tree_path_compare (c_path, filter->priv->virtual_root)))
2543     {
2544       gtk_tree_model_filter_virtual_root_deleted (filter, c_path);
2545       return;
2546     }
2547
2548   /* adjust the virtual root for the deleted row */
2549   if (filter->priv->virtual_root &&
2550       gtk_tree_path_get_depth (filter->priv->virtual_root) >=
2551       gtk_tree_path_get_depth (c_path))
2552     gtk_tree_model_filter_adjust_virtual_root (filter, c_path);
2553
2554   path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
2555                                                                 c_path,
2556                                                                 FALSE,
2557                                                                 FALSE);
2558
2559   if (!path)
2560     {
2561       gtk_tree_model_filter_row_deleted_invisible_node (filter, c_path);
2562       return;
2563     }
2564
2565   /* a node was deleted, which was in our cache */
2566   gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (data), &iter, path);
2567
2568   level = FILTER_LEVEL (iter.user_data);
2569   elt = FILTER_ELT (iter.user_data2);
2570   offset = elt->offset;
2571   orig_level_ext_ref_count = level->ext_ref_count;
2572
2573   if (elt->visible_siter)
2574     {
2575       /* get a path taking only visible nodes into account */
2576       gtk_tree_path_free (path);
2577       path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
2578
2579       if (g_sequence_get_length (level->visible_seq) == 1)
2580         {
2581           emit_child_toggled = TRUE;
2582           parent_level = level->parent_level;
2583           parent_elt = level->parent_elt;
2584         }
2585
2586       emit_row_deleted = TRUE;
2587     }
2588
2589   /* Release the references on this node, without propagation because
2590    * the node does not exist anymore in the child model.  The filter
2591    * model's references on the node in case of level->parent or use
2592    * of a virtual root are automatically destroyed by the child model.
2593    */
2594   while (elt->ext_ref_count > 0)
2595     gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
2596                                            TRUE, FALSE);
2597   while (elt->ref_count > 0)
2598     gtk_tree_model_filter_real_unref_node (GTK_TREE_MODEL (data), &iter,
2599                                            FALSE, FALSE);
2600
2601   if (g_sequence_get_length (level->seq) == 1)
2602     {
2603       /* kill level */
2604       gtk_tree_model_filter_free_level (filter, level, FALSE, FALSE);
2605     }
2606   else
2607     {
2608       GSequenceIter *tmp;
2609       gboolean is_first;
2610
2611       lookup_elt_with_offset (level->seq, elt->offset, &siter);
2612       is_first = g_sequence_get_begin_iter (level->seq) == siter;
2613
2614       /* remove the row */
2615       g_sequence_remove (elt->visible_siter);
2616       tmp = g_sequence_iter_next (siter);
2617       g_sequence_remove (siter);
2618       g_sequence_foreach_range (tmp, g_sequence_get_end_iter (level->seq),
2619                                 decrease_offset_iter, GINT_TO_POINTER (offset));
2620
2621       /* Take a reference on the new first node.  The first node previously
2622        * keeping this reference has been removed above.
2623        */
2624       if (is_first)
2625         {
2626           GtkTreeIter f_iter;
2627
2628           f_iter.stamp = filter->priv->stamp;
2629           f_iter.user_data = level;
2630           f_iter.user_data2 = g_sequence_get (g_sequence_get_begin_iter (level->seq));
2631
2632           gtk_tree_model_filter_real_ref_node (GTK_TREE_MODEL (filter),
2633                                                &f_iter, FALSE);
2634         }
2635     }
2636
2637   if (emit_row_deleted)
2638     {
2639       /* emit row_deleted */
2640       gtk_tree_model_filter_increment_stamp (filter);
2641
2642       if (!parent_elt || orig_level_ext_ref_count > 0)
2643         gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
2644     }
2645
2646   if (emit_child_toggled && parent_level)
2647     {
2648       GtkTreeIter iter2;
2649       GtkTreePath *path2;
2650
2651       iter2.stamp = filter->priv->stamp;
2652       iter2.user_data = parent_level;
2653       iter2.user_data2 = parent_elt;
2654
2655       /* We set in_row_deleted to TRUE to avoid a level build triggered
2656        * by row-has-child-toggled (parent model could call iter_has_child
2657        * for example).
2658        */
2659       filter->priv->in_row_deleted = TRUE;
2660       path2 = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter2);
2661       gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter),
2662                                             path2, &iter2);
2663       gtk_tree_path_free (path2);
2664       filter->priv->in_row_deleted = FALSE;
2665     }
2666
2667   if (filter->priv->virtual_root)
2668     {
2669       GtkTreePath *real_path;
2670
2671       real_path = gtk_tree_model_filter_remove_root (c_path,
2672                                                      filter->priv->root);
2673       if (real_path)
2674         {
2675           gtk_tree_model_filter_check_ancestors (filter, real_path);
2676           gtk_tree_path_free (real_path);
2677         }
2678     }
2679   else
2680     gtk_tree_model_filter_check_ancestors (filter, c_path);
2681
2682   gtk_tree_path_free (path);
2683 }
2684
2685 static void
2686 gtk_tree_model_filter_rows_reordered (GtkTreeModel *c_model,
2687                                       GtkTreePath  *c_path,
2688                                       GtkTreeIter  *c_iter,
2689                                       gint         *new_order,
2690                                       gpointer      data)
2691 {
2692   FilterElt *elt;
2693   FilterLevel *level;
2694   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data);
2695
2696   GtkTreePath *path;
2697   GtkTreeIter iter;
2698
2699   GSequence *tmp_seq;
2700   GSequenceIter *tmp_end_iter;
2701   GSequenceIter *old_first_elt = NULL;
2702   gint *tmp_array;
2703   gint i, elt_count;
2704   gint length;
2705
2706   g_return_if_fail (new_order != NULL);
2707
2708   if (c_path == NULL || gtk_tree_path_get_depth (c_path) == 0)
2709     {
2710       length = gtk_tree_model_iter_n_children (c_model, NULL);
2711
2712       if (filter->priv->virtual_root)
2713         {
2714           gint new_pos = -1;
2715
2716           /* reorder root level of path */
2717           for (i = 0; i < length; i++)
2718             if (new_order[i] == gtk_tree_path_get_indices (filter->priv->virtual_root)[0])
2719               new_pos = i;
2720
2721           if (new_pos < 0)
2722             return;
2723
2724           gtk_tree_path_get_indices (filter->priv->virtual_root)[0] = new_pos;
2725           return;
2726         }
2727
2728       path = gtk_tree_path_new ();
2729       level = FILTER_LEVEL (filter->priv->root);
2730     }
2731   else
2732     {
2733       GtkTreeIter child_iter;
2734
2735       /* virtual root anchor reordering */
2736       if (filter->priv->virtual_root &&
2737           gtk_tree_path_is_ancestor (c_path, filter->priv->virtual_root))
2738         {
2739           gint new_pos = -1;
2740           gint length;
2741           gint level;
2742           GtkTreeIter real_c_iter;
2743
2744           level = gtk_tree_path_get_depth (c_path);
2745
2746           if (c_iter)
2747             real_c_iter = *c_iter;
2748           else
2749             gtk_tree_model_get_iter (c_model, &real_c_iter, c_path);
2750
2751           length = gtk_tree_model_iter_n_children (c_model, &real_c_iter);
2752
2753           for (i = 0; i < length; i++)
2754             if (new_order[i] == gtk_tree_path_get_indices (filter->priv->virtual_root)[level])
2755               new_pos = i;
2756
2757           if (new_pos < 0)
2758             return;
2759
2760           gtk_tree_path_get_indices (filter->priv->virtual_root)[level] = new_pos;
2761           return;
2762         }
2763
2764       path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
2765                                                                     c_path,
2766                                                                     FALSE,
2767                                                                     FALSE);
2768
2769       if (!path && filter->priv->virtual_root &&
2770           gtk_tree_path_compare (c_path, filter->priv->virtual_root))
2771         return;
2772
2773       if (!path && !filter->priv->virtual_root)
2774         return;
2775
2776       if (!path)
2777         {
2778           /* root level mode */
2779           if (!c_iter)
2780             gtk_tree_model_get_iter (c_model, c_iter, c_path);
2781           length = gtk_tree_model_iter_n_children (c_model, c_iter);
2782           path = gtk_tree_path_new ();
2783           level = FILTER_LEVEL (filter->priv->root);
2784         }
2785       else
2786         {
2787           gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (data),
2788                                                &iter, path);
2789
2790           elt = FILTER_ELT (iter.user_data2);
2791
2792           if (!elt->children)
2793             {
2794               gtk_tree_path_free (path);
2795               return;
2796             }
2797
2798           level = elt->children;
2799
2800           gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (filter), &child_iter, &iter);
2801           length = gtk_tree_model_iter_n_children (c_model, &child_iter);
2802         }
2803     }
2804
2805   if (!level || g_sequence_get_length (level->seq) < 1)
2806     {
2807       gtk_tree_path_free (path);
2808       return;
2809     }
2810
2811   /* NOTE: we do not bail out here if level->seq->len < 2 like
2812    * GtkTreeModelSort does. This because we do some special tricky
2813    * reordering.
2814    */
2815
2816   tmp_seq = g_sequence_new (filter_elt_free);
2817   tmp_end_iter = g_sequence_get_end_iter (tmp_seq);
2818   tmp_array = g_new (gint, g_sequence_get_length (level->visible_seq));
2819   elt_count = 0;
2820
2821   for (i = 0; i < length; i++)
2822     {
2823       FilterElt *elt;
2824       GSequenceIter *siter;
2825
2826       elt = lookup_elt_with_offset (level->seq, new_order[i], &siter);
2827       if (elt == NULL)
2828         continue;
2829
2830       /* Keep a reference if this elt has old_pos == 0 */
2831       if (new_order[i] == 0)
2832         old_first_elt = siter;
2833
2834       /* Only for visible items an entry should be present in the order array
2835        * to be emitted.
2836        */
2837       if (elt->visible_siter)
2838         tmp_array[elt_count++] = g_sequence_iter_get_position (elt->visible_siter);
2839
2840       /* Steal elt from level->seq and append it to tmp_seq */
2841       g_sequence_move (siter, tmp_end_iter);
2842       elt->offset = i;
2843     }
2844
2845   g_warn_if_fail (g_sequence_get_length (level->seq) == 0);
2846   g_sequence_free (level->seq);
2847   level->seq = tmp_seq;
2848   g_sequence_sort (level->visible_seq, filter_elt_cmp, NULL);
2849
2850   /* Transfer the reference from the old item at position 0 to the
2851    * new item at position 0.
2852    */
2853   if (old_first_elt && g_sequence_iter_get_position (old_first_elt))
2854     gtk_tree_model_filter_level_transfer_first_ref (filter,
2855                                                     level,
2856                                                     old_first_elt,
2857                                                     g_sequence_get_iter_at_pos (level->seq, 0));
2858
2859
2860   /* emit rows_reordered */
2861   if (g_sequence_get_length (level->visible_seq) > 0)
2862     {
2863       if (!gtk_tree_path_get_indices (path))
2864         gtk_tree_model_rows_reordered (GTK_TREE_MODEL (data), path, NULL,
2865                                        tmp_array);
2866       else
2867         {
2868           /* get a path taking only visible nodes into account */
2869           gtk_tree_path_free (path);
2870           path = gtk_tree_model_get_path (GTK_TREE_MODEL (data), &iter);
2871
2872           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (data), path, &iter,
2873                                          tmp_array);
2874         }
2875     }
2876
2877   /* done */
2878   g_free (tmp_array);
2879   gtk_tree_path_free (path);
2880 }
2881
2882 /* TreeModelIface implementation */
2883 static GtkTreeModelFlags
2884 gtk_tree_model_filter_get_flags (GtkTreeModel *model)
2885 {
2886   GtkTreeModelFlags flags;
2887
2888   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), 0);
2889   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, 0);
2890
2891   flags = gtk_tree_model_get_flags (GTK_TREE_MODEL_FILTER (model)->priv->child_model);
2892
2893   if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
2894     return GTK_TREE_MODEL_LIST_ONLY;
2895
2896   return 0;
2897 }
2898
2899 static gint
2900 gtk_tree_model_filter_get_n_columns (GtkTreeModel *model)
2901 {
2902   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
2903
2904   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), 0);
2905   g_return_val_if_fail (filter->priv->child_model != NULL, 0);
2906
2907   if (filter->priv->child_model == NULL)
2908     return 0;
2909
2910   /* so we can't modify the modify func after this ... */
2911   filter->priv->modify_func_set = TRUE;
2912
2913   if (filter->priv->modify_n_columns > 0)
2914     return filter->priv->modify_n_columns;
2915
2916   return gtk_tree_model_get_n_columns (filter->priv->child_model);
2917 }
2918
2919 static GType
2920 gtk_tree_model_filter_get_column_type (GtkTreeModel *model,
2921                                        gint          index)
2922 {
2923   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
2924
2925   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), G_TYPE_INVALID);
2926   g_return_val_if_fail (filter->priv->child_model != NULL, G_TYPE_INVALID);
2927
2928   /* so we can't modify the modify func after this ... */
2929   filter->priv->modify_func_set = TRUE;
2930
2931   if (filter->priv->modify_types)
2932     {
2933       g_return_val_if_fail (index < filter->priv->modify_n_columns, G_TYPE_INVALID);
2934
2935       return filter->priv->modify_types[index];
2936     }
2937
2938   return gtk_tree_model_get_column_type (filter->priv->child_model, index);
2939 }
2940
2941 /* A special case of _get_iter; this function can also get iters which
2942  * are not visible.  These iters should ONLY be passed internally, never
2943  * pass those along with a signal emission.
2944  */
2945 static gboolean
2946 gtk_tree_model_filter_get_iter_full (GtkTreeModel *model,
2947                                      GtkTreeIter  *iter,
2948                                      GtkTreePath  *path)
2949 {
2950   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
2951   gint *indices;
2952   FilterLevel *level;
2953   FilterElt *elt;
2954   gint depth, i;
2955   GSequenceIter *siter;
2956
2957   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
2958   g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
2959
2960   indices = gtk_tree_path_get_indices (path);
2961
2962   if (filter->priv->root == NULL)
2963     gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
2964   level = FILTER_LEVEL (filter->priv->root);
2965
2966   depth = gtk_tree_path_get_depth (path);
2967   if (!depth)
2968     {
2969       iter->stamp = 0;
2970       return FALSE;
2971     }
2972
2973   for (i = 0; i < depth - 1; i++)
2974     {
2975       if (!level || indices[i] >= g_sequence_get_length (level->seq))
2976         {
2977           iter->stamp = 0;
2978           return FALSE;
2979         }
2980
2981       siter = g_sequence_get_iter_at_pos (level->seq, indices[i]);
2982       if (g_sequence_iter_is_end (siter))
2983         {
2984           iter->stamp = 0;
2985           return FALSE;
2986         }
2987
2988       elt = GET_ELT (siter);
2989
2990       if (!elt->children)
2991         gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
2992       level = elt->children;
2993     }
2994
2995   if (!level || indices[i] >= g_sequence_get_length (level->seq))
2996     {
2997       iter->stamp = 0;
2998       return FALSE;
2999     }
3000
3001   iter->stamp = filter->priv->stamp;
3002   iter->user_data = level;
3003
3004   siter = g_sequence_get_iter_at_pos (level->seq, indices[depth - 1]);
3005   if (g_sequence_iter_is_end (siter))
3006     {
3007       iter->stamp = 0;
3008       return FALSE;
3009     }
3010   iter->user_data2 = GET_ELT (siter);
3011
3012   return TRUE;
3013 }
3014
3015 static gboolean
3016 gtk_tree_model_filter_get_iter (GtkTreeModel *model,
3017                                 GtkTreeIter  *iter,
3018                                 GtkTreePath  *path)
3019 {
3020   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3021   gint *indices;
3022   FilterLevel *level;
3023   FilterElt *elt;
3024   GSequenceIter *siter;
3025   gint depth, i;
3026
3027   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3028   g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
3029
3030   indices = gtk_tree_path_get_indices (path);
3031
3032   if (filter->priv->root == NULL)
3033     gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
3034   level = FILTER_LEVEL (filter->priv->root);
3035
3036   depth = gtk_tree_path_get_depth (path);
3037   if (!depth)
3038     {
3039       iter->stamp = 0;
3040       return FALSE;
3041     }
3042
3043   for (i = 0; i < depth - 1; i++)
3044     {
3045       if (!level || indices[i] >= g_sequence_get_length (level->visible_seq))
3046         {
3047           iter->stamp = 0;
3048           return FALSE;
3049         }
3050
3051       siter = g_sequence_get_iter_at_pos (level->visible_seq, indices[i]);
3052       if (g_sequence_iter_is_end (siter))
3053         {
3054           iter->stamp = 0;
3055           return FALSE;
3056         }
3057
3058       elt = GET_ELT (siter);
3059       if (!elt->children)
3060         gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
3061       level = elt->children;
3062     }
3063
3064   if (!level || indices[i] >= g_sequence_get_length (level->visible_seq))
3065     {
3066       iter->stamp = 0;
3067       return FALSE;
3068     }
3069
3070   iter->stamp = filter->priv->stamp;
3071   iter->user_data = level;
3072
3073   siter = g_sequence_get_iter_at_pos (level->visible_seq, indices[depth - 1]);
3074   if (g_sequence_iter_is_end (siter))
3075     {
3076       iter->stamp = 0;
3077       return FALSE;
3078     }
3079   iter->user_data2 = GET_ELT (siter);
3080
3081   return TRUE;
3082 }
3083
3084 static GtkTreePath *
3085 gtk_tree_model_filter_get_path (GtkTreeModel *model,
3086                                 GtkTreeIter  *iter)
3087 {
3088   GtkTreePath *retval;
3089   FilterLevel *level;
3090   FilterElt *elt;
3091
3092   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), NULL);
3093   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, NULL);
3094   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp, NULL);
3095
3096   level = iter->user_data;
3097   elt = iter->user_data2;
3098
3099   if (!elt->visible_siter)
3100     return NULL;
3101
3102   retval = gtk_tree_path_new ();
3103
3104   while (level)
3105     {
3106       gint index;
3107
3108       index = g_sequence_iter_get_position (elt->visible_siter);
3109       gtk_tree_path_prepend_index (retval, index);
3110
3111       elt = level->parent_elt;
3112       level = level->parent_level;
3113     }
3114
3115   return retval;
3116 }
3117
3118 static void
3119 gtk_tree_model_filter_real_modify (GtkTreeModelFilter *self,
3120                                    GtkTreeModel       *child_model,
3121                                    GtkTreeIter        *iter,
3122                                    GValue             *value,
3123                                    gint                column)
3124 {
3125   if (self->priv->modify_func)
3126     {
3127       g_return_if_fail (column < self->priv->modify_n_columns);
3128
3129       g_value_init (value, self->priv->modify_types[column]);
3130       self->priv->modify_func (GTK_TREE_MODEL (self),
3131                            iter,
3132                            value,
3133                            column,
3134                            self->priv->modify_data);
3135     }
3136   else
3137     {
3138       GtkTreeIter child_iter;
3139
3140       gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (self),
3141                                                         &child_iter, iter);
3142       gtk_tree_model_get_value (child_model, &child_iter, column, value);
3143     }
3144 }
3145
3146 static void
3147 gtk_tree_model_filter_get_value (GtkTreeModel *model,
3148                                  GtkTreeIter  *iter,
3149                                  gint          column,
3150                                  GValue       *value)
3151 {
3152   GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (model);
3153
3154   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (model));
3155   g_return_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL);
3156   g_return_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp);
3157
3158   GTK_TREE_MODEL_FILTER_GET_CLASS (model)->modify (filter,
3159       filter->priv->child_model, iter, value, column);
3160 }
3161
3162 static gboolean
3163 gtk_tree_model_filter_iter_next (GtkTreeModel *model,
3164                                  GtkTreeIter  *iter)
3165 {
3166   FilterLevel *level;
3167   FilterElt *elt;
3168   GSequenceIter *siter;
3169
3170   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3171   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, FALSE);
3172   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp, FALSE);
3173
3174   level = iter->user_data;
3175   elt = iter->user_data2;
3176
3177   siter = g_sequence_iter_next (elt->visible_siter);
3178   if (g_sequence_iter_is_end (siter))
3179     {
3180       iter->stamp = 0;
3181       return FALSE;
3182     }
3183
3184   iter->user_data2 = GET_ELT (siter);
3185
3186   return TRUE;
3187 }
3188
3189 static gboolean
3190 gtk_tree_model_filter_iter_previous (GtkTreeModel *model,
3191                                      GtkTreeIter  *iter)
3192 {
3193   FilterElt *elt;
3194   GSequenceIter *siter;
3195
3196   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3197   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, FALSE);
3198   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp, FALSE);
3199
3200   elt = iter->user_data2;
3201
3202   siter = g_sequence_iter_prev (elt->visible_siter);
3203   if (g_sequence_iter_is_begin (siter))
3204     {
3205       iter->stamp = 0;
3206       return FALSE;
3207     }
3208
3209   iter->user_data2 = GET_ELT (siter);
3210
3211   return TRUE;
3212 }
3213
3214 static gboolean
3215 gtk_tree_model_filter_iter_children (GtkTreeModel *model,
3216                                      GtkTreeIter  *iter,
3217                                      GtkTreeIter  *parent)
3218 {
3219   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3220   FilterLevel *level;
3221   GSequenceIter *siter;
3222
3223   iter->stamp = 0;
3224   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3225   g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
3226   if (parent)
3227     g_return_val_if_fail (filter->priv->stamp == parent->stamp, FALSE);
3228
3229   if (!parent)
3230     {
3231       if (!filter->priv->root)
3232         gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
3233       if (!filter->priv->root)
3234         return FALSE;
3235
3236       level = filter->priv->root;
3237       siter = g_sequence_get_begin_iter (level->visible_seq);
3238       if (g_sequence_iter_is_end (siter))
3239         {
3240           iter->stamp = 0;
3241           return FALSE;
3242         }
3243
3244       iter->stamp = filter->priv->stamp;
3245       iter->user_data = level;
3246       iter->user_data2 = GET_ELT (siter);
3247
3248       return TRUE;
3249     }
3250   else
3251     {
3252       if (FILTER_ELT (parent->user_data2)->children == NULL)
3253         gtk_tree_model_filter_build_level (filter,
3254                                            FILTER_LEVEL (parent->user_data),
3255                                            FILTER_ELT (parent->user_data2),
3256                                            FALSE);
3257       if (FILTER_ELT (parent->user_data2)->children == NULL)
3258         return FALSE;
3259
3260       level = FILTER_ELT (parent->user_data2)->children;
3261       siter = g_sequence_get_begin_iter (level->visible_seq);
3262       if (g_sequence_iter_is_end (siter))
3263         {
3264           iter->stamp = 0;
3265           return FALSE;
3266         }
3267
3268       iter->stamp = filter->priv->stamp;
3269       iter->user_data = level;
3270       iter->user_data2 = GET_ELT (siter);
3271
3272       return TRUE;
3273     }
3274
3275   iter->stamp = 0;
3276   return FALSE;
3277 }
3278
3279 static gboolean
3280 gtk_tree_model_filter_iter_has_child (GtkTreeModel *model,
3281                                       GtkTreeIter  *iter)
3282 {
3283   GtkTreeIter child_iter;
3284   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3285   FilterElt *elt;
3286
3287   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3288   g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
3289   g_return_val_if_fail (filter->priv->stamp == iter->stamp, FALSE);
3290
3291   filter = GTK_TREE_MODEL_FILTER (model);
3292
3293   gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, iter);
3294   elt = FILTER_ELT (iter->user_data2);
3295
3296   if (!elt->visible_siter)
3297     return FALSE;
3298
3299   /* we need to build the level to check if not all children are filtered
3300    * out
3301    */
3302   if (!elt->children
3303       && gtk_tree_model_iter_has_child (filter->priv->child_model, &child_iter))
3304     gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (iter->user_data),
3305                                        elt, FALSE);
3306
3307   if (elt->children && g_sequence_get_length (elt->children->visible_seq) > 0)
3308     return TRUE;
3309
3310   return FALSE;
3311 }
3312
3313 static gint
3314 gtk_tree_model_filter_iter_n_children (GtkTreeModel *model,
3315                                        GtkTreeIter  *iter)
3316 {
3317   GtkTreeIter child_iter;
3318   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3319   FilterElt *elt;
3320
3321   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), 0);
3322   g_return_val_if_fail (filter->priv->child_model != NULL, 0);
3323   if (iter)
3324     g_return_val_if_fail (filter->priv->stamp == iter->stamp, 0);
3325
3326   if (!iter)
3327     {
3328       if (!filter->priv->root)
3329         gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
3330
3331       if (filter->priv->root)
3332         return g_sequence_get_length (FILTER_LEVEL (filter->priv->root)->visible_seq);
3333
3334       return 0;
3335     }
3336
3337   elt = FILTER_ELT (iter->user_data2);
3338
3339   if (!elt->visible_siter)
3340     return 0;
3341
3342   gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, iter);
3343
3344   if (!elt->children &&
3345       gtk_tree_model_iter_has_child (filter->priv->child_model, &child_iter))
3346     gtk_tree_model_filter_build_level (filter,
3347                                        FILTER_LEVEL (iter->user_data),
3348                                        elt, FALSE);
3349
3350   if (elt->children)
3351     return g_sequence_get_length (elt->children->visible_seq);
3352
3353   return 0;
3354 }
3355
3356 static gboolean
3357 gtk_tree_model_filter_iter_nth_child (GtkTreeModel *model,
3358                                       GtkTreeIter  *iter,
3359                                       GtkTreeIter  *parent,
3360                                       gint          n)
3361 {
3362   FilterLevel *level;
3363   GtkTreeIter children;
3364   GSequenceIter *siter;
3365
3366   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3367   if (parent)
3368     g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == parent->stamp, FALSE);
3369
3370   /* use this instead of has_child to force us to build the level, if needed */
3371   if (gtk_tree_model_filter_iter_children (model, &children, parent) == FALSE)
3372     {
3373       iter->stamp = 0;
3374       return FALSE;
3375     }
3376
3377   level = children.user_data;
3378   siter = g_sequence_get_iter_at_pos (level->visible_seq, n);
3379   if (g_sequence_iter_is_end (siter))
3380     return FALSE;
3381
3382   iter->stamp = GTK_TREE_MODEL_FILTER (model)->priv->stamp;
3383   iter->user_data = level;
3384   iter->user_data2 = GET_ELT (siter);
3385
3386   return TRUE;
3387 }
3388
3389 static gboolean
3390 gtk_tree_model_filter_iter_parent (GtkTreeModel *model,
3391                                    GtkTreeIter  *iter,
3392                                    GtkTreeIter  *child)
3393 {
3394   FilterLevel *level;
3395
3396   iter->stamp = 0;
3397   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), FALSE);
3398   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, FALSE);
3399   g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == child->stamp, FALSE);
3400
3401   level = child->user_data;
3402
3403   if (level->parent_level)
3404     {
3405       iter->stamp = GTK_TREE_MODEL_FILTER (model)->priv->stamp;
3406       iter->user_data = level->parent_level;
3407       iter->user_data2 = level->parent_elt;
3408
3409       return TRUE;
3410     }
3411
3412   return FALSE;
3413 }
3414
3415 static void
3416 gtk_tree_model_filter_ref_node (GtkTreeModel *model,
3417                                 GtkTreeIter  *iter)
3418 {
3419   gtk_tree_model_filter_real_ref_node (model, iter, TRUE);
3420 }
3421
3422 static void
3423 gtk_tree_model_filter_real_ref_node (GtkTreeModel *model,
3424                                      GtkTreeIter  *iter,
3425                                      gboolean      external)
3426 {
3427   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3428   GtkTreeIter child_iter;
3429   FilterLevel *level;
3430   FilterElt *elt;
3431
3432   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (model));
3433   g_return_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL);
3434   g_return_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->stamp == iter->stamp);
3435
3436   gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, iter);
3437
3438   gtk_tree_model_ref_node (filter->priv->child_model, &child_iter);
3439
3440   level = iter->user_data;
3441   elt = iter->user_data2;
3442
3443   elt->ref_count++;
3444   level->ref_count++;
3445
3446   if (external)
3447     {
3448       elt->ext_ref_count++;
3449       level->ext_ref_count++;
3450
3451       if (level->ext_ref_count == 1)
3452         {
3453           FilterLevel *parent_level = level->parent_level;
3454           FilterElt *parent_elt = level->parent_elt;
3455
3456           /* we were at zero -- time to decrease the zero_ref_count val */
3457           while (parent_level)
3458             {
3459               parent_elt->zero_ref_count--;
3460
3461               parent_elt = parent_level->parent_elt;
3462               parent_level = parent_level->parent_level;
3463             }
3464
3465           if (filter->priv->root != level)
3466             filter->priv->zero_ref_count--;
3467
3468 #ifdef MODEL_FILTER_DEBUG
3469           g_assert (filter->priv->zero_ref_count >= 0);
3470 #endif
3471         }
3472     }
3473
3474 #ifdef MODEL_FILTER_DEBUG
3475   g_assert (elt->ref_count >= elt->ext_ref_count);
3476   g_assert (elt->ref_count >= 0);
3477   g_assert (elt->ext_ref_count >= 0);
3478 #endif
3479 }
3480
3481 static void
3482 gtk_tree_model_filter_unref_node (GtkTreeModel *model,
3483                                   GtkTreeIter  *iter)
3484 {
3485   gtk_tree_model_filter_real_unref_node (model, iter, TRUE, TRUE);
3486 }
3487
3488 static void
3489 gtk_tree_model_filter_real_unref_node (GtkTreeModel *model,
3490                                        GtkTreeIter  *iter,
3491                                        gboolean      external,
3492                                        gboolean      propagate_unref)
3493 {
3494   GtkTreeModelFilter *filter = (GtkTreeModelFilter *)model;
3495   FilterLevel *level;
3496   FilterElt *elt;
3497
3498   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (model));
3499   g_return_if_fail (filter->priv->child_model != NULL);
3500   g_return_if_fail (filter->priv->stamp == iter->stamp);
3501
3502   if (propagate_unref)
3503     {
3504       GtkTreeIter child_iter;
3505       gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, iter);
3506       gtk_tree_model_unref_node (filter->priv->child_model, &child_iter);
3507     }
3508
3509   level = iter->user_data;
3510   elt = iter->user_data2;
3511
3512   g_return_if_fail (elt->ref_count > 0);
3513 #ifdef MODEL_FILTER_DEBUG
3514   g_assert (elt->ref_count >= elt->ext_ref_count);
3515   g_assert (elt->ref_count >= 0);
3516   g_assert (elt->ext_ref_count >= 0);
3517 #endif
3518
3519   elt->ref_count--;
3520   level->ref_count--;
3521
3522   if (external)
3523     {
3524       elt->ext_ref_count--;
3525       level->ext_ref_count--;
3526
3527       if (level->ext_ref_count == 0)
3528         {
3529           FilterLevel *parent_level = level->parent_level;
3530           FilterElt *parent_elt = level->parent_elt;
3531
3532           /* we are at zero -- time to increase the zero_ref_count val */
3533           while (parent_level)
3534             {
3535               parent_elt->zero_ref_count++;
3536
3537               parent_elt = parent_level->parent_elt;
3538               parent_level = parent_level->parent_level;
3539             }
3540
3541           if (filter->priv->root != level)
3542             filter->priv->zero_ref_count++;
3543
3544 #ifdef MODEL_FILTER_DEBUG
3545           g_assert (filter->priv->zero_ref_count >= 0);
3546 #endif
3547         }
3548     }
3549
3550 #ifdef MODEL_FILTER_DEBUG
3551   g_assert (elt->ref_count >= elt->ext_ref_count);
3552   g_assert (elt->ref_count >= 0);
3553   g_assert (elt->ext_ref_count >= 0);
3554 #endif
3555 }
3556
3557 /* TreeDragSource interface implementation */
3558 static gboolean
3559 gtk_tree_model_filter_row_draggable (GtkTreeDragSource *drag_source,
3560                                      GtkTreePath       *path)
3561 {
3562   GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *)drag_source;
3563   GtkTreePath *child_path;
3564   gboolean draggable;
3565
3566   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (drag_source), FALSE);
3567   g_return_val_if_fail (path != NULL, FALSE);
3568
3569   child_path = gtk_tree_model_filter_convert_path_to_child_path (tree_model_filter, path);
3570   draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_filter->priv->child_model), child_path);
3571   gtk_tree_path_free (child_path);
3572
3573   return draggable;
3574 }
3575
3576 static gboolean
3577 gtk_tree_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
3578                                      GtkTreePath       *path,
3579                                      GtkSelectionData  *selection_data)
3580 {
3581   GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *)drag_source;
3582   GtkTreePath *child_path;
3583   gboolean gotten;
3584
3585   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (drag_source), FALSE);
3586   g_return_val_if_fail (path != NULL, FALSE);
3587
3588   child_path = gtk_tree_model_filter_convert_path_to_child_path (tree_model_filter, path);
3589   gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_filter->priv->child_model), child_path, selection_data);
3590   gtk_tree_path_free (child_path);
3591
3592   return gotten;
3593 }
3594
3595 static gboolean
3596 gtk_tree_model_filter_drag_data_delete (GtkTreeDragSource *drag_source,
3597                                         GtkTreePath       *path)
3598 {
3599   GtkTreeModelFilter *tree_model_filter = (GtkTreeModelFilter *)drag_source;
3600   GtkTreePath *child_path;
3601   gboolean deleted;
3602
3603   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (drag_source), FALSE);
3604   g_return_val_if_fail (path != NULL, FALSE);
3605
3606   child_path = gtk_tree_model_filter_convert_path_to_child_path (tree_model_filter, path);
3607   deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_filter->priv->child_model), child_path);
3608   gtk_tree_path_free (child_path);
3609
3610   return deleted;
3611 }
3612
3613 /* bits and pieces */
3614 static void
3615 gtk_tree_model_filter_set_model (GtkTreeModelFilter *filter,
3616                                  GtkTreeModel       *child_model)
3617 {
3618   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3619
3620   if (filter->priv->child_model)
3621     {
3622       g_signal_handler_disconnect (filter->priv->child_model,
3623                                    filter->priv->changed_id);
3624       g_signal_handler_disconnect (filter->priv->child_model,
3625                                    filter->priv->inserted_id);
3626       g_signal_handler_disconnect (filter->priv->child_model,
3627                                    filter->priv->has_child_toggled_id);
3628       g_signal_handler_disconnect (filter->priv->child_model,
3629                                    filter->priv->deleted_id);
3630       g_signal_handler_disconnect (filter->priv->child_model,
3631                                    filter->priv->reordered_id);
3632
3633       /* reset our state */
3634       if (filter->priv->root)
3635         gtk_tree_model_filter_free_level (filter, filter->priv->root,
3636                                           TRUE, FALSE);
3637
3638       filter->priv->root = NULL;
3639       g_object_unref (filter->priv->child_model);
3640       filter->priv->visible_column = -1;
3641
3642       /* FIXME: do we need to destroy more here? */
3643     }
3644
3645   filter->priv->child_model = child_model;
3646
3647   if (child_model)
3648     {
3649       g_object_ref (filter->priv->child_model);
3650       filter->priv->changed_id =
3651         g_signal_connect (child_model, "row-changed",
3652                           G_CALLBACK (gtk_tree_model_filter_row_changed),
3653                           filter);
3654       filter->priv->inserted_id =
3655         g_signal_connect (child_model, "row-inserted",
3656                           G_CALLBACK (gtk_tree_model_filter_row_inserted),
3657                           filter);
3658       filter->priv->has_child_toggled_id =
3659         g_signal_connect (child_model, "row-has-child-toggled",
3660                           G_CALLBACK (gtk_tree_model_filter_row_has_child_toggled),
3661                           filter);
3662       filter->priv->deleted_id =
3663         g_signal_connect (child_model, "row-deleted",
3664                           G_CALLBACK (gtk_tree_model_filter_row_deleted),
3665                           filter);
3666       filter->priv->reordered_id =
3667         g_signal_connect (child_model, "rows-reordered",
3668                           G_CALLBACK (gtk_tree_model_filter_rows_reordered),
3669                           filter);
3670
3671       filter->priv->child_flags = gtk_tree_model_get_flags (child_model);
3672       filter->priv->stamp = g_random_int ();
3673     }
3674 }
3675
3676 static void
3677 gtk_tree_model_filter_ref_path (GtkTreeModelFilter *filter,
3678                                 GtkTreePath        *path)
3679 {
3680   int len;
3681   GtkTreePath *p;
3682
3683   len = gtk_tree_path_get_depth (path);
3684   p = gtk_tree_path_copy (path);
3685   while (len--)
3686     {
3687       GtkTreeIter iter;
3688
3689       gtk_tree_model_get_iter (GTK_TREE_MODEL (filter->priv->child_model), &iter, p);
3690       gtk_tree_model_ref_node (GTK_TREE_MODEL (filter->priv->child_model), &iter);
3691       gtk_tree_path_up (p);
3692     }
3693
3694   gtk_tree_path_free (p);
3695 }
3696
3697 static void
3698 gtk_tree_model_filter_unref_path (GtkTreeModelFilter *filter,
3699                                   GtkTreePath        *path,
3700                                   int                 depth)
3701 {
3702   int len;
3703   GtkTreePath *p;
3704
3705   if (depth != -1)
3706     len = depth;
3707   else
3708     len = gtk_tree_path_get_depth (path);
3709
3710   p = gtk_tree_path_copy (path);
3711   while (len--)
3712     {
3713       GtkTreeIter iter;
3714
3715       gtk_tree_model_get_iter (GTK_TREE_MODEL (filter->priv->child_model), &iter, p);
3716       gtk_tree_model_unref_node (GTK_TREE_MODEL (filter->priv->child_model), &iter);
3717       gtk_tree_path_up (p);
3718     }
3719
3720   gtk_tree_path_free (p);
3721 }
3722
3723 static void
3724 gtk_tree_model_filter_set_root (GtkTreeModelFilter *filter,
3725                                 GtkTreePath        *root)
3726 {
3727   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3728
3729   if (!root)
3730     filter->priv->virtual_root = NULL;
3731   else
3732     filter->priv->virtual_root = gtk_tree_path_copy (root);
3733 }
3734
3735 /* public API */
3736
3737 /**
3738  * gtk_tree_model_filter_new:
3739  * @child_model: A #GtkTreeModel.
3740  * @root: (allow-none): A #GtkTreePath or %NULL.
3741  *
3742  * Creates a new #GtkTreeModel, with @child_model as the child_model
3743  * and @root as the virtual root.
3744  *
3745  * Return value: (transfer full): A new #GtkTreeModel.
3746  *
3747  * Since: 2.4
3748  */
3749 GtkTreeModel *
3750 gtk_tree_model_filter_new (GtkTreeModel *child_model,
3751                            GtkTreePath  *root)
3752 {
3753   GtkTreeModel *retval;
3754   GtkTreeModelFilter *filter;
3755
3756   g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
3757
3758   retval = g_object_new (GTK_TYPE_TREE_MODEL_FILTER, 
3759                          "child-model", child_model,
3760                          "virtual-root", root,
3761                          NULL);
3762
3763   filter = GTK_TREE_MODEL_FILTER (retval);
3764   if (filter->priv->virtual_root)
3765     {
3766       gtk_tree_model_filter_ref_path (filter, filter->priv->virtual_root);
3767       filter->priv->virtual_root_deleted = FALSE;
3768     }
3769
3770   return retval;
3771 }
3772
3773 /**
3774  * gtk_tree_model_filter_get_model:
3775  * @filter: A #GtkTreeModelFilter.
3776  *
3777  * Returns a pointer to the child model of @filter.
3778  *
3779  * Return value: (transfer none): A pointer to a #GtkTreeModel.
3780  *
3781  * Since: 2.4
3782  */
3783 GtkTreeModel *
3784 gtk_tree_model_filter_get_model (GtkTreeModelFilter *filter)
3785 {
3786   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), NULL);
3787
3788   return filter->priv->child_model;
3789 }
3790
3791 /**
3792  * gtk_tree_model_filter_set_visible_func:
3793  * @filter: A #GtkTreeModelFilter.
3794  * @func: A #GtkTreeModelFilterVisibleFunc, the visible function.
3795  * @data: (allow-none): User data to pass to the visible function, or %NULL.
3796  * @destroy: (allow-none): Destroy notifier of @data, or %NULL.
3797  *
3798  * Sets the visible function used when filtering the @filter to be @func. The
3799  * function should return %TRUE if the given row should be visible and
3800  * %FALSE otherwise.
3801  *
3802  * If the condition calculated by the function changes over time (e.g. because
3803  * it depends on some global parameters), you must call 
3804  * gtk_tree_model_filter_refilter() to keep the visibility information of 
3805  * the model uptodate.
3806  *
3807  * Note that @func is called whenever a row is inserted, when it may still be
3808  * empty. The visible function should therefore take special care of empty
3809  * rows, like in the example below.
3810  *
3811  * <informalexample><programlisting>
3812  * static gboolean
3813  * visible_func (GtkTreeModel *model,
3814  *               GtkTreeIter  *iter,
3815  *               gpointer      data)
3816  * {
3817  *   /&ast; Visible if row is non-empty and first column is "HI" &ast;/
3818  *   gchar *str;
3819  *   gboolean visible = FALSE;
3820  *
3821  *   gtk_tree_model_get (model, iter, 0, &str, -1);
3822  *   if (str && strcmp (str, "HI") == 0)
3823  *     visible = TRUE;
3824  *   g_free (str);
3825  *
3826  *   return visible;
3827  * }
3828  * </programlisting></informalexample>
3829  *
3830  * Since: 2.4
3831  */
3832 void
3833 gtk_tree_model_filter_set_visible_func (GtkTreeModelFilter            *filter,
3834                                         GtkTreeModelFilterVisibleFunc  func,
3835                                         gpointer                       data,
3836                                         GDestroyNotify                 destroy)
3837 {
3838   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3839   g_return_if_fail (func != NULL);
3840   g_return_if_fail (filter->priv->visible_method_set == FALSE);
3841
3842   filter->priv->visible_func = func;
3843   filter->priv->visible_data = data;
3844   filter->priv->visible_destroy = destroy;
3845
3846   filter->priv->visible_method_set = TRUE;
3847 }
3848
3849 /**
3850  * gtk_tree_model_filter_set_modify_func:
3851  * @filter: A #GtkTreeModelFilter.
3852  * @n_columns: The number of columns in the filter model.
3853  * @types: (array length=n_columns): The #GType<!-- -->s of the columns.
3854  * @func: A #GtkTreeModelFilterModifyFunc
3855  * @data: (allow-none): User data to pass to the modify function, or %NULL.
3856  * @destroy: (allow-none): Destroy notifier of @data, or %NULL.
3857  *
3858  * With the @n_columns and @types parameters, you give an array of column
3859  * types for this model (which will be exposed to the parent model/view).
3860  * The @func, @data and @destroy parameters are for specifying the modify
3861  * function. The modify function will get called for <emphasis>each</emphasis>
3862  * data access, the goal of the modify function is to return the data which 
3863  * should be displayed at the location specified using the parameters of the 
3864  * modify function.
3865  *
3866  * Since: 2.4
3867  */
3868 void
3869 gtk_tree_model_filter_set_modify_func (GtkTreeModelFilter           *filter,
3870                                        gint                          n_columns,
3871                                        GType                        *types,
3872                                        GtkTreeModelFilterModifyFunc  func,
3873                                        gpointer                      data,
3874                                        GDestroyNotify                destroy)
3875 {
3876   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3877   g_return_if_fail (func != NULL);
3878   g_return_if_fail (filter->priv->modify_func_set == FALSE);
3879
3880   if (filter->priv->modify_destroy)
3881     {
3882       GDestroyNotify d = filter->priv->modify_destroy;
3883
3884       filter->priv->modify_destroy = NULL;
3885       d (filter->priv->modify_data);
3886     }
3887
3888   filter->priv->modify_n_columns = n_columns;
3889   filter->priv->modify_types = g_new0 (GType, n_columns);
3890   memcpy (filter->priv->modify_types, types, sizeof (GType) * n_columns);
3891   filter->priv->modify_func = func;
3892   filter->priv->modify_data = data;
3893   filter->priv->modify_destroy = destroy;
3894
3895   filter->priv->modify_func_set = TRUE;
3896 }
3897
3898 /**
3899  * gtk_tree_model_filter_set_visible_column:
3900  * @filter: A #GtkTreeModelFilter.
3901  * @column: A #gint which is the column containing the visible information.
3902  *
3903  * Sets @column of the child_model to be the column where @filter should
3904  * look for visibility information. @columns should be a column of type
3905  * %G_TYPE_BOOLEAN, where %TRUE means that a row is visible, and %FALSE
3906  * if not.
3907  *
3908  * Since: 2.4
3909  */
3910 void
3911 gtk_tree_model_filter_set_visible_column (GtkTreeModelFilter *filter,
3912                                           gint column)
3913 {
3914   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3915   g_return_if_fail (column >= 0);
3916   g_return_if_fail (filter->priv->visible_method_set == FALSE);
3917
3918   filter->priv->visible_column = column;
3919
3920   filter->priv->visible_method_set = TRUE;
3921 }
3922
3923 /* conversion */
3924
3925 /**
3926  * gtk_tree_model_filter_convert_child_iter_to_iter:
3927  * @filter: A #GtkTreeModelFilter.
3928  * @filter_iter: (out): An uninitialized #GtkTreeIter.
3929  * @child_iter: A valid #GtkTreeIter pointing to a row on the child model.
3930  *
3931  * Sets @filter_iter to point to the row in @filter that corresponds to the
3932  * row pointed at by @child_iter.  If @filter_iter was not set, %FALSE is
3933  * returned.
3934  *
3935  * Return value: %TRUE, if @filter_iter was set, i.e. if @child_iter is a
3936  * valid iterator pointing to a visible row in child model.
3937  *
3938  * Since: 2.4
3939  */
3940 gboolean
3941 gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *filter,
3942                                                   GtkTreeIter        *filter_iter,
3943                                                   GtkTreeIter        *child_iter)
3944 {
3945   gboolean ret;
3946   GtkTreePath *child_path, *path;
3947
3948   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), FALSE);
3949   g_return_val_if_fail (filter->priv->child_model != NULL, FALSE);
3950   g_return_val_if_fail (filter_iter != NULL, FALSE);
3951   g_return_val_if_fail (child_iter != NULL, FALSE);
3952   g_return_val_if_fail (filter_iter != child_iter, FALSE);
3953
3954   filter_iter->stamp = 0;
3955
3956   child_path = gtk_tree_model_get_path (filter->priv->child_model, child_iter);
3957   g_return_val_if_fail (child_path != NULL, FALSE);
3958
3959   path = gtk_tree_model_filter_convert_child_path_to_path (filter,
3960                                                            child_path);
3961   gtk_tree_path_free (child_path);
3962
3963   if (!path)
3964     return FALSE;
3965
3966   ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), filter_iter, path);
3967   gtk_tree_path_free (path);
3968
3969   return ret;
3970 }
3971
3972 /**
3973  * gtk_tree_model_filter_convert_iter_to_child_iter:
3974  * @filter: A #GtkTreeModelFilter.
3975  * @child_iter: (out): An uninitialized #GtkTreeIter.
3976  * @filter_iter: A valid #GtkTreeIter pointing to a row on @filter.
3977  *
3978  * Sets @child_iter to point to the row pointed to by @filter_iter.
3979  *
3980  * Since: 2.4
3981  */
3982 void
3983 gtk_tree_model_filter_convert_iter_to_child_iter (GtkTreeModelFilter *filter,
3984                                                   GtkTreeIter        *child_iter,
3985                                                   GtkTreeIter        *filter_iter)
3986 {
3987   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
3988   g_return_if_fail (filter->priv->child_model != NULL);
3989   g_return_if_fail (child_iter != NULL);
3990   g_return_if_fail (filter_iter != NULL);
3991   g_return_if_fail (filter_iter->stamp == filter->priv->stamp);
3992   g_return_if_fail (filter_iter != child_iter);
3993
3994   if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter))
3995     {
3996       *child_iter = FILTER_ELT (filter_iter->user_data2)->iter;
3997     }
3998   else
3999     {
4000       GtkTreePath *path;
4001       gboolean valid = FALSE;
4002
4003       path = gtk_tree_model_filter_elt_get_path (filter_iter->user_data,
4004                                                  filter_iter->user_data2,
4005                                                  filter->priv->virtual_root);
4006       valid = gtk_tree_model_get_iter (filter->priv->child_model, child_iter,
4007                                        path);
4008       gtk_tree_path_free (path);
4009
4010       g_return_if_fail (valid == TRUE);
4011     }
4012 }
4013
4014 /* The path returned can only be used internally in the filter model. */
4015 static GtkTreePath *
4016 gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filter,
4017                                                        GtkTreePath        *child_path,
4018                                                        gboolean            build_levels,
4019                                                        gboolean            fetch_children)
4020 {
4021   gint *child_indices;
4022   GtkTreePath *retval;
4023   GtkTreePath *real_path;
4024   FilterLevel *level;
4025   FilterElt *tmp;
4026   gint i;
4027
4028   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), NULL);
4029   g_return_val_if_fail (filter->priv->child_model != NULL, NULL);
4030   g_return_val_if_fail (child_path != NULL, NULL);
4031
4032   if (!filter->priv->virtual_root)
4033     real_path = gtk_tree_path_copy (child_path);
4034   else
4035     real_path = gtk_tree_model_filter_remove_root (child_path,
4036                                                    filter->priv->virtual_root);
4037
4038   if (!real_path)
4039     return NULL;
4040
4041   retval = gtk_tree_path_new ();
4042   child_indices = gtk_tree_path_get_indices (real_path);
4043
4044   if (filter->priv->root == NULL && build_levels)
4045     gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
4046   level = FILTER_LEVEL (filter->priv->root);
4047
4048   for (i = 0; i < gtk_tree_path_get_depth (real_path); i++)
4049     {
4050       GSequenceIter *siter;
4051       gboolean found_child = FALSE;
4052
4053       if (!level)
4054         {
4055           gtk_tree_path_free (real_path);
4056           gtk_tree_path_free (retval);
4057           return NULL;
4058         }
4059
4060       tmp = lookup_elt_with_offset (level->seq, child_indices[i], &siter);
4061       if (tmp)
4062         {
4063           gtk_tree_path_append_index (retval, g_sequence_iter_get_position (siter));
4064           if (!tmp->children && build_levels)
4065             gtk_tree_model_filter_build_level (filter, level, tmp, FALSE);
4066           level = tmp->children;
4067           found_child = TRUE;
4068         }
4069
4070       if (!found_child && fetch_children)
4071         {
4072           int j;
4073
4074           tmp = gtk_tree_model_filter_fetch_child (filter, level,
4075                                                    child_indices[i],
4076                                                    &j);
4077
4078           /* didn't find the child, let's try to bring it back */
4079           if (!tmp || tmp->offset != child_indices[i])
4080             {
4081               /* not there */
4082               gtk_tree_path_free (real_path);
4083               gtk_tree_path_free (retval);
4084               return NULL;
4085             }
4086
4087           gtk_tree_path_append_index (retval, j);
4088           if (!tmp->children && build_levels)
4089             gtk_tree_model_filter_build_level (filter, level, tmp, FALSE);
4090           level = tmp->children;
4091           found_child = TRUE;
4092         }
4093       else if (!found_child && !fetch_children)
4094         {
4095           /* no path */
4096           gtk_tree_path_free (real_path);
4097           gtk_tree_path_free (retval);
4098           return NULL;
4099         }
4100     }
4101
4102   gtk_tree_path_free (real_path);
4103   return retval;
4104 }
4105
4106 /**
4107  * gtk_tree_model_filter_convert_child_path_to_path:
4108  * @filter: A #GtkTreeModelFilter.
4109  * @child_path: A #GtkTreePath to convert.
4110  *
4111  * Converts @child_path to a path relative to @filter. That is, @child_path
4112  * points to a path in the child model. The rerturned path will point to the
4113  * same row in the filtered model. If @child_path isn't a valid path on the
4114  * child model or points to a row which is not visible in @filter, then %NULL
4115  * is returned.
4116  *
4117  * Return value: A newly allocated #GtkTreePath, or %NULL.
4118  *
4119  * Since: 2.4
4120  */
4121 GtkTreePath *
4122 gtk_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filter,
4123                                                   GtkTreePath        *child_path)
4124 {
4125   GtkTreeIter iter;
4126   GtkTreePath *path;
4127
4128   /* this function does the sanity checks */
4129   path = gtk_real_tree_model_filter_convert_child_path_to_path (filter,
4130                                                                 child_path,
4131                                                                 TRUE,
4132                                                                 TRUE);
4133
4134   if (!path)
4135       return NULL;
4136
4137   /* get a new path which only takes visible nodes into account.
4138    * -- if this gives any performance issues, we can write a special
4139    *    version of convert_child_path_to_path immediately returning
4140    *    a visible-nodes-only path.
4141    */
4142   gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (filter), &iter, path);
4143
4144   gtk_tree_path_free (path);
4145   path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter);
4146
4147   return path;
4148 }
4149
4150 /**
4151  * gtk_tree_model_filter_convert_path_to_child_path:
4152  * @filter: A #GtkTreeModelFilter.
4153  * @filter_path: A #GtkTreePath to convert.
4154  *
4155  * Converts @filter_path to a path on the child model of @filter. That is,
4156  * @filter_path points to a location in @filter. The returned path will
4157  * point to the same location in the model not being filtered. If @filter_path
4158  * does not point to a location in the child model, %NULL is returned.
4159  *
4160  * Return value: A newly allocated #GtkTreePath, or %NULL.
4161  *
4162  * Since: 2.4
4163  */
4164 GtkTreePath *
4165 gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *filter,
4166                                                   GtkTreePath        *filter_path)
4167 {
4168   gint *filter_indices;
4169   GtkTreePath *retval;
4170   FilterLevel *level;
4171   gint i;
4172
4173   g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter), NULL);
4174   g_return_val_if_fail (filter->priv->child_model != NULL, NULL);
4175   g_return_val_if_fail (filter_path != NULL, NULL);
4176
4177   /* convert path */
4178   retval = gtk_tree_path_new ();
4179   filter_indices = gtk_tree_path_get_indices (filter_path);
4180   if (!filter->priv->root)
4181     gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE);
4182   level = FILTER_LEVEL (filter->priv->root);
4183
4184   for (i = 0; i < gtk_tree_path_get_depth (filter_path); i++)
4185     {
4186       FilterElt *elt;
4187       GSequenceIter *siter;
4188
4189       if (!level)
4190         {
4191           gtk_tree_path_free (retval);
4192           return NULL;
4193         }
4194
4195       siter = g_sequence_get_iter_at_pos (level->visible_seq, filter_indices[i]);
4196       if (g_sequence_iter_is_end (siter))
4197         {
4198           gtk_tree_path_free (retval);
4199           return NULL;
4200         }
4201
4202       elt = GET_ELT (siter);
4203       if (elt->children == NULL)
4204         gtk_tree_model_filter_build_level (filter, level, elt, FALSE);
4205
4206       gtk_tree_path_append_index (retval, elt->offset);
4207       level = elt->children;
4208     }
4209
4210   /* apply vroot */
4211
4212   if (filter->priv->virtual_root)
4213     {
4214       GtkTreePath *real_retval;
4215
4216       real_retval = gtk_tree_model_filter_add_root (retval,
4217                                                     filter->priv->virtual_root);
4218       gtk_tree_path_free (retval);
4219
4220       return real_retval;
4221     }
4222
4223   return retval;
4224 }
4225
4226 static gboolean
4227 gtk_tree_model_filter_refilter_helper (GtkTreeModel *model,
4228                                        GtkTreePath  *path,
4229                                        GtkTreeIter  *iter,
4230                                        gpointer      data)
4231 {
4232   /* evil, don't try this at home, but certainly speeds things up */
4233   gtk_tree_model_filter_row_changed (model, path, iter, data);
4234
4235   return FALSE;
4236 }
4237
4238 /**
4239  * gtk_tree_model_filter_refilter:
4240  * @filter: A #GtkTreeModelFilter.
4241  *
4242  * Emits ::row_changed for each row in the child model, which causes
4243  * the filter to re-evaluate whether a row is visible or not.
4244  *
4245  * Since: 2.4
4246  */
4247 void
4248 gtk_tree_model_filter_refilter (GtkTreeModelFilter *filter)
4249 {
4250   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
4251
4252   /* S L O W */
4253   gtk_tree_model_foreach (filter->priv->child_model,
4254                           gtk_tree_model_filter_refilter_helper,
4255                           filter);
4256 }
4257
4258 /**
4259  * gtk_tree_model_filter_clear_cache:
4260  * @filter: A #GtkTreeModelFilter.
4261  *
4262  * This function should almost never be called. It clears the @filter
4263  * of any cached iterators that haven't been reffed with
4264  * gtk_tree_model_ref_node(). This might be useful if the child model
4265  * being filtered is static (and doesn't change often) and there has been
4266  * a lot of unreffed access to nodes. As a side effect of this function,
4267  * all unreffed iters will be invalid.
4268  *
4269  * Since: 2.4
4270  */
4271 void
4272 gtk_tree_model_filter_clear_cache (GtkTreeModelFilter *filter)
4273 {
4274   g_return_if_fail (GTK_IS_TREE_MODEL_FILTER (filter));
4275
4276   if (filter->priv->zero_ref_count > 0)
4277     gtk_tree_model_filter_clear_cache_helper (filter,
4278                                               FILTER_LEVEL (filter->priv->root));
4279 }