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