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