]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodelsort.c
Replace GArray with GSequence in GtkTreeModelSort
[~andy/gtk] / gtk / gtktreemodelsort.c
1 /* gtktreemodelsort.c
2  * Copyright (C) 2000,2001  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  * Copyright (C) 2001,2002  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 /* NOTE: There is a potential for confusion in this code as to whether an iter,
22  * path or value refers to the GtkTreeModelSort model, or the child model being
23  * sorted.  As a convention, variables referencing the child model will have an
24  * s_ prefix before them (ie. s_iter, s_value, s_path);
25  */
26
27 /* ITER FORMAT:
28  *
29  * iter->stamp = tree_model_sort->stamp
30  * iter->user_data = SortLevel
31  * iter->user_data2 = SortElt
32  */
33
34 #include "config.h"
35 #include <string.h>
36
37 #include "gtktreemodelsort.h"
38 #include "gtktreesortable.h"
39 #include "gtktreestore.h"
40 #include "gtktreedatalist.h"
41 #include "gtkintl.h"
42 #include "gtkprivate.h"
43 #include "gtktreednd.h"
44
45
46 /**
47  * SECTION:gtktreemodelsort
48  * @Short_description: A GtkTreeModel which makes an underlying tree model sortable
49  * @Title: GtkTreeModelSort
50  * @See_also: #GtkTreeModel, #GtkListStore, #GtkTreeStore, #GtkTreeSortable, #GtkTreeModelFilter
51  *
52  * The #GtkTreeModelSort is a model which implements the #GtkTreeSortable
53  * interface.  It does not hold any data itself, but rather is created with
54  * a child model and proxies its data.  It has identical column types to
55  * this child model, and the changes in the child are propagated.  The
56  * primary purpose of this model is to provide a way to sort a different
57  * model without modifying it. Note that the sort function used by
58  * #GtkTreeModelSort is not guaranteed to be stable.
59  *
60  * The use of this is best demonstrated through an example.  In the
61  * following sample code we create two #GtkTreeView widgets each with a
62  * view of the same data.  As the model is wrapped here by a
63  * #GtkTreeModelSort, the two #GtkTreeView<!-- -->s can each sort their
64  * view of the data without affecting the other.  By contrast, if we
65  * simply put the same model in each widget, then sorting the first would
66  * sort the second.
67  *
68  * <example>
69  * <title>Using a <structname>GtkTreeModelSort</structname></title>
70  * <programlisting>
71  * {
72  *   GtkTreeView *tree_view1;
73  *   GtkTreeView *tree_view2;
74  *   GtkTreeModel *sort_model1;
75  *   GtkTreeModel *sort_model2;
76  *   GtkTreeModel *child_model;
77  *
78  *   // get the child model
79  *   child_model = get_my_model ();
80  *
81  *   // Create the first tree
82  *   sort_model1 = gtk_tree_model_sort_new_with_model (child_model);
83  *   tree_view1 = gtk_tree_view_new_with_model (sort_model1);
84  *
85  *   // Create the second tree
86  *   sort_model2 = gtk_tree_model_sort_new_with_model (child_model);
87  *   tree_view2 = gtk_tree_view_new_with_model (sort_model2);
88  *
89  *   // Now we can sort the two models independently
90  *   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model1),
91  *                                         COLUMN_1, GTK_SORT_ASCENDING);
92  *   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model2),
93  *                                         COLUMN_1, GTK_SORT_DESCENDING);
94  * }
95  * </programlisting>
96  * </example>
97  *
98  * To demonstrate how to access the underlying child model from the sort
99  * model, the next example will be a callback for the #GtkTreeSelection
100  * #GtkTreeSelection::changed signal.  In this callback, we get a string
101  * from COLUMN_1 of the model.  We then modify the string, find the same
102  * selected row on the child model, and change the row there.
103  *
104  * <example>
105  * <title>Accessing the child model of in a selection changed callback</title>
106  * <programlisting>
107  * void
108  * selection_changed (GtkTreeSelection *selection, gpointer data)
109  * {
110  *   GtkTreeModel *sort_model = NULL;
111  *   GtkTreeModel *child_model;
112  *   GtkTreeIter sort_iter;
113  *   GtkTreeIter child_iter;
114  *   char *some_data = NULL;
115  *   char *modified_data;
116  *
117  *   // Get the current selected row and the model.
118  *   if (! gtk_tree_selection_get_selected (selection,
119  *                                          &sort_model,
120  *                                          &sort_iter))
121  *     return;
122  *
123  *   /<!---->* Look up the current value on the selected row and get a new value
124  *    * to change it to.
125  *    *<!---->/
126  *   gtk_tree_model_get (GTK_TREE_MODEL (sort_model), &sort_iter,
127  *                       COLUMN_1, &some_data,
128  *                       -1);
129  *
130  *   modified_data = change_the_data (some_data);
131  *   g_free (some_data);
132  *
133  *   // Get an iterator on the child model, instead of the sort model.
134  *   gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (sort_model),
135  *                                                   &child_iter,
136  *                                                   &sort_iter);
137  *
138  *   /<!---->* Get the child model and change the value of the row.  In this
139  *    * example, the child model is a GtkListStore.  It could be any other
140  *    * type of model, though.
141  *    *<!---->/
142  *   child_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
143  *   gtk_list_store_set (GTK_LIST_STORE (child_model), &child_iter,
144  *                       COLUMN_1, &modified_data,
145  *                       -1);
146  *   g_free (modified_data);
147  * }
148  * </programlisting>
149  * </example>
150  */
151
152
153 typedef struct _SortElt SortElt;
154 typedef struct _SortLevel SortLevel;
155 typedef struct _SortData SortData;
156
157 struct _SortElt
158 {
159   GtkTreeIter    iter;
160   SortLevel     *children;
161   gint           offset;
162   gint           ref_count;
163   gint           zero_ref_count;
164   GSequenceIter *siter; /* iter into seq */
165   gint           old_index; /* used while sorting */
166 };
167
168 struct _SortLevel
169 {
170   GSequence *seq;
171   gint       ref_count;
172   SortElt   *parent_elt;
173   SortLevel *parent_level;
174 };
175
176 struct _SortData
177 {
178   GtkTreeModelSort *tree_model_sort;
179   GtkTreeIterCompareFunc sort_func;
180   gpointer sort_data;
181
182   GtkTreePath *parent_path;
183   gint parent_path_depth;
184   gint *parent_path_indices;
185 };
186
187 /* Properties */
188 enum {
189   PROP_0,
190   /* Construct args */
191   PROP_MODEL
192 };
193
194
195 struct _GtkTreeModelSortPrivate
196 {
197   gpointer root;
198   gint stamp;
199   guint child_flags;
200   GtkTreeModel *child_model;
201   gint zero_ref_count;
202
203   /* sort information */
204   GList *sort_list;
205   gint sort_column_id;
206   GtkSortType order;
207
208   /* default sort */
209   GtkTreeIterCompareFunc default_sort_func;
210   gpointer default_sort_data;
211   GDestroyNotify default_sort_destroy;
212
213   /* signal ids */
214   gulong changed_id;
215   gulong inserted_id;
216   gulong has_child_toggled_id;
217   gulong deleted_id;
218   gulong reordered_id;
219 };
220
221 /* Set this to 0 to disable caching of child iterators.  This
222  * allows for more stringent testing.  It is recommended to set this
223  * to one when refactoring this code and running the unit tests to
224  * catch more errors.
225  */
226 #if 1
227 #  define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) \
228         (((GtkTreeModelSort *)tree_model_sort)->priv->child_flags&GTK_TREE_MODEL_ITERS_PERSIST)
229 #else
230 #  define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) (FALSE)
231 #endif
232
233 #define SORT_ELT(sort_elt) ((SortElt *)sort_elt)
234 #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level)
235 #define GET_ELT(siter) ((SortElt *) (siter ? g_sequence_get (siter) : NULL))
236
237
238 #define GET_CHILD_ITER(tree_model_sort,ch_iter,so_iter) gtk_tree_model_sort_convert_iter_to_child_iter((GtkTreeModelSort*)(tree_model_sort), (ch_iter), (so_iter));
239
240 #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1)
241
242 #define VALID_ITER(iter, tree_model_sort) ((iter) != NULL && (iter)->user_data != NULL && (iter)->user_data2 != NULL && (tree_model_sort)->priv->stamp == (iter)->stamp)
243
244 /* general (object/interface init, etc) */
245 static void gtk_tree_model_sort_tree_model_init       (GtkTreeModelIface     *iface);
246 static void gtk_tree_model_sort_tree_sortable_init    (GtkTreeSortableIface  *iface);
247 static void gtk_tree_model_sort_drag_source_init      (GtkTreeDragSourceIface*iface);
248 static void gtk_tree_model_sort_finalize              (GObject               *object);
249 static void gtk_tree_model_sort_set_property          (GObject               *object,
250                                                        guint                  prop_id,
251                                                        const GValue          *value,
252                                                        GParamSpec            *pspec);
253 static void gtk_tree_model_sort_get_property          (GObject               *object,
254                                                        guint                  prop_id,
255                                                        GValue                *value,
256                                                        GParamSpec            *pspec);
257
258 /* our signal handlers */
259 static void gtk_tree_model_sort_row_changed           (GtkTreeModel          *model,
260                                                        GtkTreePath           *start_path,
261                                                        GtkTreeIter           *start_iter,
262                                                        gpointer               data);
263 static void gtk_tree_model_sort_row_inserted          (GtkTreeModel          *model,
264                                                        GtkTreePath           *path,
265                                                        GtkTreeIter           *iter,
266                                                        gpointer               data);
267 static void gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel          *model,
268                                                        GtkTreePath           *path,
269                                                        GtkTreeIter           *iter,
270                                                        gpointer               data);
271 static void gtk_tree_model_sort_row_deleted           (GtkTreeModel          *model,
272                                                        GtkTreePath           *path,
273                                                        gpointer               data);
274 static void gtk_tree_model_sort_rows_reordered        (GtkTreeModel          *s_model,
275                                                        GtkTreePath           *s_path,
276                                                        GtkTreeIter           *s_iter,
277                                                        gint                  *new_order,
278                                                        gpointer               data);
279
280 /* TreeModel interface */
281 static GtkTreeModelFlags gtk_tree_model_sort_get_flags     (GtkTreeModel          *tree_model);
282 static gint         gtk_tree_model_sort_get_n_columns      (GtkTreeModel          *tree_model);
283 static GType        gtk_tree_model_sort_get_column_type    (GtkTreeModel          *tree_model,
284                                                             gint                   index);
285 static gboolean     gtk_tree_model_sort_get_iter           (GtkTreeModel          *tree_model,
286                                                             GtkTreeIter           *iter,
287                                                             GtkTreePath           *path);
288 static GtkTreePath *gtk_tree_model_sort_get_path           (GtkTreeModel          *tree_model,
289                                                             GtkTreeIter           *iter);
290 static void         gtk_tree_model_sort_get_value          (GtkTreeModel          *tree_model,
291                                                             GtkTreeIter           *iter,
292                                                             gint                   column,
293                                                             GValue                *value);
294 static gboolean     gtk_tree_model_sort_iter_next          (GtkTreeModel          *tree_model,
295                                                             GtkTreeIter           *iter);
296 static gboolean     gtk_tree_model_sort_iter_previous      (GtkTreeModel          *tree_model,
297                                                             GtkTreeIter           *iter);
298 static gboolean     gtk_tree_model_sort_iter_children      (GtkTreeModel          *tree_model,
299                                                             GtkTreeIter           *iter,
300                                                             GtkTreeIter           *parent);
301 static gboolean     gtk_tree_model_sort_iter_has_child     (GtkTreeModel          *tree_model,
302                                                             GtkTreeIter           *iter);
303 static gint         gtk_tree_model_sort_iter_n_children    (GtkTreeModel          *tree_model,
304                                                             GtkTreeIter           *iter);
305 static gboolean     gtk_tree_model_sort_iter_nth_child     (GtkTreeModel          *tree_model,
306                                                             GtkTreeIter           *iter,
307                                                             GtkTreeIter           *parent,
308                                                             gint                   n);
309 static gboolean     gtk_tree_model_sort_iter_parent        (GtkTreeModel          *tree_model,
310                                                             GtkTreeIter           *iter,
311                                                             GtkTreeIter           *child);
312 static void         gtk_tree_model_sort_ref_node           (GtkTreeModel          *tree_model,
313                                                             GtkTreeIter           *iter);
314 static void         gtk_tree_model_sort_real_unref_node    (GtkTreeModel          *tree_model,
315                                                             GtkTreeIter           *iter,
316                                                             gboolean               propagate_unref);
317 static void         gtk_tree_model_sort_unref_node         (GtkTreeModel          *tree_model,
318                                                             GtkTreeIter           *iter);
319
320 /* TreeDragSource interface */
321 static gboolean     gtk_tree_model_sort_row_draggable         (GtkTreeDragSource      *drag_source,
322                                                                GtkTreePath            *path);
323 static gboolean     gtk_tree_model_sort_drag_data_get         (GtkTreeDragSource      *drag_source,
324                                                                GtkTreePath            *path,
325                                                                GtkSelectionData       *selection_data);
326 static gboolean     gtk_tree_model_sort_drag_data_delete      (GtkTreeDragSource      *drag_source,
327                                                                GtkTreePath            *path);
328
329 /* TreeSortable interface */
330 static gboolean     gtk_tree_model_sort_get_sort_column_id    (GtkTreeSortable        *sortable,
331                                                                gint                   *sort_column_id,
332                                                                GtkSortType            *order);
333 static void         gtk_tree_model_sort_set_sort_column_id    (GtkTreeSortable        *sortable,
334                                                                gint                    sort_column_id,
335                                                                GtkSortType        order);
336 static void         gtk_tree_model_sort_set_sort_func         (GtkTreeSortable        *sortable,
337                                                                gint                    sort_column_id,
338                                                                GtkTreeIterCompareFunc  func,
339                                                                gpointer                data,
340                                                                GDestroyNotify          destroy);
341 static void         gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable        *sortable,
342                                                                GtkTreeIterCompareFunc  func,
343                                                                gpointer                data,
344                                                                GDestroyNotify          destroy);
345 static gboolean     gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable     *sortable);
346
347 /* Private functions (sort funcs, level handling and other utils) */
348 static void         gtk_tree_model_sort_build_level       (GtkTreeModelSort *tree_model_sort,
349                                                            SortLevel        *parent_level,
350                                                            SortElt          *parent_elt);
351 static void         gtk_tree_model_sort_free_level        (GtkTreeModelSort *tree_model_sort,
352                                                            SortLevel        *sort_level,
353                                                            gboolean          unref);
354 static void         gtk_tree_model_sort_increment_stamp   (GtkTreeModelSort *tree_model_sort);
355 static void         gtk_tree_model_sort_sort_level        (GtkTreeModelSort *tree_model_sort,
356                                                            SortLevel        *level,
357                                                            gboolean          recurse,
358                                                            gboolean          emit_reordered);
359 static void         gtk_tree_model_sort_sort              (GtkTreeModelSort *tree_model_sort);
360 static gboolean     gtk_tree_model_sort_insert_value      (GtkTreeModelSort *tree_model_sort,
361                                                            SortLevel        *level,
362                                                            GtkTreePath      *s_path,
363                                                            GtkTreeIter      *s_iter);
364 static GtkTreePath *gtk_tree_model_sort_elt_get_path      (SortLevel        *level,
365                                                            SortElt          *elt);
366 static void         gtk_tree_model_sort_set_model         (GtkTreeModelSort *tree_model_sort,
367                                                            GtkTreeModel     *child_model);
368 static GtkTreePath *gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
369                                                                          GtkTreePath      *child_path,
370                                                                          gboolean          build_levels);
371
372 static gint         gtk_tree_model_sort_compare_func        (gconstpointer     a,
373                                                              gconstpointer     b,
374                                                              gpointer          user_data);
375 static gint         gtk_tree_model_sort_offset_compare_func (gconstpointer     a,
376                                                              gconstpointer     b,
377                                                              gpointer          user_data);
378 static void         gtk_tree_model_sort_clear_cache_helper  (GtkTreeModelSort *tree_model_sort,
379                                                              SortLevel        *level);
380
381
382 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelSort, gtk_tree_model_sort, G_TYPE_OBJECT,
383                          G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
384                                                 gtk_tree_model_sort_tree_model_init)
385                          G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
386                                                 gtk_tree_model_sort_tree_sortable_init)
387                          G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
388                                                 gtk_tree_model_sort_drag_source_init))
389
390 static void
391 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
392 {
393   GtkTreeModelSortPrivate *priv;
394
395   priv = G_TYPE_INSTANCE_GET_PRIVATE (tree_model_sort,
396                                       GTK_TYPE_TREE_MODEL_SORT,
397                                       GtkTreeModelSortPrivate);
398   tree_model_sort->priv = priv;
399   priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
400   priv->stamp = 0;
401   priv->zero_ref_count = 0;
402   priv->root = NULL;
403   priv->sort_list = NULL;
404 }
405
406 static void
407 gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
408 {
409   GObjectClass *object_class;
410
411   object_class = (GObjectClass *) class;
412
413   object_class->set_property = gtk_tree_model_sort_set_property;
414   object_class->get_property = gtk_tree_model_sort_get_property;
415
416   object_class->finalize = gtk_tree_model_sort_finalize;
417
418   /* Properties */
419   g_object_class_install_property (object_class,
420                                    PROP_MODEL,
421                                    g_param_spec_object ("model",
422                                                         P_("TreeModelSort Model"),
423                                                         P_("The model for the TreeModelSort to sort"),
424                                                         GTK_TYPE_TREE_MODEL,
425                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
426
427   g_type_class_add_private (class, sizeof (GtkTreeModelSortPrivate));
428 }
429
430 static void
431 gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
432 {
433   iface->get_flags = gtk_tree_model_sort_get_flags;
434   iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
435   iface->get_column_type = gtk_tree_model_sort_get_column_type;
436   iface->get_iter = gtk_tree_model_sort_get_iter;
437   iface->get_path = gtk_tree_model_sort_get_path;
438   iface->get_value = gtk_tree_model_sort_get_value;
439   iface->iter_next = gtk_tree_model_sort_iter_next;
440   iface->iter_previous = gtk_tree_model_sort_iter_previous;
441   iface->iter_children = gtk_tree_model_sort_iter_children;
442   iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
443   iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
444   iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
445   iface->iter_parent = gtk_tree_model_sort_iter_parent;
446   iface->ref_node = gtk_tree_model_sort_ref_node;
447   iface->unref_node = gtk_tree_model_sort_unref_node;
448 }
449
450 static void
451 gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
452 {
453   iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
454   iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
455   iface->set_sort_func = gtk_tree_model_sort_set_sort_func;
456   iface->set_default_sort_func = gtk_tree_model_sort_set_default_sort_func;
457   iface->has_default_sort_func = gtk_tree_model_sort_has_default_sort_func;
458 }
459
460 static void
461 gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface *iface)
462 {
463   iface->row_draggable = gtk_tree_model_sort_row_draggable;
464   iface->drag_data_delete = gtk_tree_model_sort_drag_data_delete;
465   iface->drag_data_get = gtk_tree_model_sort_drag_data_get;
466 }
467
468 /**
469  * gtk_tree_model_sort_new_with_model:
470  * @child_model: A #GtkTreeModel
471  *
472  * Creates a new #GtkTreeModel, with @child_model as the child model.
473  *
474  * Return value: (transfer full): A new #GtkTreeModel.
475  */
476 GtkTreeModel *
477 gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model)
478 {
479   GtkTreeModel *retval;
480
481   g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
482
483   retval = g_object_new (gtk_tree_model_sort_get_type (), NULL);
484
485   gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
486
487   return retval;
488 }
489
490 /* GObject callbacks */
491 static void
492 gtk_tree_model_sort_finalize (GObject *object)
493 {
494   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
495   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
496
497   gtk_tree_model_sort_set_model (tree_model_sort, NULL);
498
499   if (priv->root)
500     gtk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE);
501
502   if (priv->sort_list)
503     {
504       _gtk_tree_data_list_header_free (priv->sort_list);
505       priv->sort_list = NULL;
506     }
507
508   if (priv->default_sort_destroy)
509     {
510       priv->default_sort_destroy (priv->default_sort_data);
511       priv->default_sort_destroy = NULL;
512       priv->default_sort_data = NULL;
513     }
514
515
516   /* must chain up */
517   G_OBJECT_CLASS (gtk_tree_model_sort_parent_class)->finalize (object);
518 }
519
520 static void
521 gtk_tree_model_sort_set_property (GObject      *object,
522                                   guint         prop_id,
523                                   const GValue *value,
524                                   GParamSpec   *pspec)
525 {
526   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
527
528   switch (prop_id)
529     {
530     case PROP_MODEL:
531       gtk_tree_model_sort_set_model (tree_model_sort, g_value_get_object (value));
532       break;
533     default:
534       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
535       break;
536     }
537 }
538
539 static void
540 gtk_tree_model_sort_get_property (GObject    *object,
541                                   guint       prop_id,
542                                   GValue     *value,
543                                   GParamSpec *pspec)
544 {
545   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
546
547   switch (prop_id)
548     {
549     case PROP_MODEL:
550       g_value_set_object (value, gtk_tree_model_sort_get_model (tree_model_sort));
551       break;
552     default:
553       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
554       break;
555     }
556 }
557
558 /* helpers */
559 static SortElt *
560 sort_elt_new (void)
561 {
562   return g_slice_new (SortElt);
563 }
564
565 static void
566 sort_elt_free (gpointer elt)
567 {
568   g_slice_free (SortElt, elt);
569 }
570
571 static void
572 increase_offset_iter (gpointer data,
573                       gpointer user_data)
574 {
575   SortElt *elt = data;
576   gint offset = GPOINTER_TO_INT (user_data);
577
578   if (elt->offset >= offset)
579     elt->offset++;
580 }
581
582 static void
583 decrease_offset_iter (gpointer data,
584                       gpointer user_data)
585 {
586   SortElt *elt = data;
587   gint offset = GPOINTER_TO_INT (user_data);
588
589   if (elt->offset > offset)
590     elt->offset--;
591 }
592
593 static void
594 fill_sort_data (SortData         *data,
595                 GtkTreeModelSort *tree_model_sort,
596                 SortLevel        *level)
597 {
598   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
599
600   data->tree_model_sort = tree_model_sort;
601
602   if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
603     {
604       GtkTreeDataSortHeader *header;
605       
606       header = _gtk_tree_data_list_get_header (priv->sort_list,
607                                                priv->sort_column_id);
608       
609       g_return_if_fail (header != NULL);
610       g_return_if_fail (header->func != NULL);
611       
612       data->sort_func = header->func;
613       data->sort_data = header->data;
614     }
615   else
616     {
617       /* absolutely SHOULD NOT happen: */
618       g_return_if_fail (priv->default_sort_func != NULL);
619
620       data->sort_func = priv->default_sort_func;
621       data->sort_data = priv->default_sort_data;
622     }
623
624   if (level->parent_elt)
625     {
626       data->parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level,
627                                                             level->parent_elt);
628       gtk_tree_path_append_index (data->parent_path, 0);
629     }
630   else
631     {
632       data->parent_path = gtk_tree_path_new_first ();
633     }
634   data->parent_path_depth = gtk_tree_path_get_depth (data->parent_path);
635   data->parent_path_indices = gtk_tree_path_get_indices (data->parent_path);
636 }
637
638 static void
639 free_sort_data (SortData *data)
640 {
641   gtk_tree_path_free (data->parent_path);
642 }
643
644 static SortElt *
645 lookup_elt_with_offset (GtkTreeModelSort *tree_model_sort,
646                         SortLevel        *level,
647                         gint              offset,
648                         GSequenceIter   **ret_siter)
649 {
650   GSequenceIter *siter, *end_siter;
651
652   /* FIXME: We have to do a search like this, because the sequence is not
653    * (always) sorted on offset order.  Perhaps we should introduce a
654    * second sequence which is sorted on offset order.
655    */
656   end_siter = g_sequence_get_end_iter (level->seq);
657   for (siter = g_sequence_get_begin_iter (level->seq);
658        siter != end_siter;
659        siter = g_sequence_iter_next (siter))
660     {
661       SortElt *elt = g_sequence_get (siter);
662
663       if (elt->offset == offset)
664         break;
665     }
666
667   if (ret_siter)
668     *ret_siter = siter;
669
670   return GET_ELT (siter);
671 }
672
673
674 static void
675 gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
676                                  GtkTreePath  *start_s_path,
677                                  GtkTreeIter  *start_s_iter,
678                                  gpointer      data)
679 {
680   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
681   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
682   GtkTreePath *path = NULL;
683   GtkTreeIter iter;
684   GtkTreeIter tmpiter;
685
686   SortElt *elt;
687   SortLevel *level;
688   SortData sort_data;
689
690   gboolean free_s_path = FALSE;
691
692   gint index = 0, old_index;
693
694   g_return_if_fail (start_s_path != NULL || start_s_iter != NULL);
695
696   if (!start_s_path)
697     {
698       free_s_path = TRUE;
699       start_s_path = gtk_tree_model_get_path (s_model, start_s_iter);
700     }
701
702   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
703                                                               start_s_path,
704                                                               FALSE);
705   if (!path)
706     {
707       if (free_s_path)
708         gtk_tree_path_free (start_s_path);
709       return;
710     }
711
712   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
713   gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (data), &iter);
714
715   level = iter.user_data;
716   elt = iter.user_data2;
717
718   if (g_sequence_get_length (level->seq) < 2 ||
719       (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
720        priv->default_sort_func == NO_SORT_FUNC))
721     {
722       if (free_s_path)
723         gtk_tree_path_free (start_s_path);
724
725       gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
726       gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
727
728       gtk_tree_path_free (path);
729
730       return;
731     }
732
733   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
734     tmpiter = elt->iter;
735   else
736     gtk_tree_model_get_iter (priv->child_model,
737                              &tmpiter, start_s_path);
738
739   old_index = g_sequence_iter_get_position (elt->siter);
740
741   fill_sort_data (&sort_data, tree_model_sort, level);
742   g_sequence_sort_changed (elt->siter,
743                            gtk_tree_model_sort_compare_func,
744                            &sort_data);
745   free_sort_data (&sort_data);
746
747   index = g_sequence_iter_get_position (elt->siter);
748
749   /* Prepare the path for signal emission */
750   gtk_tree_path_up (path);
751   gtk_tree_path_append_index (path, index);
752
753   gtk_tree_model_sort_increment_stamp (tree_model_sort);
754
755   /* if the item moved, then emit rows_reordered */
756   if (old_index != index)
757     {
758       gint *new_order;
759       gint j;
760
761       GtkTreePath *tmppath;
762
763       new_order = g_new (gint, g_sequence_get_length (level->seq));
764
765       for (j = 0; j < g_sequence_get_length (level->seq); j++)
766         {
767           if (index > old_index)
768             {
769               if (j == index)
770                 new_order[j] = old_index;
771               else if (j >= old_index && j < index)
772                 new_order[j] = j + 1;
773               else
774                 new_order[j] = j;
775             }
776           else if (index < old_index)
777             {
778               if (j == index)
779                 new_order[j] = old_index;
780               else if (j > index && j <= old_index)
781                 new_order[j] = j - 1;
782               else
783                 new_order[j] = j;
784             }
785           /* else? shouldn't really happen */
786         }
787
788       if (level->parent_elt)
789         {
790           iter.stamp = priv->stamp;
791           iter.user_data = level->parent_level;
792           iter.user_data2 = level->parent_elt;
793
794           tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter);
795
796           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
797                                          tmppath, &iter, new_order);
798         }
799       else
800         {
801           /* toplevel */
802           tmppath = gtk_tree_path_new ();
803
804           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), tmppath,
805                                          NULL, new_order);
806         }
807
808       gtk_tree_path_free (tmppath);
809       g_free (new_order);
810     }
811
812   /* emit row_changed signal (at new location) */
813   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
814   gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
815   gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
816
817   gtk_tree_path_free (path);
818   if (free_s_path)
819     gtk_tree_path_free (start_s_path);
820 }
821
822 static void
823 gtk_tree_model_sort_row_inserted (GtkTreeModel          *s_model,
824                                   GtkTreePath           *s_path,
825                                   GtkTreeIter           *s_iter,
826                                   gpointer               data)
827 {
828   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
829   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
830   GtkTreePath *path;
831   GtkTreeIter iter;
832   GtkTreeIter real_s_iter;
833
834   gint i = 0;
835
836   gboolean free_s_path = FALSE;
837
838   SortElt *elt;
839   SortLevel *level;
840   SortLevel *parent_level = NULL;
841
842   parent_level = level = SORT_LEVEL (priv->root);
843
844   g_return_if_fail (s_path != NULL || s_iter != NULL);
845
846   if (!s_path)
847     {
848       s_path = gtk_tree_model_get_path (s_model, s_iter);
849       free_s_path = TRUE;
850     }
851
852   if (!s_iter)
853     gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
854   else
855     real_s_iter = *s_iter;
856
857   if (!priv->root)
858     {
859       gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
860
861       /* the build level already put the inserted iter in the level,
862          so no need to handle this signal anymore */
863
864       goto done_and_submit;
865     }
866
867   /* find the parent level */
868   while (i < gtk_tree_path_get_depth (s_path) - 1)
869     {
870       if (!level)
871         {
872           /* level not yet build, we won't cover this signal */
873           goto done;
874         }
875
876       if (g_sequence_get_length (level->seq) < gtk_tree_path_get_indices (s_path)[i])
877         {
878           g_warning ("%s: A node was inserted with a parent that's not in the tree.\n"
879                      "This possibly means that a GtkTreeModel inserted a child node\n"
880                      "before the parent was inserted.",
881                      G_STRLOC);
882           goto done;
883         }
884
885       elt = lookup_elt_with_offset (tree_model_sort, level,
886                                     gtk_tree_path_get_indices (s_path)[i],
887                                     NULL);
888
889       g_return_if_fail (elt != NULL);
890
891       if (!elt->children)
892         {
893           /* not covering this signal */
894           goto done;
895         }
896
897       level = elt->children;
898       parent_level = level;
899       i++;
900     }
901
902   if (!parent_level)
903     goto done;
904
905   if (level->ref_count == 0 && level != priv->root)
906     {
907       gtk_tree_model_sort_free_level (tree_model_sort, level, TRUE);
908       goto done;
909     }
910
911   if (!gtk_tree_model_sort_insert_value (tree_model_sort,
912                                          parent_level,
913                                          s_path,
914                                          &real_s_iter))
915     goto done;
916
917  done_and_submit:
918   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
919                                                               s_path,
920                                                               FALSE);
921
922   if (!path)
923     return;
924
925   gtk_tree_model_sort_increment_stamp (tree_model_sort);
926
927   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
928   gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
929   gtk_tree_path_free (path);
930
931  done:
932   if (free_s_path)
933     gtk_tree_path_free (s_path);
934
935   return;
936 }
937
938 static void
939 gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
940                                            GtkTreePath  *s_path,
941                                            GtkTreeIter  *s_iter,
942                                            gpointer      data)
943 {
944   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
945   GtkTreePath *path;
946   GtkTreeIter iter;
947
948   g_return_if_fail (s_path != NULL && s_iter != NULL);
949
950   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
951   if (path == NULL)
952     return;
953
954   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
955   gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
956
957   gtk_tree_path_free (path);
958 }
959
960 static void
961 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
962                                  GtkTreePath  *s_path,
963                                  gpointer      data)
964 {
965   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
966   GtkTreePath *path = NULL;
967   SortElt *elt;
968   SortLevel *level;
969   GtkTreeIter iter;
970   gint offset;
971
972   g_return_if_fail (s_path != NULL);
973
974   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
975   if (path == NULL)
976     return;
977
978   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
979
980   level = SORT_LEVEL (iter.user_data);
981   elt = SORT_ELT (iter.user_data2);
982   offset = elt->offset;
983
984   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
985
986   while (elt->ref_count > 0)
987     gtk_tree_model_sort_real_unref_node (GTK_TREE_MODEL (data), &iter, FALSE);
988
989   /* If this node has children, we free the level (recursively) here
990    * and specify that unref may not be used, because parent and its
991    * children have been removed by now.
992    */
993   if (elt->children)
994     gtk_tree_model_sort_free_level (tree_model_sort,
995                                     elt->children, FALSE);
996
997   if (level->ref_count == 0)
998     {
999       gtk_tree_model_sort_increment_stamp (tree_model_sort);
1000       gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
1001       gtk_tree_path_free (path);
1002
1003       if (level == tree_model_sort->priv->root)
1004         {
1005           gtk_tree_model_sort_free_level (tree_model_sort,
1006                                           tree_model_sort->priv->root,
1007                                           TRUE);
1008           tree_model_sort->priv->root = NULL;
1009         }
1010       return;
1011     }
1012
1013   g_sequence_remove (elt->siter);
1014   elt = NULL;
1015
1016   /* The sequence is not ordered on offset, so we traverse the entire
1017    * sequence.
1018    */
1019   g_sequence_foreach (level->seq, decrease_offset_iter,
1020                       GINT_TO_POINTER (offset));
1021
1022   gtk_tree_model_sort_increment_stamp (tree_model_sort);
1023   gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
1024
1025   gtk_tree_path_free (path);
1026 }
1027
1028 static void
1029 gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
1030                                     GtkTreePath  *s_path,
1031                                     GtkTreeIter  *s_iter,
1032                                     gint         *new_order,
1033                                     gpointer      data)
1034 {
1035   SortElt *elt;
1036   SortLevel *level;
1037   GtkTreeIter iter;
1038   gint *tmp_array;
1039   int i, length;
1040   GtkTreePath *path;
1041   GSequenceIter *siter, *end_siter;
1042   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
1043   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1044
1045   g_return_if_fail (new_order != NULL);
1046
1047   if (s_path == NULL || gtk_tree_path_get_depth (s_path) == 0)
1048     {
1049       if (priv->root == NULL)
1050         return;
1051       path = gtk_tree_path_new ();
1052       level = SORT_LEVEL (priv->root);
1053     }
1054   else
1055     {
1056       path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
1057       if (path == NULL)
1058         return;
1059       gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
1060
1061       level = SORT_LEVEL (iter.user_data);
1062       elt = SORT_ELT (iter.user_data2);
1063
1064       if (!elt->children)
1065         {
1066           gtk_tree_path_free (path);
1067           return;
1068         }
1069
1070       level = elt->children;
1071     }
1072
1073   length = g_sequence_get_length (level->seq);
1074   if (length < 2)
1075     {
1076       gtk_tree_path_free (path);
1077       return;
1078     }
1079
1080   tmp_array = g_new (int, length);
1081
1082   /* FIXME: I need to think about whether this can be done in a more
1083    * efficient way?
1084    */
1085   i = 0;
1086   end_siter = g_sequence_get_end_iter (level->seq);
1087   for (siter = g_sequence_get_begin_iter (level->seq);
1088        siter != end_siter;
1089        siter = g_sequence_iter_next (siter))
1090     {
1091       gint j;
1092       SortElt *elt = g_sequence_get (siter);
1093
1094       for (j = 0; j < length; j++)
1095         {
1096           if (elt->offset == new_order[j])
1097             tmp_array[i] = j;
1098         }
1099
1100       i++;
1101     }
1102
1103   /* This loop cannot be merged with the above loop nest, because that
1104    * would introduce duplicate offsets.
1105    */
1106   i = 0;
1107   end_siter = g_sequence_get_end_iter (level->seq);
1108   for (siter = g_sequence_get_begin_iter (level->seq);
1109        siter != end_siter;
1110        siter = g_sequence_iter_next (siter))
1111     {
1112       SortElt *elt = g_sequence_get (siter);
1113
1114       elt->offset = tmp_array[i];
1115       i++;
1116     }
1117   g_free (tmp_array);
1118
1119   if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
1120       priv->default_sort_func == NO_SORT_FUNC)
1121     {
1122       gtk_tree_model_sort_sort_level (tree_model_sort, level,
1123                                       FALSE, FALSE);
1124       gtk_tree_model_sort_increment_stamp (tree_model_sort);
1125
1126       if (gtk_tree_path_get_depth (path))
1127         {
1128           gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
1129                                    &iter,
1130                                    path);
1131           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1132                                          path, &iter, new_order);
1133         }
1134       else
1135         {
1136           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1137                                          path, NULL, new_order);
1138         }
1139     }
1140
1141   gtk_tree_path_free (path);
1142 }
1143
1144 /* Fulfill our model requirements */
1145 static GtkTreeModelFlags
1146 gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model)
1147 {
1148   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1149   GtkTreeModelFlags flags;
1150
1151   g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, 0);
1152
1153   flags = gtk_tree_model_get_flags (tree_model_sort->priv->child_model);
1154
1155   if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
1156     return GTK_TREE_MODEL_LIST_ONLY;
1157
1158   return 0;
1159 }
1160
1161 static gint
1162 gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
1163 {
1164   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1165
1166   if (tree_model_sort->priv->child_model == 0)
1167     return 0;
1168
1169   return gtk_tree_model_get_n_columns (tree_model_sort->priv->child_model);
1170 }
1171
1172 static GType
1173 gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
1174                                      gint          index)
1175 {
1176   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1177
1178   g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, G_TYPE_INVALID);
1179
1180   return gtk_tree_model_get_column_type (tree_model_sort->priv->child_model, index);
1181 }
1182
1183 static gboolean
1184 gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
1185                               GtkTreeIter  *iter,
1186                               GtkTreePath  *path)
1187 {
1188   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1189   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1190   gint *indices;
1191   SortElt *elt;
1192   SortLevel *level;
1193   gint depth, i;
1194   GSequenceIter *siter;
1195
1196   g_return_val_if_fail (priv->child_model != NULL, FALSE);
1197
1198   indices = gtk_tree_path_get_indices (path);
1199
1200   if (priv->root == NULL)
1201     gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1202   level = SORT_LEVEL (priv->root);
1203
1204   depth = gtk_tree_path_get_depth (path);
1205   if (depth == 0)
1206     {
1207       iter->stamp = 0;
1208       return FALSE;
1209     }
1210
1211   for (i = 0; i < depth - 1; i++)
1212     {
1213       if ((level == NULL) ||
1214           (indices[i] >= g_sequence_get_length (level->seq)))
1215         {
1216           iter->stamp = 0;
1217           return FALSE;
1218         }
1219
1220       siter = g_sequence_get_iter_at_pos (level->seq, indices[i]);
1221       if (g_sequence_iter_is_end (siter))
1222         {
1223           iter->stamp = 0;
1224           return FALSE;
1225         }
1226
1227       elt = GET_ELT (siter);
1228       if (elt->children == NULL)
1229         gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
1230
1231       level = elt->children;
1232     }
1233
1234   if (!level || indices[i] >= g_sequence_get_length (level->seq))
1235     {
1236       iter->stamp = 0;
1237       return FALSE;
1238     }
1239
1240   iter->stamp = priv->stamp;
1241   iter->user_data = level;
1242
1243   siter = g_sequence_get_iter_at_pos (level->seq, indices[depth - 1]);
1244   if (g_sequence_iter_is_end (siter))
1245     {
1246       iter->stamp = 0;
1247       return FALSE;
1248     }
1249   iter->user_data2 = GET_ELT (siter);
1250
1251   return TRUE;
1252 }
1253
1254 static GtkTreePath *
1255 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
1256                               GtkTreeIter  *iter)
1257 {
1258   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1259   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1260   GtkTreePath *retval;
1261   SortLevel *level;
1262   SortElt *elt;
1263
1264   g_return_val_if_fail (priv->child_model != NULL, NULL);
1265   g_return_val_if_fail (priv->stamp == iter->stamp, NULL);
1266
1267   retval = gtk_tree_path_new ();
1268
1269   level = SORT_LEVEL (iter->user_data);
1270   elt = SORT_ELT (iter->user_data2);
1271
1272   while (level)
1273     {
1274       gint index;
1275
1276       index = g_sequence_iter_get_position (elt->siter);
1277       gtk_tree_path_prepend_index (retval, index);
1278
1279       elt = level->parent_elt;
1280       level = level->parent_level;
1281     }
1282
1283   return retval;
1284 }
1285
1286 static void
1287 gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
1288                                GtkTreeIter  *iter,
1289                                gint          column,
1290                                GValue       *value)
1291 {
1292   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1293   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1294   GtkTreeIter child_iter;
1295
1296   g_return_if_fail (priv->child_model != NULL);
1297   g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1298
1299   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1300   gtk_tree_model_get_value (priv->child_model,
1301                             &child_iter, column, value);
1302 }
1303
1304 static gboolean
1305 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
1306                                GtkTreeIter  *iter)
1307 {
1308   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1309   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1310   SortLevel *level;
1311   SortElt *elt;
1312   GSequenceIter *siter;
1313
1314   g_return_val_if_fail (priv->child_model != NULL, FALSE);
1315   g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1316
1317   level = iter->user_data;
1318   elt = iter->user_data2;
1319
1320   siter = g_sequence_iter_next (elt->siter);
1321   if (g_sequence_iter_is_end (siter))
1322     {
1323       iter->stamp = 0;
1324       return FALSE;
1325     }
1326   iter->user_data2 = GET_ELT (siter);
1327
1328   return TRUE;
1329 }
1330
1331 static gboolean
1332 gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
1333                                    GtkTreeIter  *iter)
1334 {
1335   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1336   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1337   SortLevel *level;
1338   SortElt *elt;
1339   GSequenceIter *siter;
1340
1341   g_return_val_if_fail (priv->child_model != NULL, FALSE);
1342   g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1343
1344   level = iter->user_data;
1345   elt = iter->user_data2;
1346
1347   siter = g_sequence_iter_prev (elt->siter);
1348   if (g_sequence_iter_is_begin (siter))
1349     {
1350       iter->stamp = 0;
1351       return FALSE;
1352     }
1353   iter->user_data2 = GET_ELT (siter);
1354
1355   return TRUE;
1356 }
1357
1358 static gboolean
1359 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
1360                                    GtkTreeIter  *iter,
1361                                    GtkTreeIter  *parent)
1362 {
1363   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1364   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1365   SortLevel *level;
1366
1367   iter->stamp = 0;
1368   g_return_val_if_fail (priv->child_model != NULL, FALSE);
1369   if (parent) 
1370     g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1371
1372   if (parent == NULL)
1373     {
1374       if (priv->root == NULL)
1375         gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1376       if (priv->root == NULL)
1377         return FALSE;
1378
1379       level = priv->root;
1380       iter->stamp = priv->stamp;
1381       iter->user_data = level;
1382       iter->user_data2 = g_sequence_get (g_sequence_get_begin_iter (level->seq));
1383     }
1384   else
1385     {
1386       SortElt *elt;
1387
1388       level = SORT_LEVEL (parent->user_data);
1389       elt = SORT_ELT (parent->user_data2);
1390
1391       if (elt->children == NULL)
1392         gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
1393
1394       if (elt->children == NULL)
1395         return FALSE;
1396
1397       iter->stamp = priv->stamp;
1398       iter->user_data = elt->children;
1399       iter->user_data2 = g_sequence_get (g_sequence_get_begin_iter (elt->children->seq));
1400     }
1401
1402   return TRUE;
1403 }
1404
1405 static gboolean
1406 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
1407                                     GtkTreeIter  *iter)
1408 {
1409   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1410   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1411   GtkTreeIter child_iter;
1412
1413   g_return_val_if_fail (priv->child_model != NULL, FALSE);
1414   g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), FALSE);
1415
1416   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1417
1418   return gtk_tree_model_iter_has_child (priv->child_model, &child_iter);
1419 }
1420
1421 static gint
1422 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
1423                                      GtkTreeIter  *iter)
1424 {
1425   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1426   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1427   GtkTreeIter child_iter;
1428
1429   g_return_val_if_fail (priv->child_model != NULL, 0);
1430   if (iter) 
1431     g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), 0);
1432
1433   if (iter == NULL)
1434     return gtk_tree_model_iter_n_children (priv->child_model, NULL);
1435
1436   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1437
1438   return gtk_tree_model_iter_n_children (priv->child_model, &child_iter);
1439 }
1440
1441 static gboolean
1442 gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
1443                                     GtkTreeIter  *iter,
1444                                     GtkTreeIter  *parent,
1445                                     gint          n)
1446 {
1447   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1448   SortLevel *level;
1449   /* We have this for the iter == parent case */
1450   GtkTreeIter children;
1451
1452   if (parent) 
1453     g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1454
1455   /* Use this instead of has_child to force us to build the level, if needed */
1456   if (gtk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE)
1457     {
1458       iter->stamp = 0;
1459       return FALSE;
1460     }
1461
1462   level = children.user_data;
1463   if (n >= g_sequence_get_length (level->seq))
1464     {
1465       iter->stamp = 0;
1466       return FALSE;
1467     }
1468
1469   iter->stamp = tree_model_sort->priv->stamp;
1470   iter->user_data = level;
1471   iter->user_data2 = g_sequence_get (g_sequence_get_iter_at_pos (level->seq, n));
1472
1473   return TRUE;
1474 }
1475
1476 static gboolean
1477 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
1478                                  GtkTreeIter  *iter,
1479                                  GtkTreeIter  *child)
1480
1481   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1482   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1483   SortLevel *level;
1484
1485   iter->stamp = 0;
1486   g_return_val_if_fail (priv->child_model != NULL, FALSE);
1487   g_return_val_if_fail (VALID_ITER (child, tree_model_sort), FALSE);
1488
1489   level = child->user_data;
1490
1491   if (level->parent_level)
1492     {
1493       iter->stamp = priv->stamp;
1494       iter->user_data = level->parent_level;
1495       iter->user_data2 = level->parent_elt;
1496
1497       return TRUE;
1498     }
1499   return FALSE;
1500 }
1501
1502 static void
1503 gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
1504                               GtkTreeIter  *iter)
1505 {
1506   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1507   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1508   GtkTreeIter child_iter;
1509   SortLevel *level;
1510   SortElt *elt;
1511
1512   g_return_if_fail (priv->child_model != NULL);
1513   g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1514
1515   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1516
1517   /* Reference the node in the child model */
1518   gtk_tree_model_ref_node (priv->child_model, &child_iter);
1519
1520   /* Increase the reference count of this element and its level */
1521   level = iter->user_data;
1522   elt = iter->user_data2;
1523
1524   elt->ref_count++;
1525   level->ref_count++;
1526
1527   if (level->ref_count == 1)
1528     {
1529       SortLevel *parent_level = level->parent_level;
1530       SortElt *parent_elt = level->parent_elt;
1531
1532       /* We were at zero -- time to decrement the zero_ref_count val */
1533       while (parent_level)
1534         {
1535           parent_elt->zero_ref_count--;
1536
1537           parent_elt = parent_level->parent_elt;
1538           parent_level = parent_level->parent_level;
1539         }
1540
1541       if (priv->root != level)
1542         priv->zero_ref_count--;
1543     }
1544 }
1545
1546 static void
1547 gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
1548                                      GtkTreeIter  *iter,
1549                                      gboolean      propagate_unref)
1550 {
1551   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1552   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1553   SortLevel *level;
1554   SortElt *elt;
1555
1556   g_return_if_fail (priv->child_model != NULL);
1557   g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1558
1559   if (propagate_unref)
1560     {
1561       GtkTreeIter child_iter;
1562
1563       GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1564       gtk_tree_model_unref_node (priv->child_model, &child_iter);
1565     }
1566
1567   level = iter->user_data;
1568   elt = iter->user_data2;
1569
1570   g_return_if_fail (elt->ref_count > 0);
1571
1572   elt->ref_count--;
1573   level->ref_count--;
1574
1575   if (level->ref_count == 0)
1576     {
1577       SortLevel *parent_level = level->parent_level;
1578       SortElt *parent_elt = level->parent_elt;
1579
1580       /* We are at zero -- time to increment the zero_ref_count val */
1581       while (parent_level)
1582         {
1583           parent_elt->zero_ref_count++;
1584
1585           parent_elt = parent_level->parent_elt;
1586           parent_level = parent_level->parent_level;
1587         }
1588
1589       if (priv->root != level)
1590         priv->zero_ref_count++;
1591     }
1592 }
1593
1594 static void
1595 gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
1596                                 GtkTreeIter  *iter)
1597 {
1598   gtk_tree_model_sort_real_unref_node (tree_model, iter, TRUE);
1599 }
1600
1601 /* Sortable interface */
1602 static gboolean
1603 gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
1604                                         gint            *sort_column_id,
1605                                         GtkSortType     *order)
1606 {
1607   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1608   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1609
1610   if (sort_column_id)
1611     *sort_column_id = priv->sort_column_id;
1612   if (order)
1613     *order = priv->order;
1614
1615   if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
1616       priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1617     return FALSE;
1618   
1619   return TRUE;
1620 }
1621
1622 static void
1623 gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
1624                                         gint             sort_column_id,
1625                                         GtkSortType      order)
1626 {
1627   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1628   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1629
1630   if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1631     {
1632       if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1633         {
1634           GtkTreeDataSortHeader *header = NULL;
1635
1636           header = _gtk_tree_data_list_get_header (priv->sort_list,
1637                                                    sort_column_id);
1638
1639           /* we want to make sure that we have a function */
1640           g_return_if_fail (header != NULL);
1641           g_return_if_fail (header->func != NULL);
1642         }
1643       else
1644         g_return_if_fail (priv->default_sort_func != NULL);
1645
1646       if (priv->sort_column_id == sort_column_id)
1647         {
1648           if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1649             {
1650               if (priv->order == order)
1651                 return;
1652             }
1653           else
1654             return;
1655         }
1656     }
1657
1658   priv->sort_column_id = sort_column_id;
1659   priv->order = order;
1660
1661   gtk_tree_sortable_sort_column_changed (sortable);
1662
1663   gtk_tree_model_sort_sort (tree_model_sort);
1664 }
1665
1666 static void
1667 gtk_tree_model_sort_set_sort_func (GtkTreeSortable        *sortable,
1668                                    gint                    sort_column_id,
1669                                    GtkTreeIterCompareFunc  func,
1670                                    gpointer                data,
1671                                    GDestroyNotify          destroy)
1672 {
1673   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1674   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1675
1676   priv->sort_list = _gtk_tree_data_list_set_header (priv->sort_list,
1677                                                     sort_column_id,
1678                                                     func, data, destroy);
1679
1680   if (priv->sort_column_id == sort_column_id)
1681     gtk_tree_model_sort_sort (tree_model_sort);
1682 }
1683
1684 static void
1685 gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable        *sortable,
1686                                            GtkTreeIterCompareFunc  func,
1687                                            gpointer                data,
1688                                            GDestroyNotify          destroy)
1689 {
1690   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1691   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1692
1693   if (priv->default_sort_destroy)
1694     {
1695       GDestroyNotify d = priv->default_sort_destroy;
1696
1697       priv->default_sort_destroy = NULL;
1698       d (priv->default_sort_data);
1699     }
1700
1701   priv->default_sort_func = func;
1702   priv->default_sort_data = data;
1703   priv->default_sort_destroy = destroy;
1704
1705   if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1706     gtk_tree_model_sort_sort (tree_model_sort);
1707 }
1708
1709 static gboolean
1710 gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
1711 {
1712   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1713
1714   return (tree_model_sort->priv->default_sort_func != NULL);
1715 }
1716
1717 /* DragSource interface */
1718 static gboolean
1719 gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
1720                                    GtkTreePath       *path)
1721 {
1722   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1723   GtkTreePath *child_path;
1724   gboolean draggable;
1725
1726   child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
1727                                                                path);
1728   draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1729   gtk_tree_path_free (child_path);
1730
1731   return draggable;
1732 }
1733
1734 static gboolean
1735 gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
1736                                    GtkTreePath       *path,
1737                                    GtkSelectionData  *selection_data)
1738 {
1739   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1740   GtkTreePath *child_path;
1741   gboolean gotten;
1742
1743   child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1744   gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path, selection_data);
1745   gtk_tree_path_free (child_path);
1746
1747   return gotten;
1748 }
1749
1750 static gboolean
1751 gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
1752                                       GtkTreePath       *path)
1753 {
1754   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1755   GtkTreePath *child_path;
1756   gboolean deleted;
1757
1758   child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1759   deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1760   gtk_tree_path_free (child_path);
1761
1762   return deleted;
1763 }
1764
1765 /* sorting code - private */
1766 static gint
1767 gtk_tree_model_sort_compare_func (gconstpointer a,
1768                                   gconstpointer b,
1769                                   gpointer      user_data)
1770 {
1771   SortData *data = (SortData *)user_data;
1772   GtkTreeModelSort *tree_model_sort = data->tree_model_sort;
1773   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1774   const SortElt *sa = a;
1775   const SortElt *sb = b;
1776
1777   GtkTreeIter iter_a, iter_b;
1778   gint retval;
1779
1780   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1781     {
1782       iter_a = sa->iter;
1783       iter_b = sb->iter;
1784     }
1785   else
1786     {
1787       data->parent_path_indices [data->parent_path_depth-1] = sa->offset;
1788       gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_a, data->parent_path);
1789       data->parent_path_indices [data->parent_path_depth-1] = sb->offset;
1790       gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_b, data->parent_path);
1791     }
1792
1793   retval = (* data->sort_func) (GTK_TREE_MODEL (priv->child_model),
1794                                 &iter_a, &iter_b,
1795                                 data->sort_data);
1796
1797   if (priv->order == GTK_SORT_DESCENDING)
1798     {
1799       if (retval > 0)
1800         retval = -1;
1801       else if (retval < 0)
1802         retval = 1;
1803     }
1804
1805   return retval;
1806 }
1807
1808 static gint
1809 gtk_tree_model_sort_offset_compare_func (gconstpointer a,
1810                                          gconstpointer b,
1811                                          gpointer      user_data)
1812 {
1813   gint retval;
1814
1815   const SortElt *sa = (SortElt *)a;
1816   const SortElt *sb = (SortElt *)b;
1817
1818   SortData *data = (SortData *)user_data;
1819
1820   if (sa->offset < sb->offset)
1821     retval = -1;
1822   else if (sa->offset > sb->offset)
1823     retval = 1;
1824   else
1825     retval = 0;
1826
1827   if (data->tree_model_sort->priv->order == GTK_SORT_DESCENDING)
1828     {
1829       if (retval > 0)
1830         retval = -1;
1831       else if (retval < 0)
1832         retval = 1;
1833     }
1834
1835   return retval;
1836 }
1837
1838 static void
1839 gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
1840                                 SortLevel        *level,
1841                                 gboolean          recurse,
1842                                 gboolean          emit_reordered)
1843 {
1844   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1845   gint i;
1846   GSequenceIter *begin_siter, *end_siter, *siter;
1847   SortElt *begin_elt;
1848   gint *new_order;
1849
1850   GtkTreeIter iter;
1851   GtkTreePath *path;
1852
1853   SortData data;
1854
1855   g_return_if_fail (level != NULL);
1856
1857   begin_siter = g_sequence_get_begin_iter (level->seq);
1858   begin_elt = g_sequence_get (begin_siter);
1859
1860   if (g_sequence_get_length (level->seq) < 1 && !begin_elt->children)
1861     return;
1862
1863   iter.stamp = priv->stamp;
1864   iter.user_data = level;
1865   iter.user_data2 = begin_elt;
1866
1867   gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1868
1869   i = 0;
1870   end_siter = g_sequence_get_end_iter (level->seq);
1871   for (siter = g_sequence_get_begin_iter (level->seq);
1872        siter != end_siter;
1873        siter = g_sequence_iter_next (siter))
1874     {
1875       SortElt *elt = g_sequence_get (siter);
1876
1877       elt->old_index = i;
1878       i++;
1879     }
1880
1881   fill_sort_data (&data, tree_model_sort, level);
1882
1883   if (data.sort_func == NO_SORT_FUNC)
1884     g_sequence_sort (level->seq, gtk_tree_model_sort_offset_compare_func,
1885                      &data);
1886   else
1887     g_sequence_sort (level->seq, gtk_tree_model_sort_compare_func, &data);
1888
1889   free_sort_data (&data);
1890
1891   new_order = g_new (gint, g_sequence_get_length (level->seq));
1892
1893   i = 0;
1894   end_siter = g_sequence_get_end_iter (level->seq);
1895   for (siter = g_sequence_get_begin_iter (level->seq);
1896        siter != end_siter;
1897        siter = g_sequence_iter_next (siter))
1898     {
1899       SortElt *elt = g_sequence_get (siter);
1900
1901       new_order[i++] = elt->old_index;
1902     }
1903
1904   if (emit_reordered)
1905     {
1906       gtk_tree_model_sort_increment_stamp (tree_model_sort);
1907       if (level->parent_elt)
1908         {
1909           iter.stamp = priv->stamp;
1910           iter.user_data = level->parent_level;
1911           iter.user_data2 = level->parent_elt;
1912
1913           path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort),
1914                                           &iter);
1915
1916           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1917                                          &iter, new_order);
1918         }
1919       else
1920         {
1921           /* toplevel list */
1922           path = gtk_tree_path_new ();
1923           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1924                                          NULL, new_order);
1925         }
1926
1927       gtk_tree_path_free (path);
1928     }
1929
1930   /* recurse, if possible */
1931   if (recurse)
1932     {
1933       end_siter = g_sequence_get_end_iter (level->seq);
1934       for (siter = g_sequence_get_begin_iter (level->seq);
1935            siter != end_siter;
1936            siter = g_sequence_iter_next (siter))
1937         {
1938           SortElt *elt = g_sequence_get (siter);
1939
1940           if (elt->children)
1941             gtk_tree_model_sort_sort_level (tree_model_sort,
1942                                             elt->children,
1943                                             TRUE, emit_reordered);
1944         }
1945     }
1946
1947   g_free (new_order);
1948
1949   /* get the iter we referenced at the beginning of this function and
1950    * unref it again
1951    */
1952   iter.stamp = priv->stamp;
1953   iter.user_data = level;
1954   iter.user_data2 = begin_elt;
1955
1956   gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1957 }
1958
1959 static void
1960 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
1961 {
1962   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1963
1964   if (priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1965     return;
1966
1967   if (!priv->root)
1968     return;
1969
1970   if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1971     {
1972       GtkTreeDataSortHeader *header = NULL;
1973
1974       header = _gtk_tree_data_list_get_header (priv->sort_list,
1975                                                priv->sort_column_id);
1976
1977       /* we want to make sure that we have a function */
1978       g_return_if_fail (header != NULL);
1979       g_return_if_fail (header->func != NULL);
1980     }
1981   else
1982     g_return_if_fail (priv->default_sort_func != NULL);
1983
1984   gtk_tree_model_sort_sort_level (tree_model_sort, priv->root,
1985                                   TRUE, TRUE);
1986 }
1987
1988 /* signal helpers */
1989 static gboolean
1990 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
1991                                   SortLevel        *level,
1992                                   GtkTreePath      *s_path,
1993                                   GtkTreeIter      *s_iter)
1994 {
1995   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1996   SortElt *elt;
1997   SortData data;
1998   gint offset;
1999
2000   elt = sort_elt_new ();
2001
2002   offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
2003
2004   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2005     elt->iter = *s_iter;
2006   elt->offset = offset;
2007   elt->zero_ref_count = 0;
2008   elt->ref_count = 0;
2009   elt->children = NULL;
2010
2011   /* update all larger offsets */
2012   g_sequence_foreach (level->seq, increase_offset_iter, GINT_TO_POINTER (offset));
2013
2014   fill_sort_data (&data, tree_model_sort, level);
2015
2016   if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
2017       priv->default_sort_func == NO_SORT_FUNC)
2018     {
2019       elt->siter = g_sequence_insert_sorted (level->seq, elt,
2020                                              gtk_tree_model_sort_offset_compare_func,
2021                                              &data);
2022     }
2023   else
2024     {
2025       elt->siter = g_sequence_insert_sorted (level->seq, elt,
2026                                              gtk_tree_model_sort_compare_func,
2027                                              &data);
2028     }
2029
2030   free_sort_data (&data);
2031
2032   return TRUE;
2033 }
2034
2035 /* sort elt stuff */
2036 static GtkTreePath *
2037 gtk_tree_model_sort_elt_get_path (SortLevel *level,
2038                                   SortElt *elt)
2039 {
2040   SortLevel *walker = level;
2041   SortElt *walker2 = elt;
2042   GtkTreePath *path;
2043
2044   g_return_val_if_fail (level != NULL, NULL);
2045   g_return_val_if_fail (elt != NULL, NULL);
2046
2047   path = gtk_tree_path_new ();
2048
2049   while (walker)
2050     {
2051       gtk_tree_path_prepend_index (path, walker2->offset);
2052
2053       if (!walker->parent_level)
2054         break;
2055
2056       walker2 = walker->parent_elt;
2057       walker = walker->parent_level;
2058     }
2059
2060   return path;
2061 }
2062
2063 /**
2064  * gtk_tree_model_sort_set_model:
2065  * @tree_model_sort: The #GtkTreeModelSort.
2066  * @child_model: (allow-none): A #GtkTreeModel, or %NULL.
2067  *
2068  * Sets the model of @tree_model_sort to be @model.  If @model is %NULL, 
2069  * then the old model is unset.  The sort function is unset as a result 
2070  * of this call. The model will be in an unsorted state until a sort 
2071  * function is set.
2072  **/
2073 static void
2074 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
2075                                GtkTreeModel     *child_model)
2076 {
2077   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2078
2079   if (child_model)
2080     g_object_ref (child_model);
2081
2082   if (priv->child_model)
2083     {
2084       g_signal_handler_disconnect (priv->child_model,
2085                                    priv->changed_id);
2086       g_signal_handler_disconnect (priv->child_model,
2087                                    priv->inserted_id);
2088       g_signal_handler_disconnect (priv->child_model,
2089                                    priv->has_child_toggled_id);
2090       g_signal_handler_disconnect (priv->child_model,
2091                                    priv->deleted_id);
2092       g_signal_handler_disconnect (priv->child_model,
2093                                    priv->reordered_id);
2094
2095       /* reset our state */
2096       if (priv->root)
2097         gtk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE);
2098       priv->root = NULL;
2099       _gtk_tree_data_list_header_free (priv->sort_list);
2100       priv->sort_list = NULL;
2101       g_object_unref (priv->child_model);
2102     }
2103
2104   priv->child_model = child_model;
2105
2106   if (child_model)
2107     {
2108       GType *types;
2109       gint i, n_columns;
2110
2111       priv->changed_id =
2112         g_signal_connect (child_model, "row-changed",
2113                           G_CALLBACK (gtk_tree_model_sort_row_changed),
2114                           tree_model_sort);
2115       priv->inserted_id =
2116         g_signal_connect (child_model, "row-inserted",
2117                           G_CALLBACK (gtk_tree_model_sort_row_inserted),
2118                           tree_model_sort);
2119       priv->has_child_toggled_id =
2120         g_signal_connect (child_model, "row-has-child-toggled",
2121                           G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
2122                           tree_model_sort);
2123       priv->deleted_id =
2124         g_signal_connect (child_model, "row-deleted",
2125                           G_CALLBACK (gtk_tree_model_sort_row_deleted),
2126                           tree_model_sort);
2127       priv->reordered_id =
2128         g_signal_connect (child_model, "rows-reordered",
2129                           G_CALLBACK (gtk_tree_model_sort_rows_reordered),
2130                           tree_model_sort);
2131
2132       priv->child_flags = gtk_tree_model_get_flags (child_model);
2133       n_columns = gtk_tree_model_get_n_columns (child_model);
2134
2135       types = g_new (GType, n_columns);
2136       for (i = 0; i < n_columns; i++)
2137         types[i] = gtk_tree_model_get_column_type (child_model, i);
2138
2139       priv->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
2140       g_free (types);
2141
2142       priv->default_sort_func = NO_SORT_FUNC;
2143       priv->stamp = g_random_int ();
2144     }
2145 }
2146
2147 /**
2148  * gtk_tree_model_sort_get_model:
2149  * @tree_model: a #GtkTreeModelSort
2150  *
2151  * Returns the model the #GtkTreeModelSort is sorting.
2152  *
2153  * Return value: (transfer none): the "child model" being sorted
2154  **/
2155 GtkTreeModel *
2156 gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model)
2157 {
2158   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
2159
2160   return tree_model->priv->child_model;
2161 }
2162
2163
2164 static GtkTreePath *
2165 gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2166                                                      GtkTreePath      *child_path,
2167                                                      gboolean          build_levels)
2168 {
2169   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2170   gint *child_indices;
2171   GtkTreePath *retval;
2172   SortLevel *level;
2173   gint i;
2174
2175   g_return_val_if_fail (priv->child_model != NULL, NULL);
2176   g_return_val_if_fail (child_path != NULL, NULL);
2177
2178   retval = gtk_tree_path_new ();
2179   child_indices = gtk_tree_path_get_indices (child_path);
2180
2181   if (priv->root == NULL && build_levels)
2182     gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
2183   level = SORT_LEVEL (priv->root);
2184
2185   for (i = 0; i < gtk_tree_path_get_depth (child_path); i++)
2186     {
2187       SortElt *tmp;
2188       GSequenceIter *siter;
2189       gboolean found_child = FALSE;
2190
2191       if (!level)
2192         {
2193           gtk_tree_path_free (retval);
2194           return NULL;
2195         }
2196
2197       if (child_indices[i] >= g_sequence_get_length (level->seq))
2198         {
2199           gtk_tree_path_free (retval);
2200           return NULL;
2201         }
2202       tmp = lookup_elt_with_offset (tree_model_sort, level,
2203                                     child_indices[i], &siter);
2204       if (tmp)
2205         {
2206           gtk_tree_path_append_index (retval, g_sequence_iter_get_position (siter));
2207           if (tmp->children == NULL && build_levels)
2208             gtk_tree_model_sort_build_level (tree_model_sort, level, tmp);
2209
2210           level = tmp->children;
2211           found_child = TRUE;
2212         }
2213
2214       if (! found_child)
2215         {
2216           gtk_tree_path_free (retval);
2217           return NULL;
2218         }
2219     }
2220
2221   return retval;
2222 }
2223
2224
2225 /**
2226  * gtk_tree_model_sort_convert_child_path_to_path:
2227  * @tree_model_sort: A #GtkTreeModelSort
2228  * @child_path: A #GtkTreePath to convert
2229  * 
2230  * Converts @child_path to a path relative to @tree_model_sort.  That is,
2231  * @child_path points to a path in the child model.  The returned path will
2232  * point to the same row in the sorted model.  If @child_path isn't a valid 
2233  * path on the child model, then %NULL is returned.
2234  * 
2235  * Return value: A newly allocated #GtkTreePath, or %NULL
2236  **/
2237 GtkTreePath *
2238 gtk_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2239                                                 GtkTreePath      *child_path)
2240 {
2241   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2242   g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, NULL);
2243   g_return_val_if_fail (child_path != NULL, NULL);
2244
2245   return gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE);
2246 }
2247
2248 /**
2249  * gtk_tree_model_sort_convert_child_iter_to_iter:
2250  * @tree_model_sort: A #GtkTreeModelSort
2251  * @sort_iter: (out): An uninitialized #GtkTreeIter.
2252  * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
2253  * 
2254  * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to
2255  * the row pointed at by @child_iter.  If @sort_iter was not set, %FALSE
2256  * is returned.  Note: a boolean is only returned since 2.14.
2257  *
2258  * Return value: %TRUE, if @sort_iter was set, i.e. if @sort_iter is a
2259  * valid iterator pointer to a visible row in the child model.
2260  **/
2261 gboolean
2262 gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sort,
2263                                                 GtkTreeIter      *sort_iter,
2264                                                 GtkTreeIter      *child_iter)
2265 {
2266   gboolean ret;
2267   GtkTreePath *child_path, *path;
2268   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2269
2270   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2271   g_return_val_if_fail (priv->child_model != NULL, FALSE);
2272   g_return_val_if_fail (sort_iter != NULL, FALSE);
2273   g_return_val_if_fail (child_iter != NULL, FALSE);
2274   g_return_val_if_fail (sort_iter != child_iter, FALSE);
2275
2276   sort_iter->stamp = 0;
2277
2278   child_path = gtk_tree_model_get_path (priv->child_model, child_iter);
2279   g_return_val_if_fail (child_path != NULL, FALSE);
2280
2281   path = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path);
2282   gtk_tree_path_free (child_path);
2283
2284   if (!path)
2285     {
2286       g_warning ("%s: The conversion of the child path to a GtkTreeModel sort path failed", G_STRLOC);
2287       return FALSE;
2288     }
2289
2290   ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
2291                                  sort_iter, path);
2292   gtk_tree_path_free (path);
2293
2294   return ret;
2295 }
2296
2297 /**
2298  * gtk_tree_model_sort_convert_path_to_child_path:
2299  * @tree_model_sort: A #GtkTreeModelSort
2300  * @sorted_path: A #GtkTreePath to convert
2301  * 
2302  * Converts @sorted_path to a path on the child model of @tree_model_sort.  
2303  * That is, @sorted_path points to a location in @tree_model_sort.  The 
2304  * returned path will point to the same location in the model not being 
2305  * sorted.  If @sorted_path does not point to a location in the child model, 
2306  * %NULL is returned.
2307  * 
2308  * Return value: A newly allocated #GtkTreePath, or %NULL
2309  **/
2310 GtkTreePath *
2311 gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sort,
2312                                                 GtkTreePath      *sorted_path)
2313 {
2314   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2315   gint *sorted_indices;
2316   GtkTreePath *retval;
2317   SortLevel *level;
2318   gint i;
2319
2320   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2321   g_return_val_if_fail (priv->child_model != NULL, NULL);
2322   g_return_val_if_fail (sorted_path != NULL, NULL);
2323
2324   retval = gtk_tree_path_new ();
2325   sorted_indices = gtk_tree_path_get_indices (sorted_path);
2326   if (priv->root == NULL)
2327     gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
2328   level = SORT_LEVEL (priv->root);
2329
2330   for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++)
2331     {
2332       SortElt *elt = NULL;
2333       GSequenceIter *siter;
2334
2335       if ((level == NULL) ||
2336           (g_sequence_get_length (level->seq) <= sorted_indices[i]))
2337         {
2338           gtk_tree_path_free (retval);
2339           return NULL;
2340         }
2341
2342       siter = g_sequence_get_iter_at_pos (level->seq, sorted_indices[i]);
2343       if (g_sequence_iter_is_end (siter))
2344         {
2345           gtk_tree_path_free (retval);
2346           return NULL;
2347         }
2348
2349       elt = GET_ELT (siter);
2350       if (elt->children == NULL)
2351         gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
2352
2353       if (level == NULL)
2354         {
2355           gtk_tree_path_free (retval);
2356           break;
2357         }
2358
2359       gtk_tree_path_append_index (retval, elt->offset);
2360       level = elt->children;
2361     }
2362  
2363   return retval;
2364 }
2365
2366 /**
2367  * gtk_tree_model_sort_convert_iter_to_child_iter:
2368  * @tree_model_sort: A #GtkTreeModelSort
2369  * @child_iter: (out): An uninitialized #GtkTreeIter
2370  * @sorted_iter: A valid #GtkTreeIter pointing to a row on @tree_model_sort.
2371  * 
2372  * Sets @child_iter to point to the row pointed to by @sorted_iter.
2373  **/
2374 void
2375 gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sort,
2376                                                 GtkTreeIter      *child_iter,
2377                                                 GtkTreeIter      *sorted_iter)
2378 {
2379   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2380   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2381   g_return_if_fail (priv->child_model != NULL);
2382   g_return_if_fail (child_iter != NULL);
2383   g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort));
2384   g_return_if_fail (sorted_iter != child_iter);
2385
2386   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2387     {
2388       *child_iter = SORT_ELT (sorted_iter->user_data2)->iter;
2389     }
2390   else
2391     {
2392       GtkTreePath *path;
2393       gboolean valid = FALSE;
2394
2395       path = gtk_tree_model_sort_elt_get_path (sorted_iter->user_data,
2396                                                sorted_iter->user_data2);
2397       valid = gtk_tree_model_get_iter (priv->child_model, child_iter, path);
2398       gtk_tree_path_free (path);
2399
2400       g_return_if_fail (valid == TRUE);
2401     }
2402 }
2403
2404 static void
2405 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
2406                                  SortLevel        *parent_level,
2407                                  SortElt          *parent_elt)
2408 {
2409   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2410   GtkTreeIter iter;
2411   SortLevel *new_level;
2412   gint length = 0;
2413   gint i;
2414
2415   g_assert (priv->child_model != NULL);
2416
2417   if (parent_level == NULL)
2418     {
2419       if (gtk_tree_model_get_iter_first (priv->child_model, &iter) == FALSE)
2420         return;
2421       length = gtk_tree_model_iter_n_children (priv->child_model, NULL);
2422     }
2423   else
2424     {
2425       GtkTreeIter parent_iter;
2426       GtkTreeIter child_parent_iter;
2427
2428       parent_iter.stamp = priv->stamp;
2429       parent_iter.user_data = parent_level;
2430       parent_iter.user_data2 = parent_elt;
2431
2432       gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2433                                                       &child_parent_iter,
2434                                                       &parent_iter);
2435       if (gtk_tree_model_iter_children (priv->child_model,
2436                                         &iter,
2437                                         &child_parent_iter) == FALSE)
2438         return;
2439
2440       /* stamp may have changed */
2441       gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2442                                                       &child_parent_iter,
2443                                                       &parent_iter);
2444
2445       length = gtk_tree_model_iter_n_children (priv->child_model, &child_parent_iter);
2446
2447       gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort),
2448                                     &parent_iter);
2449     }
2450
2451   g_return_if_fail (length > 0);
2452
2453   new_level = g_new (SortLevel, 1);
2454   new_level->seq = g_sequence_new (sort_elt_free);
2455   new_level->ref_count = 0;
2456   new_level->parent_level = parent_level;
2457   new_level->parent_elt = parent_elt;
2458
2459   if (parent_elt)
2460     parent_elt->children = new_level;
2461   else
2462     priv->root = new_level;
2463
2464   /* increase the count of zero ref_counts.*/
2465   while (parent_level)
2466     {
2467       parent_elt->zero_ref_count++;
2468
2469       parent_elt = parent_level->parent_elt;
2470       parent_level = parent_level->parent_level;
2471     }
2472
2473   if (new_level != priv->root)
2474     priv->zero_ref_count++;
2475
2476   for (i = 0; i < length; i++)
2477     {
2478       SortElt *sort_elt;
2479
2480       sort_elt = sort_elt_new ();
2481       sort_elt->offset = i;
2482       sort_elt->zero_ref_count = 0;
2483       sort_elt->ref_count = 0;
2484       sort_elt->children = NULL;
2485
2486       if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2487         {
2488           sort_elt->iter = iter;
2489           if (gtk_tree_model_iter_next (priv->child_model, &iter) == FALSE &&
2490               i < length - 1)
2491             {
2492               if (parent_level)
2493                 {
2494                   GtkTreePath *level;
2495                   gchar *str;
2496
2497                   level = gtk_tree_model_sort_elt_get_path (parent_level,
2498                                                             parent_elt);
2499                   str = gtk_tree_path_to_string (level);
2500                   gtk_tree_path_free (level);
2501
2502                   g_warning ("%s: There is a discrepancy between the sort model "
2503                              "and the child model.  The child model is "
2504                              "advertising a wrong length for level %s:.",
2505                              G_STRLOC, str);
2506                   g_free (str);
2507                 }
2508               else
2509                 {
2510                   g_warning ("%s: There is a discrepancy between the sort model "
2511                              "and the child model.  The child model is "
2512                              "advertising a wrong length for the root level.",
2513                              G_STRLOC);
2514                 }
2515
2516               return;
2517             }
2518         }
2519
2520       sort_elt->siter = g_sequence_append (new_level->seq, sort_elt);
2521     }
2522
2523   /* sort level */
2524   gtk_tree_model_sort_sort_level (tree_model_sort, new_level,
2525                                   FALSE, FALSE);
2526 }
2527
2528 static void
2529 gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
2530                                 SortLevel        *sort_level,
2531                                 gboolean          unref)
2532 {
2533   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2534   GSequenceIter *siter;
2535   GSequenceIter *end_siter;
2536
2537   g_assert (sort_level);
2538
2539   end_siter = g_sequence_get_end_iter (sort_level->seq);
2540   for (siter = g_sequence_get_begin_iter (sort_level->seq);
2541        siter != end_siter;
2542        siter = g_sequence_iter_next (siter))
2543     {
2544       SortElt *elt = g_sequence_get (siter);
2545
2546       if (elt->children)
2547         gtk_tree_model_sort_free_level (tree_model_sort,
2548                                         elt->children, unref);
2549     }
2550
2551   if (sort_level->ref_count == 0)
2552     {
2553       SortLevel *parent_level = sort_level->parent_level;
2554       SortElt *parent_elt = sort_level->parent_elt;
2555
2556       while (parent_level)
2557         {
2558           parent_elt->zero_ref_count--;
2559
2560           parent_elt = parent_level->parent_elt;
2561           parent_level = parent_level->parent_level;
2562         }
2563
2564       if (sort_level != priv->root)
2565         priv->zero_ref_count--;
2566     }
2567
2568   if (sort_level->parent_elt)
2569     {
2570       if (unref)
2571         {
2572           GtkTreeIter parent_iter;
2573
2574           parent_iter.stamp = tree_model_sort->priv->stamp;
2575           parent_iter.user_data = sort_level->parent_level;
2576           parent_iter.user_data2 = sort_level->parent_elt;
2577
2578           gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort),
2579                                           &parent_iter);
2580         }
2581
2582       sort_level->parent_elt->children = NULL;
2583     }
2584   else
2585     priv->root = NULL;
2586
2587   g_sequence_free (sort_level->seq);
2588   sort_level->seq = NULL;
2589
2590   g_free (sort_level);
2591   sort_level = NULL;
2592 }
2593
2594 static void
2595 gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort)
2596 {
2597   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2598
2599   do
2600     {
2601       priv->stamp++;
2602     }
2603   while (priv->stamp == 0);
2604
2605   gtk_tree_model_sort_clear_cache (tree_model_sort);
2606 }
2607
2608 static void
2609 gtk_tree_model_sort_clear_cache_helper_iter (gpointer data,
2610                                              gpointer user_data)
2611 {
2612   GtkTreeModelSort *tree_model_sort = user_data;
2613   SortElt *elt = data;
2614
2615   if (elt->zero_ref_count > 0)
2616     gtk_tree_model_sort_clear_cache_helper (tree_model_sort, elt->children);
2617 }
2618
2619 static void
2620 gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
2621                                         SortLevel        *level)
2622 {
2623   g_assert (level != NULL);
2624
2625   g_sequence_foreach (level->seq, gtk_tree_model_sort_clear_cache_helper_iter,
2626                       tree_model_sort);
2627
2628   if (level->ref_count == 0 && level != tree_model_sort->priv->root)
2629     gtk_tree_model_sort_free_level (tree_model_sort, level, TRUE);
2630 }
2631
2632 /**
2633  * gtk_tree_model_sort_reset_default_sort_func:
2634  * @tree_model_sort: A #GtkTreeModelSort
2635  * 
2636  * This resets the default sort function to be in the 'unsorted' state.  That
2637  * is, it is in the same order as the child model. It will re-sort the model
2638  * to be in the same order as the child model only if the #GtkTreeModelSort
2639  * is in 'unsorted' state.
2640  **/
2641 void
2642 gtk_tree_model_sort_reset_default_sort_func (GtkTreeModelSort *tree_model_sort)
2643 {
2644   GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2645
2646   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2647
2648   if (priv->default_sort_destroy)
2649     {
2650       GDestroyNotify d = priv->default_sort_destroy;
2651
2652       priv->default_sort_destroy = NULL;
2653       d (priv->default_sort_data);
2654     }
2655
2656   priv->default_sort_func = NO_SORT_FUNC;
2657   priv->default_sort_data = NULL;
2658   priv->default_sort_destroy = NULL;
2659
2660   if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
2661     gtk_tree_model_sort_sort (tree_model_sort);
2662   priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
2663 }
2664
2665 /**
2666  * gtk_tree_model_sort_clear_cache:
2667  * @tree_model_sort: A #GtkTreeModelSort
2668  * 
2669  * This function should almost never be called.  It clears the @tree_model_sort
2670  * of any cached iterators that haven't been reffed with
2671  * gtk_tree_model_ref_node().  This might be useful if the child model being
2672  * sorted is static (and doesn't change often) and there has been a lot of
2673  * unreffed access to nodes.  As a side effect of this function, all unreffed
2674  * iters will be invalid.
2675  **/
2676 void
2677 gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
2678 {
2679   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2680
2681   if (tree_model_sort->priv->zero_ref_count > 0)
2682     gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->priv->root);
2683 }
2684
2685 static gboolean
2686 gtk_tree_model_sort_iter_is_valid_helper (GtkTreeIter *iter,
2687                                           SortLevel   *level)
2688 {
2689   GSequenceIter *siter;
2690   GSequenceIter *end_siter;
2691
2692   end_siter = g_sequence_get_end_iter (level->seq);
2693   for (siter = g_sequence_get_begin_iter (level->seq);
2694        siter != end_siter; siter = g_sequence_iter_next (siter))
2695     {
2696       SortElt *elt = g_sequence_get (siter);
2697
2698       if (iter->user_data == level && iter->user_data2 == elt)
2699         return TRUE;
2700
2701       if (elt->children)
2702         if (gtk_tree_model_sort_iter_is_valid_helper (iter, elt->children))
2703           return TRUE;
2704     }
2705
2706   return FALSE;
2707 }
2708
2709 /**
2710  * gtk_tree_model_sort_iter_is_valid:
2711  * @tree_model_sort: A #GtkTreeModelSort.
2712  * @iter: A #GtkTreeIter.
2713  *
2714  * <warning><para>
2715  * This function is slow. Only use it for debugging and/or testing purposes.
2716  * </para></warning>
2717  *
2718  * Checks if the given iter is a valid iter for this #GtkTreeModelSort.
2719  *
2720  * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
2721  *
2722  * Since: 2.2
2723  **/
2724 gboolean
2725 gtk_tree_model_sort_iter_is_valid (GtkTreeModelSort *tree_model_sort,
2726                                    GtkTreeIter      *iter)
2727 {
2728   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2729   g_return_val_if_fail (iter != NULL, FALSE);
2730
2731   if (!VALID_ITER (iter, tree_model_sort))
2732     return FALSE;
2733
2734   return gtk_tree_model_sort_iter_is_valid_helper (iter,
2735                                                    tree_model_sort->priv->root);
2736 }