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