]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodelsort.c
various cleanups, (get_child_iter_from_elt): removed,
[~andy/gtk] / gtk / gtktreemodelsort.c
1 /* gtktreemodelsort.c
2  * Copyright (C) 2000,2001  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  * Copyright (C) 2001,2002  Kristian Rietveld <kris@gtk.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /* NOTE: There is a potential for confusion in this code as to whether an iter,
22  * path or value refers to the GtkTreeModelSort model, or the child model being
23  * sorted.  As a convention, variables referencing the child model will have an
24  * s_ prefix before them (ie. s_iter, s_value, s_path);
25  */
26
27 /* ITER FORMAT:
28  *
29  * iter->stamp = tree_model_sort->stamp
30  * iter->user_data = SortLevel
31  * iter->user_data2 = SortElt
32  */
33
34 /* WARNING: this code is dangerous, can cause sleepless nights,
35  * can cause your dog to die among other bad things
36  *
37  * we warned you and we're not liable for any head injuries.
38  */
39
40 #include "gtktreemodelsort.h"
41 #include "gtktreesortable.h"
42 #include "gtktreestore.h"
43 #include "gtksignal.h"
44 #include "gtktreedatalist.h"
45 #include <string.h>
46 #include "gtkintl.h"
47
48 typedef struct _SortElt SortElt;
49 typedef struct _SortLevel SortLevel;
50 typedef struct _SortData SortData;
51 typedef struct _SortTuple SortTuple;
52
53 struct _SortElt
54 {
55   GtkTreeIter  iter;
56   SortLevel   *children;
57   gint         offset;
58   gint         ref_count;
59   gint         zero_ref_count;
60 };
61
62 struct _SortLevel
63 {
64   GArray    *array;
65   gint       ref_count;
66   SortElt   *parent_elt;
67   SortLevel *parent_level;
68 };
69
70 struct _SortData
71 {
72   GtkTreeModelSort *tree_model_sort;
73   GtkTreePath *parent_path;
74   gint parent_path_depth;
75   gint *parent_path_indices;
76   GtkTreeIterCompareFunc sort_func;
77   gpointer sort_data;
78 };
79
80 struct _SortTuple
81 {
82   SortElt   *elt;
83   gint       offset;  
84 };
85
86 /* Properties */
87 enum {
88   PROP_0,
89   /* Construct args */
90   PROP_MODEL
91 };
92
93
94
95 #define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) \
96         (((GtkTreeModelSort *)tree_model_sort)->child_flags&GTK_TREE_MODEL_ITERS_PERSIST)
97 #define SORT_ELT(sort_elt) ((SortElt *)sort_elt)
98 #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level)
99
100 #define GET_CHILD_ITER(tree_model_sort,child_iter,sort_iter) gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT (tree_model_sort), child_iter, sort_iter);
101
102 /* general (object/interface init, etc) */
103 static void gtk_tree_model_sort_init                  (GtkTreeModelSort      *tree_model_sort);
104 static void gtk_tree_model_sort_class_init            (GtkTreeModelSortClass *tree_model_sort_class);
105 static void gtk_tree_model_sort_tree_model_init       (GtkTreeModelIface     *iface);
106 static void gtk_tree_model_sort_tree_sortable_init    (GtkTreeSortableIface  *iface);
107 static void gtk_tree_model_sort_finalize              (GObject               *object);
108 static void gtk_tree_model_sort_set_property          (GObject               *object,
109                                                        guint                  prop_id,
110                                                        const GValue          *value,
111                                                        GParamSpec            *pspec);
112 static void gtk_tree_model_sort_get_property          (GObject               *object,
113                                                        guint                  prop_id,
114                                                        GValue                *value,
115                                                        GParamSpec            *pspec);
116
117 /* our signal handlers */
118 static void gtk_tree_model_sort_row_changed           (GtkTreeModel          *model,
119                                                        GtkTreePath           *start_path,
120                                                        GtkTreeIter           *start_iter,
121                                                        gpointer               data);
122 static void gtk_tree_model_sort_row_inserted          (GtkTreeModel          *model,
123                                                        GtkTreePath           *path,
124                                                        GtkTreeIter           *iter,
125                                                        gpointer               data);
126 static void gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel          *model,
127                                                        GtkTreePath           *path,
128                                                        GtkTreeIter           *iter,
129                                                        gpointer               data);
130 static void gtk_tree_model_sort_row_deleted           (GtkTreeModel          *model,
131                                                        GtkTreePath           *path,
132                                                        gpointer               data);
133 static void gtk_tree_model_sort_rows_reordered        (GtkTreeModel          *s_model,
134                                                        GtkTreePath           *s_path,
135                                                        GtkTreeIter           *s_iter,
136                                                        gint                  *new_order,
137                                                        gpointer               data);
138
139 /* TreeModel interface */
140 static guint        gtk_tree_model_sort_get_flags          (GtkTreeModel          *tree_model);
141 static gint         gtk_tree_model_sort_get_n_columns      (GtkTreeModel          *tree_model);
142 static GType        gtk_tree_model_sort_get_column_type    (GtkTreeModel          *tree_model,
143                                                             gint                   index);
144 static gboolean     gtk_tree_model_sort_get_iter           (GtkTreeModel          *tree_model,
145                                                             GtkTreeIter           *iter,
146                                                             GtkTreePath           *path);
147 static GtkTreePath *gtk_tree_model_sort_get_path           (GtkTreeModel          *tree_model,
148                                                             GtkTreeIter           *iter);
149 static void         gtk_tree_model_sort_get_value          (GtkTreeModel          *tree_model,
150                                                             GtkTreeIter           *iter,
151                                                             gint                   column,
152                                                             GValue                *value);
153 static gboolean     gtk_tree_model_sort_iter_next          (GtkTreeModel          *tree_model,
154                                                             GtkTreeIter           *iter);
155 static gboolean     gtk_tree_model_sort_iter_children      (GtkTreeModel          *tree_model,
156                                                             GtkTreeIter           *iter,
157                                                             GtkTreeIter           *parent);
158 static gboolean     gtk_tree_model_sort_iter_has_child     (GtkTreeModel          *tree_model,
159                                                             GtkTreeIter           *iter);
160 static gint         gtk_tree_model_sort_iter_n_children    (GtkTreeModel          *tree_model,
161                                                             GtkTreeIter           *iter);
162 static gboolean     gtk_tree_model_sort_iter_nth_child     (GtkTreeModel          *tree_model,
163                                                             GtkTreeIter           *iter,
164                                                             GtkTreeIter           *parent,
165                                                             gint                   n);
166 static gboolean     gtk_tree_model_sort_iter_parent        (GtkTreeModel          *tree_model,
167                                                             GtkTreeIter           *iter,
168                                                             GtkTreeIter           *child);
169 static void         gtk_tree_model_sort_ref_node           (GtkTreeModel          *tree_model,
170                                                             GtkTreeIter           *iter);
171 static void         gtk_tree_model_sort_unref_node         (GtkTreeModel          *tree_model,
172                                                             GtkTreeIter           *iter);
173
174 /* TreeSortable interface */
175 static gboolean     gtk_tree_model_sort_get_sort_column_id    (GtkTreeSortable        *sortable,
176                                                                gint                   *sort_column_id,
177                                                                GtkSortType            *order);
178 static void         gtk_tree_model_sort_set_sort_column_id    (GtkTreeSortable        *sortable,
179                                                                gint                    sort_column_id,
180                                                                GtkSortType        order);
181 static void         gtk_tree_model_sort_set_sort_func         (GtkTreeSortable        *sortable,
182                                                                gint                    sort_column_id,
183                                                                GtkTreeIterCompareFunc  func,
184                                                                gpointer                data,
185                                                                GtkDestroyNotify        destroy);
186 static void         gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable        *sortable,
187                                                                GtkTreeIterCompareFunc  func,
188                                                                gpointer                data,
189                                                                GtkDestroyNotify        destroy);
190 static gboolean     gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable     *sortable);
191
192 /* Private functions (sort funcs, level handling and other utils) */
193 static void         gtk_tree_model_sort_build_level       (GtkTreeModelSort *tree_model_sort,
194                                                            SortLevel        *parent_level,
195                                                            SortElt          *parent_elt);
196 static void         gtk_tree_model_sort_free_level        (GtkTreeModelSort *tree_model_sort,
197                                                            SortLevel        *sort_level);
198 static void         gtk_tree_model_sort_increment_stamp   (GtkTreeModelSort *tree_model_sort);
199 static void         gtk_tree_model_sort_sort_level        (GtkTreeModelSort *tree_model_sort,
200                                                            SortLevel        *level,
201                                                            gboolean          recurse,
202                                                            gboolean          emit_reordered);
203 static void         gtk_tree_model_sort_sort              (GtkTreeModelSort *tree_model_sort);
204 static gint         gtk_tree_model_sort_level_find_insert (GtkTreeModelSort *tree_model_sort,
205                                                            SortLevel        *level,
206                                                            GtkTreeIter      *iter,
207                                                            gboolean          skip_sort_elt);
208 static gboolean     gtk_tree_model_sort_insert_value      (GtkTreeModelSort *tree_model_sort,
209                                                            SortLevel        *level,
210                                                            GtkTreePath      *s_path,
211                                                            GtkTreeIter      *s_iter);
212 static GtkTreePath *gtk_tree_model_sort_elt_get_path      (SortLevel        *level,
213                                                            SortElt          *elt);
214 static void         gtk_tree_model_sort_set_model         (GtkTreeModelSort *tree_model_sort,
215                                                            GtkTreeModel     *child_model);
216 static GtkTreePath *gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
217                                                                          GtkTreePath      *child_path,
218                                                                          gboolean          build_levels);
219
220 static GObjectClass *parent_class = NULL;
221
222 GType
223 gtk_tree_model_sort_get_type (void)
224 {
225   static GType tree_model_sort_type = 0;
226   
227   if (!tree_model_sort_type)
228     {
229       static const GTypeInfo tree_model_sort_info =
230       {
231         sizeof (GtkTreeModelSortClass),
232         NULL,           /* base_init */
233         NULL,           /* base_finalize */
234         (GClassInitFunc) gtk_tree_model_sort_class_init,
235         NULL,           /* class_finalize */
236         NULL,           /* class_data */
237         sizeof (GtkTreeModelSort),
238         0,              /* n_preallocs */
239         (GInstanceInitFunc) gtk_tree_model_sort_init
240       };
241
242       static const GInterfaceInfo tree_model_info =
243       {
244         (GInterfaceInitFunc) gtk_tree_model_sort_tree_model_init,
245         NULL,
246         NULL
247       };
248
249       static const GInterfaceInfo sortable_info =
250       {
251         (GInterfaceInitFunc) gtk_tree_model_sort_tree_sortable_init,
252         NULL,
253         NULL
254       };
255
256       tree_model_sort_type = g_type_register_static (G_TYPE_OBJECT,
257                                                      "GtkTreeModelSort",
258                                                      &tree_model_sort_info, 0);
259       g_type_add_interface_static (tree_model_sort_type,
260                                    GTK_TYPE_TREE_MODEL,
261                                    &tree_model_info);
262       
263       g_type_add_interface_static (tree_model_sort_type,
264                                    GTK_TYPE_TREE_SORTABLE,
265                                    &sortable_info);
266     }
267
268   return tree_model_sort_type;
269 }
270
271 static void
272 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
273 {
274   tree_model_sort->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
275   tree_model_sort->stamp = 0;
276   tree_model_sort->zero_ref_count = 0;
277   tree_model_sort->root = NULL;
278   tree_model_sort->sort_list = NULL;
279 }
280
281 static void
282 gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
283 {
284   GObjectClass *object_class;
285
286   object_class = (GObjectClass *) class;
287   parent_class = g_type_class_peek_parent (class);
288
289   object_class->set_property = gtk_tree_model_sort_set_property;
290   object_class->get_property = gtk_tree_model_sort_get_property;
291
292   object_class->finalize = gtk_tree_model_sort_finalize;
293
294   /* Properties */
295   g_object_class_install_property (object_class,
296                                    PROP_MODEL,
297                                    g_param_spec_object ("model",
298                                                         _("TreeModelSort Model"),
299                                                         _("The model for the TreeModelSort to sort"),
300                                                         GTK_TYPE_TREE_MODEL,
301                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
302 }
303
304 static void
305 gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
306 {
307   iface->get_flags = gtk_tree_model_sort_get_flags;
308   iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
309   iface->get_column_type = gtk_tree_model_sort_get_column_type;
310   iface->get_iter = gtk_tree_model_sort_get_iter;
311   iface->get_path = gtk_tree_model_sort_get_path;
312   iface->get_value = gtk_tree_model_sort_get_value;
313   iface->iter_next = gtk_tree_model_sort_iter_next;
314   iface->iter_children = gtk_tree_model_sort_iter_children;
315   iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
316   iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
317   iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
318   iface->iter_parent = gtk_tree_model_sort_iter_parent;
319   iface->ref_node = gtk_tree_model_sort_ref_node;
320   iface->unref_node = gtk_tree_model_sort_unref_node;
321 }
322
323 static void
324 gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
325 {
326   iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
327   iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
328   iface->set_sort_func = gtk_tree_model_sort_set_sort_func;
329   iface->set_default_sort_func = gtk_tree_model_sort_set_default_sort_func;
330   iface->has_default_sort_func = gtk_tree_model_sort_has_default_sort_func;
331 }
332
333 /**
334  * gtk_tree_model_sort_new_with_model:
335  * @child_model: A #GtkTreeModel
336  *
337  * Creates a new #GtkTreeModel, with @child_model as the child_model.
338  *
339  * Return value: A new #GtkTreeModel.
340  */
341 GtkTreeModel *
342 gtk_tree_model_sort_new_with_model (GtkTreeModel      *child_model)
343 {
344   GtkTreeModel *retval;
345
346   g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
347
348   retval = GTK_TREE_MODEL (g_object_new (gtk_tree_model_sort_get_type (), NULL));
349
350   gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
351
352   return retval;
353 }
354
355 /* GObject callbacks */
356 static void
357 gtk_tree_model_sort_finalize (GObject *object)
358 {
359   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
360
361   gtk_tree_model_sort_set_model (tree_model_sort, NULL);
362
363   if (tree_model_sort->root)
364     gtk_tree_model_sort_free_level (tree_model_sort, tree_model_sort->root);
365
366   if (tree_model_sort->sort_list)
367     {
368       _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
369       tree_model_sort->sort_list = NULL;
370     }
371
372   /* must chain up */
373   parent_class->finalize (object);
374 }
375
376 static void
377 gtk_tree_model_sort_set_property (GObject      *object,
378                                   guint         prop_id,
379                                   const GValue *value,
380                                   GParamSpec   *pspec)
381 {
382   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
383
384   switch (prop_id)
385     {
386     case PROP_MODEL:
387       gtk_tree_model_sort_set_model (tree_model_sort, g_value_get_object (value));
388       break;
389     default:
390       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
391       break;
392     }
393 }
394
395 static void
396 gtk_tree_model_sort_get_property (GObject    *object,
397                                   guint       prop_id,
398                                   GValue     *value,
399                                   GParamSpec *pspec)
400 {
401   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
402
403   switch (prop_id)
404     {
405     case PROP_MODEL:
406       g_value_set_object (value, gtk_tree_model_sort_get_model(tree_model_sort));
407       break;
408     default:
409       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
410       break;
411     }
412 }
413
414 static void
415 gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
416                                  GtkTreePath  *start_s_path,
417                                  GtkTreeIter  *start_s_iter,
418                                  gpointer      data)
419 {
420   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
421   GtkTreePath *path = NULL;
422   GtkTreeIter iter;
423   GtkTreeIter tmpiter;
424   
425   SortElt tmp;
426   SortElt *elt;
427   SortLevel *level;
428
429   gboolean free_s_path = FALSE;
430
431   gint offset, index = 0, i;
432
433   g_return_if_fail (start_s_path != NULL || start_s_iter != NULL);
434
435 #ifdef VERBOSE
436   g_print ("::row_changed run\n");
437 #endif
438
439   if (!start_s_path)
440     {
441       free_s_path = TRUE;
442       start_s_path = gtk_tree_model_get_path (s_model, start_s_iter);
443     }
444
445   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
446                                                               start_s_path,
447                                                               FALSE);
448   if (!path)
449     {
450       if (free_s_path)
451         gtk_tree_path_free (start_s_path);
452       return;
453     }
454
455   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
456   
457   level = iter.user_data;
458   elt = iter.user_data2;
459   
460   if (level->array->len < 2 || tree_model_sort->sort_column_id == -1)
461     {
462       if (free_s_path)
463         gtk_tree_path_free (start_s_path);
464       
465       gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
466       
467       gtk_tree_path_free (path);
468       
469       return;
470     }
471
472   if (!GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
473     {
474       gtk_tree_model_get_iter (tree_model_sort->child_model,
475                                &tmpiter, start_s_path);
476     }
477
478   offset = elt->offset;
479
480   for (i = 0; i < level->array->len; i++)
481     if (elt->offset == g_array_index (level->array, SortElt, i).offset)
482       index = i;
483   
484   memcpy (&tmp, elt, sizeof (SortElt));
485   g_array_remove_index (level->array, index);
486
487   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
488     index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
489                                                    level,
490                                                    &tmp.iter,
491                                                    TRUE);
492   else
493     index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
494                                                    level,
495                                                    &tmpiter,
496                                                    TRUE);
497   
498   g_array_insert_val (level->array, index, tmp);
499
500   for (i = 0; i < level->array->len; i++)
501     if (g_array_index (level->array, SortElt, i).children)
502       g_array_index (level->array, SortElt, i).children->parent_elt = &g_array_index (level->array, SortElt, i);
503   
504   gtk_tree_path_up (path);
505   gtk_tree_path_append_index (path, index);
506     
507   gtk_tree_model_sort_increment_stamp (tree_model_sort);
508   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
509   
510   gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
511
512   gtk_tree_path_free (path);
513   if (free_s_path)
514     gtk_tree_path_free (start_s_path);
515 }
516
517 static void
518 gtk_tree_model_sort_row_inserted (GtkTreeModel          *s_model,
519                                   GtkTreePath           *s_path,
520                                   GtkTreeIter           *s_iter,
521                                   gpointer               data)
522 {
523   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
524   GtkTreePath *path;
525   GtkTreeIter iter;
526   GtkTreeIter real_s_iter;
527
528   gint i = 0;
529
530   gboolean free_s_path = FALSE;
531
532   SortElt *elt;
533   SortLevel *level;
534   SortLevel *parent_level = NULL;
535
536   parent_level = level = SORT_LEVEL (tree_model_sort->root);
537
538 #ifdef VERBOSE
539   g_print ("::row_inserted\n");
540 #endif
541
542   g_return_if_fail (s_path != NULL || s_iter != NULL);
543   
544   if (!s_path)
545     {
546       s_path = gtk_tree_model_get_path (s_model, s_iter);
547       free_s_path = TRUE;
548     }
549   
550   if (!s_iter)
551     gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
552   else
553     real_s_iter = *s_iter;
554
555   if (!tree_model_sort->root)
556     {
557       gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
558
559       /* the build level already put the inserted iter in the level,
560          so no need to handle this signal anymore */
561       
562       goto done_and_submit;
563     }
564   
565   /* find the parent level */
566   while (i < gtk_tree_path_get_depth (s_path) - 1)
567     {
568       gint j;
569
570       if (!level)
571         {
572           /* level not yet build, we won't cover this signal */
573           goto done;
574         }
575
576       if (level->array->len < gtk_tree_path_get_indices (s_path)[i])
577         {
578           g_warning ("A node was inserted with a parent that's not in the tree.\n"
579                      "This possibly means that a GtkTreeModel inserted a child node\n"
580                      "before the parent was inserted.");
581           goto done;
582         }
583       
584       elt = NULL;
585       for (j = 0; j < level->array->len; j++)
586         if (g_array_index (level->array, SortElt, j).offset == gtk_tree_path_get_indices (s_path)[i])
587           {
588             elt = &g_array_index (level->array, SortElt, j);
589             break;
590           }
591
592       g_return_if_fail (elt != NULL);
593
594       if (!elt->children)
595         {
596           GtkTreePath *tmppath;
597           GtkTreeIter  tmpiter;
598           
599           tmppath = gtk_tree_model_sort_elt_get_path (level, elt);
600           if (tmppath)
601             {
602               gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &tmpiter,
603                                        tmppath);
604               gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data),
605                                                     tmppath,
606                                                     &tmpiter);
607               gtk_tree_path_free (tmppath);
608             }
609
610           /* not covering this signal */
611           goto done;
612         }
613
614       level = elt->children;
615       parent_level = level;
616       i++;
617     }
618   
619   if (!parent_level)
620     goto done;
621   
622   if (!gtk_tree_model_sort_insert_value (tree_model_sort,
623                                          parent_level,
624                                          s_path,
625                                          &real_s_iter))
626     goto done;
627   
628  done_and_submit:
629   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
630                                                               s_path,
631                                                               FALSE);
632   
633   if (!path)
634     return;
635
636   gtk_tree_model_sort_increment_stamp (tree_model_sort);
637   
638   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
639   gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
640   gtk_tree_path_free (path);
641
642  done:
643   if (free_s_path)
644     gtk_tree_path_free (s_path);
645   
646   return;
647 }
648
649 static void
650 gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
651                                            GtkTreePath  *s_path,
652                                            GtkTreeIter  *s_iter,
653                                            gpointer      data)
654 {
655   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
656   GtkTreePath *path;
657   GtkTreeIter iter;
658
659   g_return_if_fail (s_path != NULL && s_iter != NULL);
660
661   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
662   if (path == NULL)
663     return;
664   
665   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
666   gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
667
668   gtk_tree_path_free (path);
669 }
670
671 /* FIXME: I still have doubts if this works */
672 static void
673 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
674                                  GtkTreePath  *s_path,
675                                  gpointer      data)
676 {
677   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
678   GtkTreePath *path = NULL;
679   SortElt *elt;
680   SortLevel *level;
681   GtkTreeIter iter;
682   gint offset;
683   gint i;
684   
685   g_return_if_fail (s_path != NULL);
686
687 #ifdef VERBOSE
688   g_print ("::row_deleted\n");
689 #endif
690
691   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
692   if (path == NULL)
693     return;
694
695   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
696
697   level = SORT_LEVEL (iter.user_data);
698   elt = SORT_ELT (iter.user_data2);
699   offset = elt->offset;
700
701   gtk_tree_model_sort_increment_stamp (tree_model_sort);
702   gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
703
704   while (elt->ref_count > 0)
705     gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
706
707   if (level->ref_count == 0 && level != tree_model_sort->root)
708     {
709       /* This will prune the level, so I can just emit the signal and not worry
710        * about cleaning this level up. */
711 #ifdef VERBOSE
712       g_print ("ref_count == 0, prune level\n");
713 #endif
714
715       gtk_tree_path_free (path);
716       return;
717     }
718
719   /* Remove the row */
720   for (i = 0; i < level->array->len; i++)
721     if (elt->offset == g_array_index (level->array, SortElt, i).offset)
722       break;
723
724   g_array_remove_index (level->array, i);
725       
726   /* update all offsets */
727   for (i = 0; i < level->array->len; i++)
728     {
729       elt = & (g_array_index (level->array, SortElt, i));
730       if (elt->offset > offset)
731         elt->offset--;
732       if (elt->children)
733         elt->children->parent_elt = elt;
734     }
735
736   gtk_tree_path_free (path);
737 }
738
739 static void
740 gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
741                                     GtkTreePath  *s_path,
742                                     GtkTreeIter  *s_iter,
743                                     gint         *new_order,
744                                     gpointer      data)
745 {
746   SortElt *elt;
747   SortLevel *level;
748   GtkTreeIter iter;
749   gint *tmp_array;
750   int i, j;
751   GtkTreePath *path;
752   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
753   
754   g_return_if_fail (new_order != NULL);
755
756   if (s_path == NULL || gtk_tree_path_get_indices (s_path) == NULL)
757     {
758       if (tree_model_sort->root == NULL)
759         return;
760       path = gtk_tree_path_new ();
761       level = SORT_LEVEL (tree_model_sort->root);
762     }
763   else
764     {
765       path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
766       if (path == NULL)
767         return;
768       gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
769
770       level = SORT_LEVEL (iter.user_data);
771       elt = SORT_ELT (iter.user_data2);
772
773       if (!elt->children)
774         {
775           gtk_tree_path_free (path);
776           return;
777         }
778
779       level = elt->children;
780     }
781
782   if (level->array->len < 2)
783     {
784       gtk_tree_path_free (path);
785       return;
786     }
787
788   tmp_array = g_new (int, level->array->len);
789   for (i = 0; i < level->array->len; i++)
790     {
791       for (j = 0; j < level->array->len; j++)
792         {
793           if (g_array_index (level->array, SortElt, i).offset == new_order[j])
794             tmp_array[i] = j;
795         }
796     }
797
798   for (i = 0; i < level->array->len; i++)
799     g_array_index (level->array, SortElt, i).offset = tmp_array[i];
800   g_free (tmp_array);
801
802   if (tree_model_sort->sort_column_id == -1 &&
803       tree_model_sort->default_sort_func == (GtkTreeIterCompareFunc) 0x1)
804     {
805       
806       gtk_tree_model_sort_sort_level (tree_model_sort, level,
807                                       FALSE, FALSE);
808       gtk_tree_model_sort_increment_stamp (tree_model_sort);
809       
810       if (gtk_tree_path_get_depth (path))
811         {
812           gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
813                                    &iter,
814                                    path);
815           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
816                                          path, &iter, new_order);
817         }
818       else
819         {
820           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
821                                          path, NULL, new_order);
822         }
823     }
824
825   gtk_tree_path_free (path);
826 }
827
828 /* Fulfill our model requirements */
829 static guint
830 gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model)
831 {
832   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
833
834   return 0;
835 }
836
837 static gint
838 gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
839 {
840   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
841
842   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
843
844   if (tree_model_sort->child_model == 0)
845     return 0;
846
847   return gtk_tree_model_get_n_columns (tree_model_sort->child_model);
848 }
849
850 static GType
851 gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
852                                      gint          index)
853 {
854   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), G_TYPE_INVALID);
855   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, G_TYPE_INVALID);
856
857   return gtk_tree_model_get_column_type (GTK_TREE_MODEL_SORT (tree_model)->child_model, index);
858 }
859
860 static gboolean
861 gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
862                               GtkTreeIter  *iter,
863                               GtkTreePath  *path)
864 {
865   GtkTreeModelSort *tree_model_sort;
866   gint *indices;
867   SortLevel *level;
868   gint depth, i;
869
870   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
871   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
872
873   tree_model_sort = (GtkTreeModelSort *) tree_model;
874   indices = gtk_tree_path_get_indices (path);
875
876   if (tree_model_sort->root == NULL)
877     gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
878   level = SORT_LEVEL (tree_model_sort->root);
879
880   depth = gtk_tree_path_get_depth (path);
881   if (depth == 0)
882     return FALSE;
883
884   for (i = 0; i < depth - 1; i++)
885     {
886       if ((level == NULL) ||
887           (level->array->len < indices[i]))
888         return FALSE;
889
890       if (g_array_index (level->array, SortElt, indices[i]).children == NULL)
891         gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, indices[i]));
892       level = g_array_index (level->array, SortElt, indices[i]).children;
893     }
894
895   if (level == NULL)
896     return FALSE;
897   iter->stamp = tree_model_sort->stamp;
898   iter->user_data = level;
899   iter->user_data2 = &g_array_index (level->array, SortElt, indices[depth - 1]);
900
901   return TRUE;
902 }
903
904 static GtkTreePath *
905 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
906                               GtkTreeIter  *iter)
907 {
908   GtkTreePath *retval;
909   SortLevel *level;
910   SortElt *elt;
911
912   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
913   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, NULL);
914   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, NULL);
915
916   retval = gtk_tree_path_new ();
917   level = iter->user_data;
918   elt = iter->user_data2;
919   while (level != NULL)
920     {
921       gtk_tree_path_prepend_index (retval, elt - (SortElt *)level->array->data);
922
923       elt = level->parent_elt;
924       level = level->parent_level;
925     }
926
927   return retval;
928 }
929
930 static void
931 gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
932                                GtkTreeIter  *iter,
933                                gint          column,
934                                GValue       *value)
935 {
936   GtkTreeIter child_iter;
937
938   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
939   g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
940   g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
941
942   GET_CHILD_ITER (tree_model, &child_iter, iter);
943   gtk_tree_model_get_value (GTK_TREE_MODEL_SORT (tree_model)->child_model,
944                             &child_iter, column, value);
945 }
946
947 static gboolean
948 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
949                                GtkTreeIter  *iter)
950 {
951   SortLevel *level;
952   SortElt *elt;
953
954   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
955   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
956   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
957
958   level = iter->user_data;
959   elt = iter->user_data2;
960
961   if (elt - (SortElt *)level->array->data >= level->array->len - 1)
962     {
963       iter->stamp = 0;
964       return FALSE;
965     }
966   iter->user_data2 = elt + 1;
967
968   return TRUE;
969 }
970
971 static gboolean
972 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
973                                    GtkTreeIter  *iter,
974                                    GtkTreeIter  *parent)
975 {
976   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
977   SortLevel *level;
978
979   iter->stamp = 0;
980   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
981   g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
982   if (parent) g_return_val_if_fail (tree_model_sort->stamp == parent->stamp, FALSE);
983
984   if (parent == NULL)
985     {
986       if (tree_model_sort->root == NULL)
987         gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
988       if (tree_model_sort->root == NULL)
989         return FALSE;
990
991       level = tree_model_sort->root;
992       iter->stamp = tree_model_sort->stamp;
993       iter->user_data = level;
994       iter->user_data2 = level->array->data;
995     }
996   else
997     {
998       if (((SortElt *)parent->user_data2)->children == NULL)
999         gtk_tree_model_sort_build_level (tree_model_sort,
1000                                          (SortLevel *)parent->user_data,
1001                                          (SortElt *)parent->user_data2);
1002       if (((SortElt *)parent->user_data2)->children == NULL)
1003         return FALSE;
1004       iter->stamp = tree_model_sort->stamp;
1005       iter->user_data = ((SortElt *)parent->user_data2)->children;
1006       iter->user_data2 = ((SortLevel *)iter->user_data)->array->data;
1007     }
1008   
1009   return TRUE;
1010 }
1011
1012 static gboolean
1013 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
1014                                     GtkTreeIter  *iter)
1015 {
1016   GtkTreeIter child_iter;
1017
1018   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1019   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
1020   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
1021
1022   GET_CHILD_ITER (tree_model, &child_iter, iter);
1023
1024   return gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter);
1025 }
1026
1027 static gint
1028 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
1029                                      GtkTreeIter  *iter)
1030 {
1031   GtkTreeIter child_iter;
1032
1033   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
1034   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, 0);
1035   if (iter) g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, 0);
1036
1037   if (iter == NULL)
1038     return gtk_tree_model_iter_n_children (GTK_TREE_MODEL_SORT (tree_model)->child_model, NULL);
1039
1040   GET_CHILD_ITER (tree_model, &child_iter, iter);
1041
1042   return gtk_tree_model_iter_n_children (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter);
1043 }
1044
1045 static gboolean
1046 gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
1047                                     GtkTreeIter  *iter,
1048                                     GtkTreeIter  *parent,
1049                                     gint          n)
1050 {
1051   SortLevel *level;
1052   /* We have this for the iter == parent case */
1053   GtkTreeIter children;
1054
1055   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1056   if (parent) g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
1057
1058   /* Use this instead of has_child to force us to build the level, if needed */
1059   if (gtk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE)
1060     {
1061       iter->stamp = 0;
1062       return FALSE;
1063     }
1064
1065   level = children.user_data;
1066   if (n >= level->array->len)
1067     {
1068       iter->stamp = 0;
1069       return FALSE;
1070     }
1071
1072   iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
1073   iter->user_data = level;
1074   iter->user_data2 = &g_array_index (level->array, SortElt, n);
1075
1076   return TRUE;
1077 }
1078
1079 static gboolean
1080 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
1081                                  GtkTreeIter  *iter,
1082                                  GtkTreeIter  *child)
1083 {
1084   SortLevel *level;
1085
1086   iter->stamp = 0;
1087   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1088   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
1089   g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == child->stamp, FALSE);
1090
1091   level = child->user_data;
1092
1093   if (level->parent_level)
1094     {
1095       iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
1096       iter->user_data = level->parent_level;
1097       iter->user_data2 = level->parent_elt;
1098
1099       return TRUE;
1100     }
1101   return FALSE;
1102 }
1103
1104 static void
1105 gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
1106                               GtkTreeIter  *iter)
1107 {
1108   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1109   SortLevel *level;
1110   SortElt *elt;
1111
1112   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
1113   g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
1114   g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
1115
1116   level = iter->user_data;
1117   elt = iter->user_data2;
1118
1119   elt->ref_count++;
1120   level->ref_count++;
1121   if (level->ref_count == 1)
1122     {
1123       SortLevel *parent_level = level->parent_level;
1124       SortElt *parent_elt = level->parent_elt;
1125       /* We were at zero -- time to decrement the zero_ref_count val */
1126       do
1127         {
1128           if (parent_elt)
1129             parent_elt->zero_ref_count--;
1130           else
1131             tree_model_sort->zero_ref_count--;
1132           
1133           if (parent_level)
1134             {
1135               parent_elt = parent_level->parent_elt;
1136               parent_level = parent_level->parent_level;
1137             }
1138         }
1139       while (parent_level);
1140     }
1141 }
1142
1143 static void
1144 gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
1145                                 GtkTreeIter  *iter)
1146 {
1147   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1148   SortLevel *level;
1149   SortElt *elt;
1150
1151   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
1152   g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
1153   g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
1154
1155   level = iter->user_data;
1156   elt = iter->user_data2;
1157
1158   g_return_if_fail (elt->ref_count > 0);
1159
1160   elt->ref_count--;
1161   level->ref_count--;
1162   if (level->ref_count == 0)
1163     {
1164       SortLevel *parent_level = level->parent_level;
1165       SortElt *parent_elt = level->parent_elt;
1166
1167       /* We are at zero -- time to increment the zero_ref_count val */
1168       while (parent_level)
1169         {
1170           parent_elt->zero_ref_count++;
1171           
1172           parent_elt = parent_level->parent_elt;
1173           parent_level = parent_level->parent_level;
1174         }
1175       tree_model_sort->zero_ref_count++;
1176     }
1177 }
1178
1179 /* Sortable interface */
1180 static gboolean
1181 gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
1182                                         gint            *sort_column_id,
1183                                         GtkSortType     *order)
1184 {
1185   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1186
1187   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (sortable), FALSE);
1188
1189   if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1190     return FALSE;
1191
1192   if (sort_column_id)
1193     *sort_column_id = tree_model_sort->sort_column_id;
1194   if (order)
1195     *order = tree_model_sort->order;
1196
1197   return TRUE;
1198 }
1199
1200 static void
1201 gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
1202                                         gint             sort_column_id,
1203                                         GtkSortType      order)
1204 {
1205   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1206   
1207   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
1208   
1209   if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1210     {
1211       GtkTreeDataSortHeader *header = NULL;
1212       
1213       header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1214                                                sort_column_id);
1215
1216       /* we want to make sure that we have a function */
1217       g_return_if_fail (header != NULL);
1218       g_return_if_fail (header->func != NULL);
1219     }
1220   else
1221     g_return_if_fail (tree_model_sort->default_sort_func != NULL);
1222
1223   if (tree_model_sort->sort_column_id == sort_column_id)
1224     {
1225       if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1226         {
1227           if (tree_model_sort->order == order)
1228             return;
1229         }
1230       else
1231         return;
1232     }
1233
1234   tree_model_sort->sort_column_id = sort_column_id;
1235   tree_model_sort->order = order;
1236
1237   gtk_tree_model_sort_sort (tree_model_sort);
1238   gtk_tree_sortable_sort_column_changed (sortable);
1239 }
1240
1241 static void
1242 gtk_tree_model_sort_set_sort_func (GtkTreeSortable        *sortable,
1243                                    gint                    sort_column_id,
1244                                    GtkTreeIterCompareFunc  func,
1245                                    gpointer                data,
1246                                    GtkDestroyNotify        destroy)
1247 {
1248   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1249   GtkTreeDataSortHeader *header = NULL;
1250   GList *list;
1251
1252   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
1253   g_return_if_fail (func != NULL);
1254
1255   for (list = tree_model_sort->sort_list; list; list = list->next)
1256     {
1257       header = (GtkTreeDataSortHeader *) list->data;
1258       
1259       if (header->sort_column_id == sort_column_id)
1260         break;
1261     }
1262
1263   if (header == NULL)
1264     {
1265       header = g_new0 (GtkTreeDataSortHeader, 1);
1266       header->sort_column_id = sort_column_id;
1267       tree_model_sort->sort_list = g_list_append (tree_model_sort->sort_list,
1268                                                   header);
1269     }
1270
1271   if (header->destroy)
1272     (* header->destroy) (header->data);
1273
1274   header->func = func;
1275   header->data = data;
1276   header->destroy = destroy;
1277 }
1278
1279 static void
1280 gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable        *sortable,
1281                                            GtkTreeIterCompareFunc  func,
1282                                            gpointer                data,
1283                                            GtkDestroyNotify        destroy)
1284 {
1285   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1286   
1287   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
1288   
1289   if (tree_model_sort->default_sort_destroy)
1290     (* tree_model_sort->default_sort_destroy) (tree_model_sort->default_sort_data);
1291
1292   tree_model_sort->default_sort_func = func;
1293   tree_model_sort->default_sort_data = data;
1294   tree_model_sort->default_sort_destroy = destroy;
1295 }
1296
1297 static gboolean
1298 gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
1299 {
1300   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1301
1302   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (sortable), FALSE);
1303
1304   return (tree_model_sort->default_sort_func != NULL);
1305 }
1306
1307 /* sorting code - private */
1308 static gint
1309 gtk_tree_model_sort_compare_func (gconstpointer a,
1310                                   gconstpointer b,
1311                                   gpointer      user_data)
1312 {
1313   SortData *data = (SortData *)user_data;
1314   GtkTreeModelSort *tree_model_sort = data->tree_model_sort;
1315   SortTuple *sa = (SortTuple *)a;
1316   SortTuple *sb = (SortTuple *)b;
1317
1318   GtkTreeIter iter_a, iter_b;
1319   gint retval;
1320
1321   /* shortcut, if we've the same offsets here, they should be equal */
1322   if (sa->offset == sb->offset)
1323     return 0;
1324
1325   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1326     {
1327       iter_a = sa->elt->iter;
1328       iter_b = sb->elt->iter;
1329     }
1330   else
1331     {
1332       data->parent_path_indices [data->parent_path_depth-1] = sa->elt->offset;
1333       gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort->child_model), &iter_a, data->parent_path);
1334       data->parent_path_indices [data->parent_path_depth-1] = sb->elt->offset;
1335       gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort->child_model), &iter_b, data->parent_path);
1336     }
1337
1338   retval = (* data->sort_func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1339                                 &iter_a, &iter_b,
1340                                 data->sort_data);
1341
1342   if (tree_model_sort->order == GTK_SORT_DESCENDING)
1343     {
1344       if (retval > 0)
1345         retval = -1;
1346       else if (retval < 0)
1347         retval = 1;
1348     }
1349
1350   return retval;
1351 }
1352
1353 static gint
1354 gtk_tree_model_sort_offset_compare_func (gconstpointer a,
1355                                          gconstpointer b,
1356                                          gpointer      user_data)
1357 {
1358   gint retval;
1359
1360   SortTuple *sa = (SortTuple *)a;
1361   SortTuple *sb = (SortTuple *)b;
1362
1363   SortData *data = (SortData *)user_data;
1364
1365   if (sa->elt->offset < sb->elt->offset)
1366     retval = -1;
1367   else if (sa->elt->offset > sb->elt->offset)
1368     retval = 1;
1369   else
1370     retval = 0;
1371
1372   if (data->tree_model_sort->order == GTK_SORT_DESCENDING)
1373     {
1374       if (retval > 0)
1375         retval = -1;
1376       else if (retval < 0)
1377         retval = 1;
1378     }
1379
1380   return retval;
1381 }
1382
1383 static void
1384 gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
1385                                 SortLevel        *level,
1386                                 gboolean          recurse,
1387                                 gboolean          emit_reordered)
1388 {
1389   gint i;
1390   GArray *sort_array;
1391   GArray *new_array;
1392   gint *new_order;
1393
1394   GtkTreeIter iter;
1395   GtkTreePath *path;
1396   
1397   SortData data;
1398
1399   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1400   g_return_if_fail (level != NULL);
1401   
1402   if (level->array->len < 1 && !((SortElt *)level->array->data)->children)
1403     return;
1404
1405   /* Set up data */
1406   data.tree_model_sort = tree_model_sort;
1407   if (level->parent_elt)
1408     {
1409       data.parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level,
1410                                                            level->parent_elt);
1411       gtk_tree_path_append_index (data.parent_path, 0);
1412     }
1413   else
1414     {
1415       data.parent_path = gtk_tree_path_new_root ();
1416     }
1417   data.parent_path_depth = gtk_tree_path_get_depth (data.parent_path);
1418   data.parent_path_indices = gtk_tree_path_get_indices (data.parent_path);
1419
1420   /* make the array to be sorted */
1421   sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), level->array->len);
1422   for (i = 0; i < level->array->len; i++)
1423     {
1424       SortTuple tuple;
1425
1426       tuple.elt = &g_array_index (level->array, SortElt, i);
1427       tuple.offset = i;
1428
1429       g_array_append_val (sort_array, tuple);
1430     }
1431
1432     if (tree_model_sort->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1433       {
1434         GtkTreeDataSortHeader *header = NULL;
1435
1436         header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1437                                                  tree_model_sort->sort_column_id);
1438       
1439         g_return_if_fail (header != NULL);
1440         g_return_if_fail (header->func != NULL);
1441       
1442         data.sort_func = header->func;
1443         data.sort_data = header->data;
1444       }
1445     else
1446       {
1447         /* absolutely SHOULD NOT happen: */
1448         g_return_if_fail (tree_model_sort->default_sort_func != NULL);
1449
1450         data.sort_func = tree_model_sort->default_sort_func;
1451         data.sort_data = tree_model_sort->default_sort_data;
1452       }
1453
1454   if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
1455       tree_model_sort->default_sort_func == (GtkTreeIterCompareFunc) 0x1)
1456     {
1457       g_array_sort_with_data (sort_array,
1458                               gtk_tree_model_sort_offset_compare_func,
1459                               &data);
1460     }
1461   else
1462     {
1463       g_array_sort_with_data (sort_array,
1464                               gtk_tree_model_sort_compare_func,
1465                               &data);
1466     }
1467
1468   gtk_tree_path_free (data.parent_path);
1469
1470   new_array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), level->array->len);
1471   new_order = g_new (gint, level->array->len);
1472
1473 #ifdef VERBOSE
1474   g_print ("---- sort\n");
1475 #endif
1476   for (i = 0; i < level->array->len; i++)
1477     {
1478       SortElt *elt;
1479       
1480       elt = g_array_index (sort_array, SortTuple, i).elt;
1481       new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1482
1483       g_array_append_val (new_array, *elt);
1484       elt = &g_array_index (new_array, SortElt, i);
1485       if (elt->children)
1486         elt->children->parent_elt = elt;
1487     }
1488
1489   g_array_free (level->array, TRUE);
1490   level->array = new_array;
1491   g_array_free (sort_array, TRUE);
1492
1493   if (emit_reordered)
1494     {
1495       if (level->parent_elt)
1496         {
1497           iter.stamp = tree_model_sort->stamp;
1498           iter.user_data = level->parent_level;
1499           iter.user_data2 = level->parent_elt;
1500
1501           path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort),
1502                                           &iter);
1503
1504           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1505                                          &iter, new_order);
1506         }
1507       else
1508         {
1509           /* toplevel list */
1510           path = gtk_tree_path_new ();
1511           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1512                                          NULL, new_order);
1513         }
1514
1515       gtk_tree_path_free (path);
1516     }
1517
1518   /* recurse, if possible */
1519   if (recurse)
1520     {
1521       for (i = 0; i < level->array->len; i++)
1522         {
1523           SortElt *elt = &g_array_index (level->array, SortElt, i);
1524
1525           if (elt->children)
1526             gtk_tree_model_sort_sort_level (tree_model_sort,
1527                                             elt->children,
1528                                             TRUE, emit_reordered);
1529         }
1530     }
1531   
1532   g_free (new_order);
1533 }    
1534
1535 static void
1536 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
1537 {
1538   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1539
1540   if (!tree_model_sort->root)
1541     return;
1542
1543   if (tree_model_sort->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1544     {
1545       GtkTreeDataSortHeader *header = NULL;
1546
1547       header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1548                                                tree_model_sort->sort_column_id);
1549
1550       /* we want to make sure that we have a function */
1551       g_return_if_fail (header != NULL);
1552       g_return_if_fail (header->func != NULL);
1553     }
1554   else
1555     g_return_if_fail (tree_model_sort->default_sort_func != NULL);
1556
1557   gtk_tree_model_sort_sort_level (tree_model_sort, tree_model_sort->root,
1558                                   TRUE, TRUE);
1559 }
1560
1561 /* signal helpers */
1562 static gint
1563 gtk_tree_model_sort_level_find_insert (GtkTreeModelSort *tree_model_sort,
1564                                        SortLevel        *level,
1565                                        GtkTreeIter      *iter,
1566                                        gboolean          skip_sort_elt)
1567 {
1568   gint middle;
1569   gint cmp;
1570   SortElt *tmp_elt;
1571   GtkTreeIter tmp_iter;
1572
1573   GtkTreeIterCompareFunc func;
1574   gpointer data;
1575   
1576   GtkTreePath *path;
1577
1578   {
1579     GtkTreeDataSortHeader *header;
1580     
1581     header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1582                                              tree_model_sort->sort_column_id);
1583     
1584     g_return_val_if_fail (header != NULL, 0);
1585     g_return_val_if_fail (header->func != NULL, 0);
1586     
1587     func = header->func;
1588     data = header->data;
1589   }
1590   
1591   for (middle = 0; middle < level->array->len; middle++)
1592     {
1593       tmp_elt = &(g_array_index (level->array, SortElt, middle));
1594
1595       if (!skip_sort_elt && SORT_ELT (iter->user_data2) == tmp_elt)
1596         continue;
1597       
1598       path = gtk_tree_model_sort_elt_get_path (level, tmp_elt);
1599       gtk_tree_model_get_iter (tree_model_sort->child_model,
1600                                &tmp_iter, path);
1601       gtk_tree_path_free (path);
1602
1603       if (tree_model_sort->order == GTK_SORT_ASCENDING)
1604         cmp = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1605                         &tmp_iter, iter, data);
1606       else
1607         cmp = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1608                         iter, &tmp_iter, data);
1609       
1610       if (cmp > 0)
1611         break;
1612     }
1613   
1614   return middle;
1615 }
1616
1617 static gboolean
1618 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
1619                                   SortLevel        *level,
1620                                   GtkTreePath      *s_path,
1621                                   GtkTreeIter      *s_iter)
1622 {
1623   gint offset, index, i;
1624   
1625   SortElt elt;
1626   SortElt *tmp_elt;
1627
1628   offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
1629   
1630   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1631     elt.iter = *s_iter;
1632   elt.offset = offset;
1633   elt.zero_ref_count = 0;
1634   elt.ref_count = 0;
1635   elt.children = NULL;
1636
1637   /* just insert it here, the ::row_changed signal will put the model
1638    * back in a nice sort order
1639    */
1640
1641   index = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path)-1];
1642   g_array_insert_vals (level->array, index, &elt, 1);
1643
1644   /* update all larger offsets */
1645   tmp_elt = SORT_ELT (level->array->data);
1646   for (i = 0; i < level->array->len; i++, tmp_elt++)
1647     {
1648       if ((tmp_elt->offset >= offset) && i != index)
1649         tmp_elt->offset++;
1650       if (tmp_elt->children)
1651         tmp_elt->children->parent_elt = tmp_elt;
1652     }
1653
1654   return TRUE;
1655 }
1656
1657 /* sort elt stuff */
1658 static GtkTreePath *
1659 gtk_tree_model_sort_elt_get_path (SortLevel *level,
1660                                   SortElt *elt)
1661 {
1662   SortLevel *walker = level;
1663   SortElt *walker2 = elt;
1664   GtkTreePath *path;
1665   
1666   g_return_val_if_fail (level != NULL, NULL);
1667   g_return_val_if_fail (elt != NULL, NULL);
1668
1669   path = gtk_tree_path_new ();
1670
1671   while (walker)
1672     {
1673       gtk_tree_path_prepend_index (path, walker2->offset);
1674       
1675       walker2 = walker->parent_elt;
1676       walker = walker->parent_level;
1677     }
1678
1679   return path;
1680 }
1681
1682 /**
1683  * gtk_tree_model_sort_set_model:
1684  * @tree_model_sort: The #GtkTreeModelSort.
1685  * @child_model: A #GtkTreeModel, or NULL.
1686  *
1687  * Sets the model of @tree_model_sort to be @model.  If @model is NULL, then the
1688  * old model is unset.  The sort function is unset as a result of this call.
1689  * The model will be in an unsorted state until a sort function is set.
1690  **/
1691 static void
1692 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
1693                                GtkTreeModel     *child_model)
1694 {
1695   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1696
1697   if (child_model)
1698     g_object_ref (G_OBJECT (child_model));
1699
1700   if (tree_model_sort->child_model)
1701     {
1702       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1703                                    tree_model_sort->changed_id);
1704       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1705                                    tree_model_sort->inserted_id);
1706       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1707                                    tree_model_sort->has_child_toggled_id);
1708       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1709                                    tree_model_sort->deleted_id);
1710       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1711                                    tree_model_sort->reordered_id);
1712
1713       /* reset our state */
1714       gtk_tree_model_sort_free_level (tree_model_sort, tree_model_sort->root);
1715       tree_model_sort->root = NULL;
1716       _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
1717       tree_model_sort->sort_list = NULL;
1718       g_object_unref (G_OBJECT (tree_model_sort->child_model));
1719     }
1720
1721   tree_model_sort->child_model = child_model;
1722
1723   if (child_model)
1724     {
1725       GType *types;
1726       gint i, n_columns;
1727
1728       g_object_ref (tree_model_sort->child_model);
1729       tree_model_sort->changed_id =
1730         g_signal_connect (child_model, "row_changed",
1731                           G_CALLBACK (gtk_tree_model_sort_row_changed),
1732                           tree_model_sort);
1733       tree_model_sort->inserted_id =
1734         g_signal_connect (child_model, "row_inserted",
1735                           G_CALLBACK (gtk_tree_model_sort_row_inserted),
1736                           tree_model_sort);
1737       tree_model_sort->has_child_toggled_id =
1738         g_signal_connect (child_model, "row_has_child_toggled",
1739                           G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
1740                           tree_model_sort);
1741       tree_model_sort->deleted_id =
1742         g_signal_connect (child_model, "row_deleted",
1743                           G_CALLBACK (gtk_tree_model_sort_row_deleted),
1744                           tree_model_sort);
1745       tree_model_sort->reordered_id =
1746         g_signal_connect (child_model, "rows_reordered",
1747                           G_CALLBACK (gtk_tree_model_sort_rows_reordered),
1748                           tree_model_sort);
1749
1750       tree_model_sort->child_flags = gtk_tree_model_get_flags (child_model);
1751       n_columns = gtk_tree_model_get_n_columns (child_model);
1752
1753       types = g_new (GType, n_columns);
1754       for (i = 0; i < n_columns; i++)
1755         types[i] = gtk_tree_model_get_column_type (child_model, i);
1756
1757       tree_model_sort->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
1758       g_free (types);
1759
1760       tree_model_sort->default_sort_func = (GtkTreeIterCompareFunc)0x1;
1761       tree_model_sort->stamp = g_random_int ();
1762     }
1763 }
1764
1765 /**
1766  * gtk_tree_model_sort_get_model:
1767  * @tree_model: a #GtkTreeModelSort
1768  *
1769  * Returns the model the #GtkTreeModelSort is sorting.
1770  *
1771  * Return value: the "child model" being sorted
1772  **/
1773 GtkTreeModel *
1774 gtk_tree_model_sort_get_model (GtkTreeModelSort  *tree_model)
1775 {
1776   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
1777
1778   return tree_model->child_model;
1779 }
1780
1781
1782 static GtkTreePath *
1783 gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
1784                                                      GtkTreePath      *child_path,
1785                                                      gboolean          build_levels)
1786 {
1787   gint *child_indices;
1788   GtkTreePath *retval;
1789   SortLevel *level;
1790   gint i;
1791
1792   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
1793   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
1794   g_return_val_if_fail (child_path != NULL, NULL);
1795
1796   retval = gtk_tree_path_new ();
1797   child_indices = gtk_tree_path_get_indices (child_path);
1798
1799   if (tree_model_sort->root == NULL && build_levels)
1800     gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1801   level = SORT_LEVEL (tree_model_sort->root);
1802     
1803   for (i = 0; i < gtk_tree_path_get_depth (child_path); i++)
1804     {
1805       gint j;
1806       gboolean found_child = FALSE;
1807
1808       if (!level)
1809         {
1810           gtk_tree_path_free (retval);
1811           return NULL;
1812         }
1813
1814       if (child_indices[i] >= level->array->len)
1815         {
1816           gtk_tree_path_free (retval);
1817           return NULL;
1818         }
1819       for (j = 0; j < level->array->len; j++)
1820         {
1821           if ((g_array_index (level->array, SortElt, j)).offset == child_indices[i])
1822             {
1823               gtk_tree_path_append_index (retval, j);
1824               if (g_array_index (level->array, SortElt, j).children == NULL && build_levels)
1825                 {
1826                   gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, j));
1827                 }
1828               level = g_array_index (level->array, SortElt, j).children;
1829               found_child = TRUE;
1830               break;
1831             }
1832         }
1833       if (! found_child)
1834         {
1835           gtk_tree_path_free (retval);
1836           return NULL;
1837         }
1838     }
1839
1840   return retval;
1841 }
1842
1843
1844 /**
1845  * gtk_tree_model_sort_convert_child_path_to_path:
1846  * @tree_model_sort: A #GtkTreeModelSort
1847  * @child_path: A #GtkTreePath to convert
1848  * 
1849  * Converts @child_path to a path relative to @tree_model_sort.  That is,
1850  * @child_path points to a path in the child model.  The returned path will
1851  * point to the same row in the sorted model.  If @child_path isn't a valid path
1852  * on the child model, then %NULL is returned.
1853  * 
1854  * Return value: A newly allocated #GtkTreePath, or %NULL
1855  **/
1856 GtkTreePath *
1857 gtk_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
1858                                                 GtkTreePath      *child_path)
1859 {
1860   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
1861   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
1862   g_return_val_if_fail (child_path != NULL, NULL);
1863
1864   return gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE);
1865 }
1866
1867 /**
1868  * gtk_tree_model_sort_convert_child_iter_to_iter:
1869  * @tree_model_sort: A #GtkTreeModelSort
1870  * @sort_iter: An uninitialized #GtkTreeIter.
1871  * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
1872  * 
1873  * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to
1874  * the row pointed at by @child_iter.
1875  **/
1876 void
1877 gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sort,
1878                                                 GtkTreeIter      *sort_iter,
1879                                                 GtkTreeIter      *child_iter)
1880 {
1881   GtkTreePath *child_path, *path;
1882
1883   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1884   g_return_if_fail (tree_model_sort->child_model != NULL);
1885   g_return_if_fail (sort_iter != NULL);
1886   g_return_if_fail (child_iter != NULL);
1887
1888   sort_iter->stamp = 0;
1889
1890   child_path = gtk_tree_model_get_path (tree_model_sort->child_model, child_iter);
1891   g_return_if_fail (child_path != NULL);
1892
1893   path = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path);
1894   gtk_tree_path_free (child_path);
1895   g_return_if_fail (path != NULL);
1896
1897   gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort), sort_iter, path);
1898   gtk_tree_path_free (path);
1899 }
1900
1901 /**
1902  * gtk_tree_model_sort_convert_path_to_child_path:
1903  * @tree_model_sort: A #GtkTreeModelSort
1904  * @sorted_path: A #GtkTreePath to convert
1905  * 
1906  * Converts @sort_path to a path on the child model of @tree_model_sort.  That
1907  * is, @sort_path points ot a location in @tree_model_sort.  The returned path
1908  * will point to the same location in the model not being sorted.  If @path does not point to a 
1909  * 
1910  * Return value: A newly allocated #GtkTreePath, or %NULL
1911  **/
1912 GtkTreePath *
1913 gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sort,
1914                                                 GtkTreePath      *sorted_path)
1915 {
1916   gint *sorted_indices;
1917   GtkTreePath *retval;
1918   SortLevel *level;
1919   gint i;
1920
1921   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
1922   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
1923   g_return_val_if_fail (sorted_path != NULL, NULL);
1924
1925   retval = gtk_tree_path_new ();
1926   sorted_indices = gtk_tree_path_get_indices (sorted_path);
1927   if (tree_model_sort->root == NULL)
1928     gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1929   level = SORT_LEVEL (tree_model_sort->root);
1930
1931   for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++)
1932     {
1933       if ((level == NULL) ||
1934           (level->array->len > sorted_indices[i]))
1935         {
1936           gtk_tree_path_free (retval);
1937           return NULL;
1938         }
1939       if (g_array_index (level->array, SortElt, sorted_indices[i]).children == NULL)
1940         gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, sorted_indices[i]));
1941       if (level == NULL)
1942         
1943       gtk_tree_path_append_index (retval, g_array_index (level->array, SortElt, i).offset);
1944     }
1945   
1946   return retval;
1947 }
1948
1949 /**
1950  * gtk_tree_model_sort_convert_iter_to_child_iter:
1951  * @tree_model_sort: A #GtkTreeModelSort
1952  * @child_iter: An uninitialized #GtkTreeIter
1953  * @sorted_iter: A valid #GtkTreeIter pointing to a row on @tree_model_sort.
1954  * 
1955  * Sets @child_iter to point to the row pointed to by *sorted_iter.
1956  **/
1957 void
1958 gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sort,
1959                                                 GtkTreeIter      *child_iter,
1960                                                 GtkTreeIter      *sorted_iter)
1961 {
1962   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1963   g_return_if_fail (tree_model_sort->child_model != NULL);
1964   g_return_if_fail (child_iter != NULL);
1965   g_return_if_fail (sorted_iter != NULL);
1966   g_return_if_fail (sorted_iter->stamp == tree_model_sort->stamp);
1967
1968   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1969     {
1970       *child_iter = SORT_ELT (sorted_iter->user_data2)->iter;
1971     }
1972   else
1973     {
1974       GtkTreePath *path;
1975
1976       path = gtk_tree_model_sort_elt_get_path (sorted_iter->user_data,
1977                                                sorted_iter->user_data2);
1978       gtk_tree_model_get_iter (tree_model_sort->child_model, child_iter, path);
1979       gtk_tree_path_free (path);
1980     }
1981 }
1982
1983 static void
1984 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
1985                                  SortLevel        *parent_level,
1986                                  SortElt          *parent_elt)
1987 {
1988   GtkTreeIter iter;
1989   SortLevel *new_level;
1990   gint length = 0;
1991   gint i;
1992
1993   g_assert (tree_model_sort->child_model != NULL);
1994
1995   if (parent_level == NULL)
1996     {
1997       if (gtk_tree_model_get_iter_root (tree_model_sort->child_model, &iter) == FALSE)
1998         return;
1999       length = gtk_tree_model_iter_n_children (tree_model_sort->child_model, NULL);
2000     }
2001   else
2002     {
2003       GtkTreeIter parent_iter;
2004       GtkTreeIter child_parent_iter;
2005
2006       parent_iter.stamp = tree_model_sort->stamp;
2007       parent_iter.user_data = parent_level;
2008       parent_iter.user_data2 = parent_elt;
2009
2010       gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2011                                                       &child_parent_iter,
2012                                                       &parent_iter);
2013       if (gtk_tree_model_iter_children (tree_model_sort->child_model,
2014                                         &iter,
2015                                         &child_parent_iter) == FALSE)
2016         return;
2017       length = gtk_tree_model_iter_n_children (tree_model_sort->child_model, &child_parent_iter);
2018     }
2019
2020   g_return_if_fail (length > 0);
2021
2022   new_level = g_new (SortLevel, 1);
2023   new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), length);
2024   new_level->ref_count = 0;
2025   new_level->parent_elt = parent_elt;
2026   new_level->parent_level = parent_level;
2027
2028   if (parent_elt)
2029     parent_elt->children = new_level;
2030   else
2031     tree_model_sort->root = new_level;
2032
2033   /* increase the count of zero ref_counts.*/
2034   while (parent_level)
2035     {
2036       parent_elt->zero_ref_count++;
2037
2038       parent_elt = parent_level->parent_elt;
2039       parent_level = parent_level->parent_level;
2040     }
2041   if (new_level != tree_model_sort->root)
2042     tree_model_sort->zero_ref_count++;
2043
2044   for (i = 0; i < length; i++)
2045     {
2046       SortElt sort_elt;
2047       sort_elt.offset = i;
2048       sort_elt.zero_ref_count = 0;
2049       sort_elt.ref_count = 0;
2050       sort_elt.children = NULL;
2051
2052       if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2053         {
2054           sort_elt.iter = iter;
2055           if (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter) == FALSE &&
2056               i < length - 1)
2057             {
2058               g_warning ("There is a discrepency between the sort model and the child model.");
2059               return;
2060             }
2061         }
2062       g_array_append_val (new_level->array, sort_elt);
2063     }
2064
2065 #ifdef VERBOSE
2066   g_print ("-- new level\n");
2067 #endif
2068
2069   /* sort level */
2070   gtk_tree_model_sort_sort_level (tree_model_sort, new_level,
2071                                   FALSE, FALSE);
2072 }
2073
2074 static void
2075 gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
2076                                 SortLevel        *sort_level)
2077 {
2078   gint i;
2079
2080 #ifdef VERBOSE
2081   g_print ("freeing level: %p, %p (ref = %d)\n", sort_level, 
2082            sort_level->array, sort_level->ref_count);
2083   g_print ("-- parents - elt: %p, level %p\n",
2084            sort_level->parent_elt, sort_level->parent_level);
2085 #endif
2086
2087   g_assert (sort_level);
2088
2089 #ifdef VERBOSE  
2090   g_print ("-- freeing current level (ref = %d)\n",sort_level->ref_count);
2091 #endif
2092
2093   if (sort_level->ref_count == 0)
2094     {
2095       SortLevel *parent_level = sort_level->parent_level;
2096       SortElt *parent_elt = sort_level->parent_elt;
2097
2098       do
2099         {
2100           if (parent_elt)
2101             parent_elt->zero_ref_count--;
2102           else
2103             tree_model_sort->zero_ref_count--;
2104           
2105           if (parent_level)
2106             {
2107               parent_elt = parent_level->parent_elt;
2108               parent_level = parent_level->parent_level;
2109             }
2110         }
2111       while (parent_level);
2112     }
2113   
2114 #ifdef VERBOSE
2115   g_print ("-- freeing children\n");
2116 #endif
2117   
2118   for (i = 0; i < sort_level->array->len; i++)
2119     {
2120       if (g_array_index (sort_level->array, SortElt, i).children)
2121         gtk_tree_model_sort_free_level (tree_model_sort, 
2122                                         SORT_LEVEL(g_array_index (sort_level->array, SortElt, i).children));
2123     }
2124   
2125   if (sort_level->parent_elt)
2126     {
2127       sort_level->parent_elt->children = NULL;
2128     }
2129   else
2130     {
2131       tree_model_sort->root = NULL;
2132     }
2133
2134 #ifdef VERBOSE  
2135   g_print ("free %p\n", sort_level->array);
2136 #endif
2137
2138   g_array_free (sort_level->array, TRUE);
2139   sort_level->array = NULL;
2140
2141 #ifdef VERBOSE
2142   g_print ("free %p\n", sort_level);
2143 #endif
2144
2145   g_free (sort_level);
2146   sort_level = NULL;
2147
2148 #ifdef VERBOSE
2149   g_print ("-------- done ---------\n");
2150 #endif
2151 }
2152
2153 static void
2154 gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort)
2155 {
2156   while (tree_model_sort->stamp == 0) tree_model_sort->stamp++;
2157
2158   gtk_tree_model_sort_clear_cache (tree_model_sort);
2159 }
2160
2161 static void
2162 gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
2163                                         SortLevel        *level)
2164 {
2165   gint i;
2166
2167   g_assert (level != NULL);
2168
2169   for (i = 0; i < level->array->len; i++)
2170     {
2171       if (g_array_index (level->array, SortElt, i).zero_ref_count > 0)
2172         gtk_tree_model_sort_clear_cache_helper (tree_model_sort, g_array_index (level->array, SortElt, i).children);
2173     }
2174
2175   if (level->ref_count == 0 && level != tree_model_sort->root)
2176     {
2177       gtk_tree_model_sort_free_level (tree_model_sort, level);
2178       return;
2179     }
2180 }
2181
2182 /**
2183  * gtk_tree_model_sort_reset_default_sort_func:
2184  * @tree_model_sort: A #GtkTreeModelSort
2185  * 
2186  * This resets the default sort function to be in the 'unsorted' state.  That
2187  * is, it is in the same order as the child model.
2188  **/
2189 void
2190 gtk_tree_model_sort_reset_default_sort_func (GtkTreeModelSort *tree_model_sort)
2191 {
2192   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2193
2194   if (tree_model_sort->default_sort_destroy)
2195     (* tree_model_sort->default_sort_destroy) (tree_model_sort->default_sort_data);
2196
2197   tree_model_sort->default_sort_func = (GtkTreeIterCompareFunc) 0x1;
2198   tree_model_sort->default_sort_data = NULL;
2199   tree_model_sort->default_sort_destroy = NULL;
2200   tree_model_sort->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
2201 }
2202
2203 /**
2204  * gtk_tree_model_sort_clear_cache:
2205  * @tree_model_sort: A #GtkTreeModelSort
2206  * 
2207  * This function should almost never be called.  It clears the @tree_model_sort
2208  * of any cached iterators that haven't been reffed with
2209  * gtk_tree_model_ref_node().  This might be useful if the child model being
2210  * sorted is static (and doesn't change often) and there has been a lot of
2211  * unreffed access to nodes.  As a side effect of this function, all unreffed
2212  * iters will be invalid.
2213  **/
2214 void
2215 gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
2216 {
2217   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2218
2219   if (tree_model_sort->zero_ref_count)
2220     gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->root);
2221 }