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