]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodelsort.c
add some more stamp checks (pointed out by Anders Carlsson)
[~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     if (!header)
1585       return 0;
1586
1587     g_return_val_if_fail (header->func != NULL, 0);
1588
1589     func = header->func;
1590     data = header->data;
1591   }
1592
1593   for (middle = 0; middle < level->array->len; middle++)
1594     {
1595       tmp_elt = &(g_array_index (level->array, SortElt, middle));
1596
1597       if (!skip_sort_elt && SORT_ELT (iter->user_data2) == tmp_elt)
1598         continue;
1599
1600       path = gtk_tree_model_sort_elt_get_path (level, tmp_elt);
1601       gtk_tree_model_get_iter (tree_model_sort->child_model,
1602                                &tmp_iter, path);
1603       gtk_tree_path_free (path);
1604
1605       if (tree_model_sort->order == GTK_SORT_ASCENDING)
1606         cmp = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1607                         &tmp_iter, iter, data);
1608       else
1609         cmp = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1610                         iter, &tmp_iter, data);
1611
1612       if (cmp > 0)
1613         break;
1614     }
1615
1616   return middle;
1617 }
1618
1619 static gboolean
1620 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
1621                                   SortLevel        *level,
1622                                   GtkTreePath      *s_path,
1623                                   GtkTreeIter      *s_iter)
1624 {
1625   gint offset, index, i;
1626
1627   SortElt elt;
1628   SortElt *tmp_elt;
1629
1630   offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
1631
1632   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1633     elt.iter = *s_iter;
1634   elt.offset = offset;
1635   elt.zero_ref_count = 0;
1636   elt.ref_count = 0;
1637   elt.children = NULL;
1638
1639   index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
1640                                                  level, s_iter,
1641                                                  FALSE);
1642
1643   g_array_insert_vals (level->array, index, &elt, 1);
1644
1645   /* update all larger offsets */
1646   tmp_elt = SORT_ELT (level->array->data);
1647   for (i = 0; i < level->array->len; i++, tmp_elt++)
1648     {
1649       if ((tmp_elt->offset >= offset) && i != index)
1650         tmp_elt->offset++;
1651       if (tmp_elt->children)
1652         tmp_elt->children->parent_elt = tmp_elt;
1653     }
1654
1655   return TRUE;
1656 }
1657
1658 /* sort elt stuff */
1659 static GtkTreePath *
1660 gtk_tree_model_sort_elt_get_path (SortLevel *level,
1661                                   SortElt *elt)
1662 {
1663   SortLevel *walker = level;
1664   SortElt *walker2 = elt;
1665   GtkTreePath *path;
1666
1667   g_return_val_if_fail (level != NULL, NULL);
1668   g_return_val_if_fail (elt != NULL, NULL);
1669
1670   path = gtk_tree_path_new ();
1671
1672   while (walker)
1673     {
1674       gtk_tree_path_prepend_index (path, walker2->offset);
1675
1676       walker2 = walker->parent_elt;
1677       walker = walker->parent_level;
1678     }
1679
1680   return path;
1681 }
1682
1683 /**
1684  * gtk_tree_model_sort_set_model:
1685  * @tree_model_sort: The #GtkTreeModelSort.
1686  * @child_model: A #GtkTreeModel, or NULL.
1687  *
1688  * Sets the model of @tree_model_sort to be @model.  If @model is NULL, then the
1689  * old model is unset.  The sort function is unset as a result of this call.
1690  * The model will be in an unsorted state until a sort function is set.
1691  **/
1692 static void
1693 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
1694                                GtkTreeModel     *child_model)
1695 {
1696   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1697
1698   if (child_model)
1699     g_object_ref (G_OBJECT (child_model));
1700
1701   if (tree_model_sort->child_model)
1702     {
1703       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1704                                    tree_model_sort->changed_id);
1705       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1706                                    tree_model_sort->inserted_id);
1707       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1708                                    tree_model_sort->has_child_toggled_id);
1709       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1710                                    tree_model_sort->deleted_id);
1711       g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
1712                                    tree_model_sort->reordered_id);
1713
1714       /* reset our state */
1715       if (tree_model_sort->root)
1716         gtk_tree_model_sort_free_level (tree_model_sort, tree_model_sort->root);
1717       tree_model_sort->root = NULL;
1718       _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
1719       tree_model_sort->sort_list = NULL;
1720       g_object_unref (G_OBJECT (tree_model_sort->child_model));
1721     }
1722
1723   tree_model_sort->child_model = child_model;
1724
1725   if (child_model)
1726     {
1727       GType *types;
1728       gint i, n_columns;
1729
1730       g_object_ref (tree_model_sort->child_model);
1731       tree_model_sort->changed_id =
1732         g_signal_connect (child_model, "row_changed",
1733                           G_CALLBACK (gtk_tree_model_sort_row_changed),
1734                           tree_model_sort);
1735       tree_model_sort->inserted_id =
1736         g_signal_connect (child_model, "row_inserted",
1737                           G_CALLBACK (gtk_tree_model_sort_row_inserted),
1738                           tree_model_sort);
1739       tree_model_sort->has_child_toggled_id =
1740         g_signal_connect (child_model, "row_has_child_toggled",
1741                           G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
1742                           tree_model_sort);
1743       tree_model_sort->deleted_id =
1744         g_signal_connect (child_model, "row_deleted",
1745                           G_CALLBACK (gtk_tree_model_sort_row_deleted),
1746                           tree_model_sort);
1747       tree_model_sort->reordered_id =
1748         g_signal_connect (child_model, "rows_reordered",
1749                           G_CALLBACK (gtk_tree_model_sort_rows_reordered),
1750                           tree_model_sort);
1751
1752       tree_model_sort->child_flags = gtk_tree_model_get_flags (child_model);
1753       n_columns = gtk_tree_model_get_n_columns (child_model);
1754
1755       types = g_new (GType, n_columns);
1756       for (i = 0; i < n_columns; i++)
1757         types[i] = gtk_tree_model_get_column_type (child_model, i);
1758
1759       tree_model_sort->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
1760       g_free (types);
1761
1762       tree_model_sort->default_sort_func = (GtkTreeIterCompareFunc)0x1;
1763       tree_model_sort->stamp = g_random_int ();
1764     }
1765 }
1766
1767 /**
1768  * gtk_tree_model_sort_get_model:
1769  * @tree_model: a #GtkTreeModelSort
1770  *
1771  * Returns the model the #GtkTreeModelSort is sorting.
1772  *
1773  * Return value: the "child model" being sorted
1774  **/
1775 GtkTreeModel *
1776 gtk_tree_model_sort_get_model (GtkTreeModelSort  *tree_model)
1777 {
1778   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
1779
1780   return tree_model->child_model;
1781 }
1782
1783
1784 static GtkTreePath *
1785 gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
1786                                                      GtkTreePath      *child_path,
1787                                                      gboolean          build_levels)
1788 {
1789   gint *child_indices;
1790   GtkTreePath *retval;
1791   SortLevel *level;
1792   gint i;
1793
1794   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
1795   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
1796   g_return_val_if_fail (child_path != NULL, NULL);
1797
1798   retval = gtk_tree_path_new ();
1799   child_indices = gtk_tree_path_get_indices (child_path);
1800
1801   if (tree_model_sort->root == NULL && build_levels)
1802     gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1803   level = SORT_LEVEL (tree_model_sort->root);
1804
1805   for (i = 0; i < gtk_tree_path_get_depth (child_path); i++)
1806     {
1807       gint j;
1808       gboolean found_child = FALSE;
1809
1810       if (!level)
1811         {
1812           gtk_tree_path_free (retval);
1813           return NULL;
1814         }
1815
1816       if (child_indices[i] >= level->array->len)
1817         {
1818           gtk_tree_path_free (retval);
1819           return NULL;
1820         }
1821       for (j = 0; j < level->array->len; j++)
1822         {
1823           if ((g_array_index (level->array, SortElt, j)).offset == child_indices[i])
1824             {
1825               gtk_tree_path_append_index (retval, j);
1826               if (g_array_index (level->array, SortElt, j).children == NULL && build_levels)
1827                 {
1828                   gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, j));
1829                 }
1830               level = g_array_index (level->array, SortElt, j).children;
1831               found_child = TRUE;
1832               break;
1833             }
1834         }
1835       if (! found_child)
1836         {
1837           gtk_tree_path_free (retval);
1838           return NULL;
1839         }
1840     }
1841
1842   return retval;
1843 }
1844
1845
1846 /**
1847  * gtk_tree_model_sort_convert_child_path_to_path:
1848  * @tree_model_sort: A #GtkTreeModelSort
1849  * @child_path: A #GtkTreePath to convert
1850  * 
1851  * Converts @child_path to a path relative to @tree_model_sort.  That is,
1852  * @child_path points to a path in the child model.  The returned path will
1853  * point to the same row in the sorted model.  If @child_path isn't a valid path
1854  * on the child model, then %NULL is returned.
1855  * 
1856  * Return value: A newly allocated #GtkTreePath, or %NULL
1857  **/
1858 GtkTreePath *
1859 gtk_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
1860                                                 GtkTreePath      *child_path)
1861 {
1862   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
1863   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
1864   g_return_val_if_fail (child_path != NULL, NULL);
1865
1866   return gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE);
1867 }
1868
1869 /**
1870  * gtk_tree_model_sort_convert_child_iter_to_iter:
1871  * @tree_model_sort: A #GtkTreeModelSort
1872  * @sort_iter: An uninitialized #GtkTreeIter.
1873  * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
1874  * 
1875  * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to
1876  * the row pointed at by @child_iter.
1877  **/
1878 void
1879 gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sort,
1880                                                 GtkTreeIter      *sort_iter,
1881                                                 GtkTreeIter      *child_iter)
1882 {
1883   GtkTreePath *child_path, *path;
1884
1885   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1886   g_return_if_fail (tree_model_sort->child_model != NULL);
1887   g_return_if_fail (sort_iter != NULL);
1888   g_return_if_fail (child_iter != NULL);
1889
1890   sort_iter->stamp = 0;
1891
1892   child_path = gtk_tree_model_get_path (tree_model_sort->child_model, child_iter);
1893   g_return_if_fail (child_path != NULL);
1894
1895   path = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path);
1896   gtk_tree_path_free (child_path);
1897   g_return_if_fail (path != NULL);
1898
1899   gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort), sort_iter, path);
1900   gtk_tree_path_free (path);
1901 }
1902
1903 /**
1904  * gtk_tree_model_sort_convert_path_to_child_path:
1905  * @tree_model_sort: A #GtkTreeModelSort
1906  * @sorted_path: A #GtkTreePath to convert
1907  * 
1908  * Converts @sort_path to a path on the child model of @tree_model_sort.  That
1909  * is, @sort_path points ot a location in @tree_model_sort.  The returned path
1910  * will point to the same location in the model not being sorted.  If @path does not point to a 
1911  * 
1912  * Return value: A newly allocated #GtkTreePath, or %NULL
1913  **/
1914 GtkTreePath *
1915 gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sort,
1916                                                 GtkTreePath      *sorted_path)
1917 {
1918   gint *sorted_indices;
1919   GtkTreePath *retval;
1920   SortLevel *level;
1921   gint i;
1922
1923   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
1924   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
1925   g_return_val_if_fail (sorted_path != NULL, NULL);
1926
1927   retval = gtk_tree_path_new ();
1928   sorted_indices = gtk_tree_path_get_indices (sorted_path);
1929   if (tree_model_sort->root == NULL)
1930     gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1931   level = SORT_LEVEL (tree_model_sort->root);
1932
1933   for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++)
1934     {
1935       if ((level == NULL) ||
1936           (level->array->len > sorted_indices[i]))
1937         {
1938           gtk_tree_path_free (retval);
1939           return NULL;
1940         }
1941       if (g_array_index (level->array, SortElt, sorted_indices[i]).children == NULL)
1942         gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, sorted_indices[i]));
1943       if (level == NULL)
1944
1945       gtk_tree_path_append_index (retval, g_array_index (level->array, SortElt, i).offset);
1946     }
1947  
1948   return retval;
1949 }
1950
1951 /**
1952  * gtk_tree_model_sort_convert_iter_to_child_iter:
1953  * @tree_model_sort: A #GtkTreeModelSort
1954  * @child_iter: An uninitialized #GtkTreeIter
1955  * @sorted_iter: A valid #GtkTreeIter pointing to a row on @tree_model_sort.
1956  * 
1957  * Sets @child_iter to point to the row pointed to by *sorted_iter.
1958  **/
1959 void
1960 gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sort,
1961                                                 GtkTreeIter      *child_iter,
1962                                                 GtkTreeIter      *sorted_iter)
1963 {
1964   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1965   g_return_if_fail (tree_model_sort->child_model != NULL);
1966   g_return_if_fail (child_iter != NULL);
1967   g_return_if_fail (sorted_iter != NULL);
1968   g_return_if_fail (sorted_iter->stamp == tree_model_sort->stamp);
1969
1970   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1971     {
1972       *child_iter = SORT_ELT (sorted_iter->user_data2)->iter;
1973     }
1974   else
1975     {
1976       GtkTreePath *path;
1977
1978       path = gtk_tree_model_sort_elt_get_path (sorted_iter->user_data,
1979                                                sorted_iter->user_data2);
1980       gtk_tree_model_get_iter (tree_model_sort->child_model, child_iter, path);
1981       gtk_tree_path_free (path);
1982     }
1983 }
1984
1985 static void
1986 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
1987                                  SortLevel        *parent_level,
1988                                  SortElt          *parent_elt)
1989 {
1990   GtkTreeIter iter;
1991   SortLevel *new_level;
1992   gint length = 0;
1993   gint i;
1994
1995   g_assert (tree_model_sort->child_model != NULL);
1996
1997   if (parent_level == NULL)
1998     {
1999       if (gtk_tree_model_get_iter_root (tree_model_sort->child_model, &iter) == FALSE)
2000         return;
2001       length = gtk_tree_model_iter_n_children (tree_model_sort->child_model, NULL);
2002     }
2003   else
2004     {
2005       GtkTreeIter parent_iter;
2006       GtkTreeIter child_parent_iter;
2007
2008       parent_iter.stamp = tree_model_sort->stamp;
2009       parent_iter.user_data = parent_level;
2010       parent_iter.user_data2 = parent_elt;
2011
2012       gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2013                                                       &child_parent_iter,
2014                                                       &parent_iter);
2015       if (gtk_tree_model_iter_children (tree_model_sort->child_model,
2016                                         &iter,
2017                                         &child_parent_iter) == FALSE)
2018         return;
2019       length = gtk_tree_model_iter_n_children (tree_model_sort->child_model, &child_parent_iter);
2020     }
2021
2022   g_return_if_fail (length > 0);
2023
2024   new_level = g_new (SortLevel, 1);
2025   new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), length);
2026   new_level->ref_count = 0;
2027   new_level->parent_elt = parent_elt;
2028   new_level->parent_level = parent_level;
2029
2030   if (parent_elt)
2031     parent_elt->children = new_level;
2032   else
2033     tree_model_sort->root = new_level;
2034
2035   /* increase the count of zero ref_counts.*/
2036   while (parent_level)
2037     {
2038       parent_elt->zero_ref_count++;
2039
2040       parent_elt = parent_level->parent_elt;
2041       parent_level = parent_level->parent_level;
2042     }
2043   if (new_level != tree_model_sort->root)
2044     tree_model_sort->zero_ref_count++;
2045
2046   for (i = 0; i < length; i++)
2047     {
2048       SortElt sort_elt;
2049       sort_elt.offset = i;
2050       sort_elt.zero_ref_count = 0;
2051       sort_elt.ref_count = 0;
2052       sort_elt.children = NULL;
2053
2054       if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2055         {
2056           sort_elt.iter = iter;
2057           if (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter) == FALSE &&
2058               i < length - 1)
2059             {
2060               g_warning ("There is a discrepency between the sort model and the child model.");
2061               return;
2062             }
2063         }
2064       g_array_append_val (new_level->array, sort_elt);
2065     }
2066
2067 #ifdef VERBOSE
2068   g_print ("-- new level\n");
2069 #endif
2070
2071   /* sort level */
2072   gtk_tree_model_sort_sort_level (tree_model_sort, new_level,
2073                                   FALSE, FALSE);
2074 }
2075
2076 static void
2077 gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
2078                                 SortLevel        *sort_level)
2079 {
2080   gint i;
2081
2082 #ifdef VERBOSE
2083   g_print ("freeing level: %p, %p (ref = %d)\n", sort_level, 
2084            sort_level->array, sort_level->ref_count);
2085   g_print ("-- parents - elt: %p, level %p\n",
2086            sort_level->parent_elt, sort_level->parent_level);
2087 #endif
2088
2089   g_assert (sort_level);
2090
2091 #ifdef VERBOSE  
2092   g_print ("-- freeing current level (ref = %d)\n",sort_level->ref_count);
2093 #endif
2094
2095   if (sort_level->ref_count == 0)
2096     {
2097       SortLevel *parent_level = sort_level->parent_level;
2098       SortElt *parent_elt = sort_level->parent_elt;
2099
2100       do
2101         {
2102           if (parent_elt)
2103             parent_elt->zero_ref_count--;
2104           else
2105             tree_model_sort->zero_ref_count--;
2106
2107           if (parent_level)
2108             {
2109               parent_elt = parent_level->parent_elt;
2110               parent_level = parent_level->parent_level;
2111             }
2112         }
2113       while (parent_level);
2114     }
2115
2116 #ifdef VERBOSE
2117   g_print ("-- freeing children\n");
2118 #endif
2119
2120   for (i = 0; i < sort_level->array->len; i++)
2121     {
2122       if (g_array_index (sort_level->array, SortElt, i).children)
2123         gtk_tree_model_sort_free_level (tree_model_sort, 
2124                                         SORT_LEVEL(g_array_index (sort_level->array, SortElt, i).children));
2125     }
2126
2127   if (sort_level->parent_elt)
2128     {
2129       sort_level->parent_elt->children = NULL;
2130     }
2131   else
2132     {
2133       tree_model_sort->root = NULL;
2134     }
2135
2136 #ifdef VERBOSE  
2137   g_print ("free %p\n", sort_level->array);
2138 #endif
2139
2140   g_array_free (sort_level->array, TRUE);
2141   sort_level->array = NULL;
2142
2143 #ifdef VERBOSE
2144   g_print ("free %p\n", sort_level);
2145 #endif
2146
2147   g_free (sort_level);
2148   sort_level = NULL;
2149
2150 #ifdef VERBOSE
2151   g_print ("-------- done ---------\n");
2152 #endif
2153 }
2154
2155 static void
2156 gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort)
2157 {
2158   while (tree_model_sort->stamp == 0) tree_model_sort->stamp++;
2159
2160   gtk_tree_model_sort_clear_cache (tree_model_sort);
2161 }
2162
2163 static void
2164 gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
2165                                         SortLevel        *level)
2166 {
2167   gint i;
2168
2169   g_assert (level != NULL);
2170
2171   for (i = 0; i < level->array->len; i++)
2172     {
2173       if (g_array_index (level->array, SortElt, i).zero_ref_count > 0)
2174         gtk_tree_model_sort_clear_cache_helper (tree_model_sort, g_array_index (level->array, SortElt, i).children);
2175     }
2176
2177   if (level->ref_count == 0 && level != tree_model_sort->root)
2178     {
2179       gtk_tree_model_sort_free_level (tree_model_sort, level);
2180       return;
2181     }
2182 }
2183
2184 /**
2185  * gtk_tree_model_sort_reset_default_sort_func:
2186  * @tree_model_sort: A #GtkTreeModelSort
2187  * 
2188  * This resets the default sort function to be in the 'unsorted' state.  That
2189  * is, it is in the same order as the child model.
2190  **/
2191 void
2192 gtk_tree_model_sort_reset_default_sort_func (GtkTreeModelSort *tree_model_sort)
2193 {
2194   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2195
2196   if (tree_model_sort->default_sort_destroy)
2197     (* tree_model_sort->default_sort_destroy) (tree_model_sort->default_sort_data);
2198
2199   tree_model_sort->default_sort_func = (GtkTreeIterCompareFunc) 0x1;
2200   tree_model_sort->default_sort_data = NULL;
2201   tree_model_sort->default_sort_destroy = NULL;
2202   tree_model_sort->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
2203 }
2204
2205 /**
2206  * gtk_tree_model_sort_clear_cache:
2207  * @tree_model_sort: A #GtkTreeModelSort
2208  * 
2209  * This function should almost never be called.  It clears the @tree_model_sort
2210  * of any cached iterators that haven't been reffed with
2211  * gtk_tree_model_ref_node().  This might be useful if the child model being
2212  * sorted is static (and doesn't change often) and there has been a lot of
2213  * unreffed access to nodes.  As a side effect of this function, all unreffed
2214  * iters will be invalid.
2215  **/
2216 void
2217 gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
2218 {
2219   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2220
2221   if (tree_model_sort->zero_ref_count)
2222     gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->root);
2223 }