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