]> Pileus Git - ~andy/gtk/blob - gtk/gtktreestore.c
to simplify parsing for exported functions: - made implementation
[~andy/gtk] / gtk / gtktreestore.c
1 /* gtktreestore.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "gtktreemodel.h"
21 #include "gtktreestore.h"
22 #include "gtktreedatalist.h"
23 #include "gtktreednd.h"
24 #include <string.h>
25 #include <gobject/gvaluecollector.h>
26
27 #define G_NODE(node) ((GNode *)node)
28 #define GTK_TREE_STORE_IS_SORTED(tree) (GTK_TREE_STORE (tree)->sort_column_id != -2)
29 #define VALID_ITER(iter, tree_store) (iter!= NULL && iter->user_data != NULL && tree_store->stamp == iter->stamp)
30
31 static void         gtk_tree_store_init            (GtkTreeStore      *tree_store);
32 static void         gtk_tree_store_class_init      (GtkTreeStoreClass *tree_store_class);
33 static void         gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
34 static void         gtk_tree_store_drag_source_init(GtkTreeDragSourceIface *iface);
35 static void         gtk_tree_store_drag_dest_init  (GtkTreeDragDestIface   *iface);
36 static void         gtk_tree_store_sortable_init   (GtkTreeSortableIface   *iface);
37 static void         gtk_tree_store_finalize        (GObject           *object);
38 static guint        gtk_tree_store_get_flags       (GtkTreeModel      *tree_model);
39 static gint         gtk_tree_store_get_n_columns   (GtkTreeModel      *tree_model);
40 static GType        gtk_tree_store_get_column_type (GtkTreeModel      *tree_model,
41                                                     gint               index);
42 static gboolean     gtk_tree_store_get_iter        (GtkTreeModel      *tree_model,
43                                                     GtkTreeIter       *iter,
44                                                     GtkTreePath       *path);
45 static GtkTreePath *gtk_tree_store_get_path        (GtkTreeModel      *tree_model,
46                                                     GtkTreeIter       *iter);
47 static void         gtk_tree_store_get_value       (GtkTreeModel      *tree_model,
48                                                     GtkTreeIter       *iter,
49                                                     gint               column,
50                                                     GValue            *value);
51 static gboolean     gtk_tree_store_iter_next       (GtkTreeModel      *tree_model,
52                                                     GtkTreeIter       *iter);
53 static gboolean     gtk_tree_store_iter_children   (GtkTreeModel      *tree_model,
54                                                     GtkTreeIter       *iter,
55                                                     GtkTreeIter       *parent);
56 static gboolean     gtk_tree_store_iter_has_child  (GtkTreeModel      *tree_model,
57                                                     GtkTreeIter       *iter);
58 static gint         gtk_tree_store_iter_n_children (GtkTreeModel      *tree_model,
59                                                     GtkTreeIter       *iter);
60 static gboolean     gtk_tree_store_iter_nth_child  (GtkTreeModel      *tree_model,
61                                                     GtkTreeIter       *iter,
62                                                     GtkTreeIter       *parent,
63                                                     gint               n);
64 static gboolean     gtk_tree_store_iter_parent     (GtkTreeModel      *tree_model,
65                                                     GtkTreeIter       *iter,
66                                                     GtkTreeIter       *child);
67
68
69 static void gtk_tree_store_set_n_columns   (GtkTreeStore *tree_store,
70                                             gint          n_columns);
71 static void gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
72                                             gint          column,
73                                             GType         type);
74
75
76 /* DND interfaces */
77 static gboolean gtk_tree_store_drag_data_delete   (GtkTreeDragSource *drag_source,
78                                                    GtkTreePath       *path);
79 static gboolean gtk_tree_store_drag_data_get      (GtkTreeDragSource *drag_source,
80                                                    GtkTreePath       *path,
81                                                    GtkSelectionData  *selection_data);
82 static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
83                                                    GtkTreePath       *dest,
84                                                    GtkSelectionData  *selection_data);
85 static gboolean gtk_tree_store_row_drop_possible  (GtkTreeDragDest   *drag_dest,
86                                                    GtkTreeModel      *src_model,
87                                                    GtkTreePath       *src_path,
88                                                    GtkTreePath       *dest_path);
89
90 /* Sortable Interfaces */
91
92 static void     gtk_tree_store_sort                    (GtkTreeStore           *tree_store);
93 static void     gtk_tree_store_sort_iter_changed       (GtkTreeStore           *tree_store,
94                                                         GtkTreeIter            *iter,
95                                                         gint                    column);
96 static gboolean gtk_tree_store_get_sort_column_id      (GtkTreeSortable        *sortable,
97                                                         gint                   *sort_column_id,
98                                                         GtkSortType            *order);
99 static void     gtk_tree_store_set_sort_column_id      (GtkTreeSortable        *sortable,
100                                                         gint                    sort_column_id,
101                                                         GtkSortType             order);
102 static void     gtk_tree_store_set_sort_func           (GtkTreeSortable        *sortable,
103                                                         gint                    sort_column_id,
104                                                         GtkTreeIterCompareFunc  func,
105                                                         gpointer                data,
106                                                         GtkDestroyNotify        destroy);
107 static void     gtk_tree_store_set_default_sort_func   (GtkTreeSortable        *sortable,
108                                                         GtkTreeIterCompareFunc  func,
109                                                         gpointer                data,
110                                                         GtkDestroyNotify        destroy);
111 static gboolean gtk_tree_store_has_default_sort_func   (GtkTreeSortable        *sortable);
112
113 static void     validate_gnode                         (GNode *node);
114
115
116 static GObjectClass *parent_class = NULL;
117
118
119 static inline void
120 validate_tree (GtkTreeStore *tree_store)
121 {
122   if (gtk_debug_flags & GTK_DEBUG_TREE)
123     {
124       g_assert (G_NODE (tree_store->root)->parent == NULL);
125
126       validate_gnode (G_NODE (tree_store->root));
127     }
128 }
129
130 GtkType
131 gtk_tree_store_get_type (void)
132 {
133   static GType tree_store_type = 0;
134
135   if (!tree_store_type)
136     {
137       static const GTypeInfo tree_store_info =
138       {
139         sizeof (GtkTreeStoreClass),
140         NULL,           /* base_init */
141         NULL,           /* base_finalize */
142         (GClassInitFunc) gtk_tree_store_class_init,
143         NULL,           /* class_finalize */
144         NULL,           /* class_data */
145         sizeof (GtkTreeStore),
146         0,              /* n_preallocs */
147         (GInstanceInitFunc) gtk_tree_store_init
148       };
149
150       static const GInterfaceInfo tree_model_info =
151       {
152         (GInterfaceInitFunc) gtk_tree_store_tree_model_init,
153         NULL,
154         NULL
155       };
156
157       static const GInterfaceInfo drag_source_info =
158       {
159         (GInterfaceInitFunc) gtk_tree_store_drag_source_init,
160         NULL,
161         NULL
162       };
163
164       static const GInterfaceInfo drag_dest_info =
165       {
166         (GInterfaceInitFunc) gtk_tree_store_drag_dest_init,
167         NULL,
168         NULL
169       };
170
171       static const GInterfaceInfo sortable_info =
172       {
173         (GInterfaceInitFunc) gtk_tree_store_sortable_init,
174         NULL,
175         NULL
176       };
177
178       tree_store_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0);
179
180       g_type_add_interface_static (tree_store_type,
181                                    GTK_TYPE_TREE_MODEL,
182                                    &tree_model_info);
183       g_type_add_interface_static (tree_store_type,
184                                    GTK_TYPE_TREE_DRAG_SOURCE,
185                                    &drag_source_info);
186       g_type_add_interface_static (tree_store_type,
187                                    GTK_TYPE_TREE_DRAG_DEST,
188                                    &drag_dest_info);
189       g_type_add_interface_static (tree_store_type,
190                                    GTK_TYPE_TREE_SORTABLE,
191                                    &sortable_info);
192
193     }
194
195   return tree_store_type;
196 }
197
198 static void
199 gtk_tree_store_class_init (GtkTreeStoreClass *class)
200 {
201   GObjectClass *object_class;
202
203   parent_class = g_type_class_peek_parent (class);
204   object_class = (GObjectClass *) class;
205
206   object_class->finalize = gtk_tree_store_finalize;
207 }
208
209 static void
210 gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
211 {
212   iface->get_flags = gtk_tree_store_get_flags;
213   iface->get_n_columns = gtk_tree_store_get_n_columns;
214   iface->get_column_type = gtk_tree_store_get_column_type;
215   iface->get_iter = gtk_tree_store_get_iter;
216   iface->get_path = gtk_tree_store_get_path;
217   iface->get_value = gtk_tree_store_get_value;
218   iface->iter_next = gtk_tree_store_iter_next;
219   iface->iter_children = gtk_tree_store_iter_children;
220   iface->iter_has_child = gtk_tree_store_iter_has_child;
221   iface->iter_n_children = gtk_tree_store_iter_n_children;
222   iface->iter_nth_child = gtk_tree_store_iter_nth_child;
223   iface->iter_parent = gtk_tree_store_iter_parent;
224 }
225
226 static void
227 gtk_tree_store_drag_source_init (GtkTreeDragSourceIface *iface)
228 {
229   iface->drag_data_delete = gtk_tree_store_drag_data_delete;
230   iface->drag_data_get = gtk_tree_store_drag_data_get;
231 }
232
233 static void
234 gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface)
235 {
236   iface->drag_data_received = gtk_tree_store_drag_data_received;
237   iface->row_drop_possible = gtk_tree_store_row_drop_possible;
238 }
239
240 static void
241 gtk_tree_store_sortable_init (GtkTreeSortableIface *iface)
242 {
243   iface->get_sort_column_id = gtk_tree_store_get_sort_column_id;
244   iface->set_sort_column_id = gtk_tree_store_set_sort_column_id;
245   iface->set_sort_func = gtk_tree_store_set_sort_func;
246   iface->set_default_sort_func = gtk_tree_store_set_default_sort_func;
247   iface->has_default_sort_func = gtk_tree_store_has_default_sort_func;
248 }
249
250 static void
251 gtk_tree_store_init (GtkTreeStore *tree_store)
252 {
253   tree_store->root = g_node_new (NULL);
254   do
255     {
256       tree_store->stamp = g_random_int ();
257     }
258   while (tree_store->stamp == 0);
259   tree_store->sort_list = NULL;
260   tree_store->sort_column_id = -2;
261 }
262
263 /**
264  * gtk_tree_store_new:
265  * @n_columns: number of columns in the tree store
266  * @Varargs: all #GType types for the columns, from first to last
267  *
268  * Creates a new tree store as with @n_columns columns each of the types passed
269  * in.  As an example, gtk_tree_store_new (3, G_TYPE_INT, G_TYPE_STRING,
270  * GDK_TYPE_PIXBUF); will create a new GtkTreeStore with three columns, of type
271  * int, string and GDkPixbuf respectively.
272  *
273  * Return value: a new #GtkTreeStore
274  **/
275 GtkTreeStore *
276 gtk_tree_store_new (gint n_columns,
277                                ...)
278 {
279   GtkTreeStore *retval;
280   va_list args;
281   gint i;
282
283   g_return_val_if_fail (n_columns > 0, NULL);
284
285   retval = GTK_TREE_STORE (g_object_new (GTK_TYPE_TREE_STORE, NULL));
286   gtk_tree_store_set_n_columns (retval, n_columns);
287
288   va_start (args, n_columns);
289
290   for (i = 0; i < n_columns; i++)
291     {
292       GType type = va_arg (args, GType);
293       if (! _gtk_tree_data_list_check_type (type))
294         {
295           g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (type));
296           g_object_unref (G_OBJECT (retval));
297           return NULL;
298         }
299       gtk_tree_store_set_column_type (retval, i, type);
300     }
301   va_end (args);
302
303   return retval;
304 }
305 /**
306  * gtk_tree_store_newv:
307  * @n_columns: number of columns in the tree store
308  * @types: an array of #GType types for the columns, from first to last
309  *
310  * Non vararg creation function.  Used primarily by language bindings.
311  *
312  * Return value: a new #GtkTreeStore
313  **/
314 GtkTreeStore *
315 gtk_tree_store_newv (gint   n_columns,
316                      GType *types)
317 {
318   GtkTreeStore *retval;
319   gint i;
320
321   g_return_val_if_fail (n_columns > 0, NULL);
322
323   retval = GTK_TREE_STORE (g_object_new (GTK_TYPE_TREE_STORE, NULL));
324   gtk_tree_store_set_n_columns (retval, n_columns);
325
326    for (i = 0; i < n_columns; i++)
327     {
328       if (! _gtk_tree_data_list_check_type (types[i]))
329         {
330           g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (types[i]));
331           g_object_unref (G_OBJECT (retval));
332           return NULL;
333         }
334       gtk_tree_store_set_column_type (retval, i, types[i]);
335     }
336
337   return retval;
338 }
339
340 static void
341 gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
342                               gint          n_columns)
343 {
344   GType *new_columns;
345
346   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
347
348   if (tree_store->n_columns == n_columns)
349     return;
350
351   new_columns = g_new0 (GType, n_columns);
352   if (tree_store->column_headers)
353     {
354       /* copy the old header orders over */
355       if (n_columns >= tree_store->n_columns)
356         memcpy (new_columns, tree_store->column_headers, tree_store->n_columns * sizeof (gchar *));
357       else
358         memcpy (new_columns, tree_store->column_headers, n_columns * sizeof (GType));
359
360       g_free (tree_store->column_headers);
361     }
362
363   if (tree_store->sort_list)
364     _gtk_tree_data_list_header_free (tree_store->sort_list);
365
366   tree_store->sort_list = _gtk_tree_data_list_header_new (n_columns, tree_store->column_headers);
367
368   tree_store->column_headers = new_columns;
369   tree_store->n_columns = n_columns;
370 }
371
372 /**
373  * gtk_tree_store_set_column_type:
374  * @tree_store: a #GtkTreeStore
375  * @column: column number
376  * @type: type of the data to be stored in @column
377  *
378  * Supported types include: %G_TYPE_UINT, %G_TYPE_INT, %G_TYPE_UCHAR,
379  * %G_TYPE_CHAR, %G_TYPE_BOOLEAN, %G_TYPE_POINTER, %G_TYPE_FLOAT,
380  * %G_TYPE_DOUBLE, %G_TYPE_STRING, %G_TYPE_OBJECT, and %G_TYPE_BOXED, along with
381  * subclasses of those types such as %GDK_TYPE_PIXBUF.
382  *
383  **/
384 static void
385 gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
386                                 gint          column,
387                                 GType         type)
388 {
389   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
390   g_return_if_fail (column >=0 && column < tree_store->n_columns);
391   if (!_gtk_tree_data_list_check_type (type))
392     {
393       g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (type));
394       return;
395     }
396   tree_store->column_headers[column] = type;
397 }
398
399 static void
400 node_free (GNode *node, gpointer data)
401 {
402   _gtk_tree_data_list_free (node->data, (GType*)data);
403 }
404
405 static void
406 gtk_tree_store_finalize (GObject *object)
407 {
408   GtkTreeStore *tree_store = GTK_TREE_STORE (object);
409
410   g_node_children_foreach (tree_store->root, G_TRAVERSE_LEAFS, node_free, tree_store->column_headers);
411   _gtk_tree_data_list_header_free (tree_store->sort_list);
412   g_free (tree_store->column_headers);
413
414   if (tree_store->default_sort_destroy)
415     {
416       (* tree_store->default_sort_destroy) (tree_store->default_sort_data);
417       tree_store->default_sort_destroy = NULL;
418       tree_store->default_sort_data = NULL;
419     }
420
421   (* parent_class->finalize) (object);
422 }
423
424 /* fulfill the GtkTreeModel requirements */
425 /* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node.  However,
426  * it is not visible to the tree or to the user., and the path "0" refers to the
427  * first child of GtkTreeStore::root.
428  */
429
430
431 static guint
432 gtk_tree_store_get_flags (GtkTreeModel *tree_model)
433 {
434   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
435
436   return GTK_TREE_MODEL_ITERS_PERSIST;
437 }
438
439 static gint
440 gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
441 {
442   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
443
444   return GTK_TREE_STORE (tree_model)->n_columns;
445 }
446
447 static GType
448 gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
449                                 gint          index)
450 {
451   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), G_TYPE_INVALID);
452   g_return_val_if_fail (index < GTK_TREE_STORE (tree_model)->n_columns &&
453                         index >= 0, G_TYPE_INVALID);
454
455   return GTK_TREE_STORE (tree_model)->column_headers[index];
456 }
457
458 static gboolean
459 gtk_tree_store_get_iter (GtkTreeModel *tree_model,
460                          GtkTreeIter  *iter,
461                          GtkTreePath  *path)
462 {
463   GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
464   GtkTreeIter parent;
465   gint *indices;
466   gint depth, i;
467
468   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
469   
470   indices = gtk_tree_path_get_indices (path);
471   depth = gtk_tree_path_get_depth (path);
472
473   g_return_val_if_fail (depth > 0, FALSE);
474
475   parent.stamp = tree_store->stamp;
476   parent.user_data = tree_store->root;
477
478   if (! gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[0]))
479     return FALSE;
480
481   for (i = 1; i < depth; i++)
482     {
483       parent = *iter;
484       if (! gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[i]))
485         return FALSE;
486     }
487
488   return TRUE;
489 }
490
491 static GtkTreePath *
492 gtk_tree_store_get_path (GtkTreeModel *tree_model,
493                          GtkTreeIter  *iter)
494 {
495   GtkTreePath *retval;
496   GNode *tmp_node;
497   gint i = 0;
498
499   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
500   g_return_val_if_fail (iter != NULL, NULL);
501   g_return_val_if_fail (iter->user_data != NULL, NULL);
502   g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, NULL);
503
504   validate_tree ((GtkTreeStore*)tree_model);
505
506   if (G_NODE (iter->user_data)->parent == NULL &&
507       G_NODE (iter->user_data) == GTK_TREE_STORE (tree_model)->root)
508     return gtk_tree_path_new ();
509   g_assert (G_NODE (iter->user_data)->parent != NULL);
510
511   if (G_NODE (iter->user_data)->parent == G_NODE (GTK_TREE_STORE (tree_model)->root))
512     {
513       retval = gtk_tree_path_new ();
514       tmp_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
515     }
516   else
517     {
518       GtkTreeIter tmp_iter = *iter;
519
520       tmp_iter.user_data = G_NODE (iter->user_data)->parent;
521
522       retval = gtk_tree_store_get_path (tree_model,
523                                         &tmp_iter);
524       tmp_node = G_NODE (iter->user_data)->parent->children;
525     }
526
527   if (retval == NULL)
528     return NULL;
529
530   if (tmp_node == NULL)
531     {
532       gtk_tree_path_free (retval);
533       return NULL;
534     }
535
536   for (; tmp_node; tmp_node = tmp_node->next)
537     {
538       if (tmp_node == G_NODE (iter->user_data))
539         break;
540       i++;
541     }
542
543   if (tmp_node == NULL)
544     {
545       /* We couldn't find node, meaning it's prolly not ours */
546       /* Perhaps I should do a g_return_if_fail here. */
547       gtk_tree_path_free (retval);
548       return NULL;
549     }
550
551   gtk_tree_path_append_index (retval, i);
552
553   return retval;
554 }
555
556
557 static void
558 gtk_tree_store_get_value (GtkTreeModel *tree_model,
559                           GtkTreeIter  *iter,
560                           gint          column,
561                           GValue       *value)
562 {
563   GtkTreeDataList *list;
564   gint tmp_column = column;
565
566   g_return_if_fail (GTK_IS_TREE_STORE (tree_model));
567   g_return_if_fail (iter != NULL);
568   g_return_if_fail (column < GTK_TREE_STORE (tree_model)->n_columns);
569
570   list = G_NODE (iter->user_data)->data;
571
572   while (tmp_column-- > 0 && list)
573     list = list->next;
574
575   if (list)
576     {
577       _gtk_tree_data_list_node_to_value (list,
578                                          GTK_TREE_STORE (tree_model)->column_headers[column],
579                                          value);
580     }
581   else
582     {
583       /* We want to return an initialized but empty (default) value */
584       g_value_init (value, GTK_TREE_STORE (tree_model)->column_headers[column]);
585     }
586 }
587
588 static gboolean
589 gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
590                           GtkTreeIter   *iter)
591 {
592   g_return_val_if_fail (iter->user_data != NULL, FALSE);
593
594   if (G_NODE (iter->user_data)->next)
595     {
596       iter->user_data = G_NODE (iter->user_data)->next;
597       return TRUE;
598     }
599   else
600     return FALSE;
601 }
602
603 static gboolean
604 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
605                               GtkTreeIter  *iter,
606                               GtkTreeIter  *parent)
607 {
608   GNode *children;
609
610   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
611
612   if (parent)
613     children = G_NODE (parent->user_data)->children;
614   else
615     children = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
616
617   if (children)
618     {
619       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
620       iter->user_data = children;
621       return TRUE;
622     }
623   else
624     return FALSE;
625 }
626
627 static gboolean
628 gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
629                                GtkTreeIter  *iter)
630 {
631   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
632   g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, FALSE);
633   g_return_val_if_fail (iter->user_data != NULL, FALSE);
634
635   return G_NODE (iter->user_data)->children != NULL;
636 }
637
638 static gint
639 gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
640                                 GtkTreeIter  *iter)
641 {
642   GNode *node;
643   gint i = 0;
644
645   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
646   g_return_val_if_fail (iter == NULL || iter->user_data != NULL, FALSE);
647
648   if (iter == NULL)
649     node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
650   else
651     node = G_NODE (iter->user_data)->children;
652
653   while (node)
654     {
655       i++;
656       node = node->next;
657     }
658
659   return i;
660 }
661
662 static gboolean
663 gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
664                                GtkTreeIter  *iter,
665                                GtkTreeIter  *parent,
666                                gint          n)
667 {
668   GNode *parent_node;
669   GNode *child;
670
671   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
672   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
673
674   if (parent == NULL)
675     parent_node = GTK_TREE_STORE (tree_model)->root;
676   else
677     parent_node = parent->user_data;
678
679   child = g_node_nth_child (parent_node, n);
680
681   if (child)
682     {
683       iter->user_data = child;
684       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
685       return TRUE;
686     }
687   else
688     return FALSE;
689 }
690
691 static gboolean
692 gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
693                             GtkTreeIter  *iter,
694                             GtkTreeIter  *child)
695 {
696   GNode *parent;
697
698   g_return_val_if_fail (iter != NULL, FALSE);
699   g_return_val_if_fail (iter->user_data != NULL, FALSE);
700
701   parent = G_NODE (child->user_data)->parent;
702
703   g_assert (parent != NULL);
704
705   if (parent != GTK_TREE_STORE (tree_model)->root)
706     {
707       iter->user_data = parent;
708       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
709       return TRUE;
710     }
711   else
712     return FALSE;
713 }
714
715
716 /* Does not emit a signal */
717 static gboolean
718 gtk_tree_store_real_set_value (GtkTreeStore *tree_store,
719                                GtkTreeIter  *iter,
720                                gint          column,
721                                GValue       *value)
722 {
723   GtkTreeDataList *list;
724   GtkTreeDataList *prev;
725   GtkTreePath *path = NULL;
726   GValue real_value = {0, };
727   gboolean converted = FALSE;
728   gint orig_column = column;
729   gboolean retval = FALSE;
730
731   if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column]))
732     {
733       if (! (g_value_type_compatible (G_VALUE_TYPE (value), tree_store->column_headers[column]) &&
734              g_value_type_compatible (tree_store->column_headers[column], G_VALUE_TYPE (value))))
735         {
736           g_warning ("%s: Unable to convert from %s to %s\n",
737                      G_STRLOC,
738                      g_type_name (G_VALUE_TYPE (value)),
739                      g_type_name (tree_store->column_headers[column]));
740           return retval;
741         }
742       if (!g_value_transform (value, &real_value))
743         {
744           g_warning ("%s: Unable to make conversion from %s to %s\n",
745                      G_STRLOC,
746                      g_type_name (G_VALUE_TYPE (value)),
747                      g_type_name (tree_store->column_headers[column]));
748           g_value_unset (&real_value);
749           return retval;
750         }
751       converted = TRUE;
752     }
753
754   prev = list = G_NODE (iter->user_data)->data;
755
756   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
757
758   while (list != NULL)
759     {
760       if (column == 0)
761         {
762           if (converted)
763             _gtk_tree_data_list_value_to_node (list, &real_value);
764           else
765             _gtk_tree_data_list_value_to_node (list, value);
766           retval = TRUE;
767           gtk_tree_path_free (path);
768           if (converted)
769             g_value_unset (&real_value);
770           return retval;
771         }
772
773       column--;
774       prev = list;
775       list = list->next;
776     }
777
778   if (G_NODE (iter->user_data)->data == NULL)
779     {
780       G_NODE (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
781       list->next = NULL;
782     }
783   else
784     {
785       list = prev->next = _gtk_tree_data_list_alloc ();
786       list->next = NULL;
787     }
788
789   while (column != 0)
790     {
791       list->next = _gtk_tree_data_list_alloc ();
792       list = list->next;
793       list->next = NULL;
794       column --;
795     }
796   if (converted)
797     _gtk_tree_data_list_value_to_node (list, &real_value);
798   else
799     _gtk_tree_data_list_value_to_node (list, value);
800
801   gtk_tree_path_free (path);
802   if (converted)
803     g_value_unset (&real_value);
804
805   if (GTK_TREE_STORE_IS_SORTED (tree_store))
806     gtk_tree_store_sort_iter_changed (tree_store, iter, orig_column);
807
808   return retval;
809 }
810
811 /**
812  * gtk_tree_store_set_value:
813  * @tree_store: a #GtkTreeStore
814  * @iter: A valid #GtkTreeIter for the row being modified
815  * @column: column number to modify
816  * @value: new value for the cell
817  *
818  * Sets the data in the cell specified by @iter and @column.
819  * The type of @value must be convertible to the type of the
820  * column.
821  *
822  **/
823 void
824 gtk_tree_store_set_value (GtkTreeStore *tree_store,
825                           GtkTreeIter  *iter,
826                           gint          column,
827                           GValue       *value)
828 {
829   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
830   g_return_if_fail (VALID_ITER (iter, tree_store));
831   g_return_if_fail (column >= 0 && column < tree_store->n_columns);
832   g_return_if_fail (G_IS_VALUE (value));
833
834   if (gtk_tree_store_real_set_value (tree_store, iter, column, value))
835     {
836       GtkTreePath *path;
837
838       path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
839       gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
840       gtk_tree_path_free (path);
841     }
842 }
843
844 /**
845  * gtk_tree_store_set_valist:
846  * @tree_store: A #GtkTreeStore
847  * @iter: A valid #GtkTreeIter for the row being modified
848  * @var_args: va_list of column/value pairs
849  *
850  * See @gtk_tree_store_set; this version takes a va_list for
851  * use by language bindings.
852  *
853  **/
854 void
855 gtk_tree_store_set_valist (GtkTreeStore *tree_store,
856                            GtkTreeIter  *iter,
857                            va_list      var_args)
858 {
859   gint column;
860   gboolean emit_signal = FALSE;
861
862   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
863   g_return_if_fail (VALID_ITER (iter, tree_store));
864
865   column = va_arg (var_args, gint);
866
867   while (column != -1)
868     {
869       GValue value = { 0, };
870       gchar *error = NULL;
871
872       if (column >= tree_store->n_columns)
873         {
874           g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
875           break;
876         }
877       g_value_init (&value, tree_store->column_headers[column]);
878
879       G_VALUE_COLLECT (&value, var_args, 0, &error);
880       if (error)
881         {
882           g_warning ("%s: %s", G_STRLOC, error);
883           g_free (error);
884
885           /* we purposely leak the value here, it might not be
886            * in a sane state if an error condition occoured
887            */
888           break;
889         }
890
891       emit_signal = gtk_tree_store_real_set_value (tree_store,
892                                                    iter,
893                                                    column,
894                                                    &value) || emit_signal;
895
896       g_value_unset (&value);
897
898       column = va_arg (var_args, gint);
899     }
900   if (emit_signal)
901     {
902       GtkTreePath *path;
903
904       path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
905       gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
906       gtk_tree_path_free (path);
907     }
908 }
909
910 /**
911  * gtk_tree_store_set:
912  * @tree_store: A #GtkTreeStore
913  * @iter: A valid #GtkTreeIter for the row being modified
914  * @Varargs: pairs of column number and value, terminated with -1
915  *
916  * Sets the value of one or more cells in the row referenced by @iter.
917  * The variable argument list should contain integer column numbers,
918  * each column number followed by the value to be set. For example,
919  * The list is terminated by a -1. For example, to set column 0 with type
920  * %G_TYPE_STRING to "Foo", you would write gtk_tree_store_set (store, iter,
921  * 0, "Foo", -1).
922  **/
923 void
924 gtk_tree_store_set (GtkTreeStore *tree_store,
925                     GtkTreeIter  *iter,
926                     ...)
927 {
928   va_list var_args;
929
930   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
931   g_return_if_fail (VALID_ITER (iter, tree_store));
932
933   va_start (var_args, iter);
934   gtk_tree_store_set_valist (tree_store, iter, var_args);
935   va_end (var_args);
936 }
937
938 /**
939  * gtk_tree_store_remove:
940  * @tree_store: A #GtkTreeStore
941  * @iter: A valid #GtkTreeIter
942  * 
943  * Removes @iter from @tree_store.  After being removed, @iter is set to the
944  * next valid row at that level, or invalidated if it previeously pointed to the
945  * last one.
946  **/
947 void
948 gtk_tree_store_remove (GtkTreeStore *tree_store,
949                        GtkTreeIter  *iter)
950 {
951   GtkTreePath *path;
952   GtkTreeIter new_iter = {0,};
953   GNode *parent;
954   GNode *next_node;
955
956   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
957   g_return_if_fail (VALID_ITER (iter, tree_store));
958
959   parent = G_NODE (iter->user_data)->parent;
960
961   g_assert (parent != NULL);
962   next_node = G_NODE (iter->user_data)->next;
963
964   if (G_NODE (iter->user_data)->data)
965     _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
966                               tree_store->column_headers);
967
968   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
969   g_node_destroy (G_NODE (iter->user_data));
970
971   gtk_tree_model_row_deleted (GTK_TREE_MODEL (tree_store), path);
972
973   if (parent != G_NODE (tree_store->root))
974     {
975       /* child_toggled */
976       if (parent->children == NULL)
977         {
978           gtk_tree_path_up (path);
979
980           new_iter.stamp = tree_store->stamp;
981           new_iter.user_data = parent;
982           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &new_iter);
983         }
984     }
985   gtk_tree_path_free (path);
986
987   /* revalidate iter */
988   if (next_node != NULL)
989     {
990       iter->stamp = tree_store->stamp;
991       iter->user_data = next_node;
992     }
993   else
994     {
995       iter->stamp = 0;
996       iter->user_data = NULL;
997     }
998 }
999
1000 /**
1001  * gtk_tree_store_insert:
1002  * @tree_store: A #GtkListStore
1003  * @iter: An unset #GtkTreeIter to set to the new row
1004  * @parent: A valid #GtkTreeIter, or %NULL
1005  * @position: position to insert the new row
1006  *
1007  * Creates a new row at @position.  If parent is non-NULL, then the row will be
1008  * made a child of @parent.  Otherwise, the row will be created at the toplevel.
1009  * If @position is larger than the number of rows at that level, then the new
1010  * row will be inserted to the end of the list.  @iter will be changed to point
1011  * to this new row.  The row will be empty before this function is called.  To
1012  * fill in values, you need to call @gtk_list_store_set or
1013  * @gtk_list_store_set_value.
1014  *
1015  **/
1016 void
1017 gtk_tree_store_insert (GtkTreeStore *tree_store,
1018                        GtkTreeIter  *iter,
1019                        GtkTreeIter  *parent,
1020                        gint          position)
1021 {
1022   GtkTreePath *path;
1023   GNode *parent_node;
1024
1025   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1026   if (parent)
1027     g_return_if_fail (VALID_ITER (parent, tree_store));
1028
1029   if (parent)
1030     parent_node = parent->user_data;
1031   else
1032     parent_node = tree_store->root;
1033
1034   iter->stamp = tree_store->stamp;
1035   iter->user_data = g_node_new (NULL);
1036   g_node_insert (parent_node, position, G_NODE (iter->user_data));
1037
1038   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1039   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1040
1041   gtk_tree_path_free (path);
1042
1043   validate_tree ((GtkTreeStore*)tree_store);
1044 }
1045
1046 /**
1047  * gtk_tree_store_insert_before:
1048  * @tree_store: A #GtkTreeStore
1049  * @iter: An unset #GtkTreeIter to set to the new row
1050  * @parent: A valid #GtkTreeIter, or %NULL
1051  * @sibling: A valid #GtkTreeIter, or %NULL
1052  *
1053  * Inserts a new row before @sibling.  If @sibling is %NULL, then the row will
1054  * be appended to the beginning of the @parent 's children.  If @parent and
1055  * @sibling are %NULL, then the row will be appended to the toplevel.  If both
1056  * @sibling and @parent are set, then @parent must be the parent of @sibling.
1057  * When @sibling is set, @parent is optional.
1058  *
1059  * @iter will be changed to point to this new row.  The row will be empty after
1060  * this function is called.  To fill in values, you need to call
1061  * @gtk_tree_store_set or @gtk_tree_store_set_value.
1062  *
1063  **/
1064 void
1065 gtk_tree_store_insert_before (GtkTreeStore *tree_store,
1066                               GtkTreeIter  *iter,
1067                               GtkTreeIter  *parent,
1068                               GtkTreeIter  *sibling)
1069 {
1070   GtkTreePath *path;
1071   GNode *parent_node = NULL;
1072   GNode *new_node;
1073
1074   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1075   g_return_if_fail (iter != NULL);
1076   if (parent != NULL)
1077     g_return_if_fail (VALID_ITER (parent, tree_store));
1078   if (sibling != NULL)
1079     g_return_if_fail (VALID_ITER (sibling, tree_store));
1080
1081   new_node = g_node_new (NULL);
1082
1083   if (parent == NULL && sibling == NULL)
1084     parent_node = tree_store->root;
1085   else if (parent == NULL)
1086     parent_node = G_NODE (sibling->user_data)->parent;
1087   else if (sibling == NULL)
1088     parent_node = G_NODE (parent->user_data);
1089   else
1090     {
1091       g_return_if_fail (G_NODE (sibling->user_data)->parent == G_NODE (parent->user_data));
1092       parent_node = G_NODE (parent->user_data);
1093     }
1094
1095   g_node_insert_before (parent_node,
1096                         sibling ? G_NODE (sibling->user_data) : NULL,
1097                         new_node);
1098
1099   iter->stamp = tree_store->stamp;
1100   iter->user_data = new_node;
1101
1102   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1103   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1104
1105   gtk_tree_path_free (path);
1106
1107   validate_tree ((GtkTreeStore*)tree_store);
1108 }
1109
1110 /**
1111  * gtk_tree_store_insert_after:
1112  * @tree_store: A #GtkTreeStore
1113  * @iter: An unset #GtkTreeIter to set to the new row
1114  * @parent: A valid #GtkTreeIter, or %NULL
1115  * @sibling: A valid #GtkTreeIter, or %NULL
1116  *
1117  * Inserts a new row after @sibling.  If @sibling is %NULL, then the row will be
1118  * prepended to the beginning of the @parent 's children.  If @parent and
1119  * @sibling are %NULL, then the row will be prepended to the toplevel.  If both
1120  * @sibling and @parent are set, then @parent must be the parent of @sibling.
1121  * When @sibling is set, @parent is optional.
1122  *
1123  * @iter will be changed to point to this new row.  The row will be empty after
1124  * this function is called.  To fill in values, you need to call
1125  * @gtk_tree_store_set or @gtk_tree_store_set_value.
1126  *
1127  **/
1128 void
1129 gtk_tree_store_insert_after (GtkTreeStore *tree_store,
1130                              GtkTreeIter  *iter,
1131                              GtkTreeIter  *parent,
1132                              GtkTreeIter  *sibling)
1133 {
1134   GtkTreePath *path;
1135   GNode *parent_node;
1136   GNode *new_node;
1137
1138   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1139   g_return_if_fail (iter != NULL);
1140   if (parent != NULL)
1141     g_return_if_fail (VALID_ITER (parent, tree_store));
1142   if (sibling != NULL)
1143     g_return_if_fail (VALID_ITER (sibling, tree_store));
1144
1145   new_node = g_node_new (NULL);
1146
1147   if (parent == NULL && sibling == NULL)
1148     parent_node = tree_store->root;
1149   else if (parent == NULL)
1150     parent_node = G_NODE (sibling->user_data)->parent;
1151   else if (sibling == NULL)
1152     parent_node = G_NODE (parent->user_data);
1153   else
1154     {
1155       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
1156                         G_NODE (parent->user_data));
1157       parent_node = G_NODE (parent->user_data);
1158     }
1159
1160
1161   g_node_insert_after (parent_node,
1162                        sibling ? G_NODE (sibling->user_data) : NULL,
1163                        new_node);
1164
1165   iter->stamp = tree_store->stamp;
1166   iter->user_data = new_node;
1167
1168   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1169   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1170
1171   gtk_tree_path_free (path);
1172
1173   validate_tree ((GtkTreeStore*)tree_store);
1174 }
1175
1176 /**
1177  * gtk_tree_store_prepend:
1178  * @tree_store: A #GtkTreeStore
1179  * @iter: An unset #GtkTreeIter to set to the prepended row
1180  * @parent: A valid #GtkTreeIter, or %NULL
1181  * 
1182  * Prepends a new row to @tree_store.  If @parent is non-NULL, then it will prepend
1183  * the new row before the first child of @parent, otherwise it will prepend a row
1184  * to the top level.  @iter will be changed to point to this new row.  The row
1185  * will be empty after this function is called.  To fill in values, you need to
1186  * call @gtk_tree_store_set or @gtk_tree_store_set_value.
1187  **/
1188 void
1189 gtk_tree_store_prepend (GtkTreeStore *tree_store,
1190                         GtkTreeIter  *iter,
1191                         GtkTreeIter  *parent)
1192 {
1193   GNode *parent_node;
1194
1195   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1196   g_return_if_fail (iter != NULL);
1197   if (parent != NULL)
1198     g_return_if_fail (VALID_ITER (parent, tree_store));
1199
1200   if (parent == NULL)
1201     parent_node = tree_store->root;
1202   else
1203     parent_node = parent->user_data;
1204
1205   if (parent_node->children == NULL)
1206     {
1207       GtkTreePath *path;
1208       
1209       iter->stamp = tree_store->stamp;
1210       iter->user_data = g_node_new (NULL);
1211
1212       g_node_prepend (parent_node, iter->user_data);
1213
1214       path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1215       gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1216
1217       if (parent_node != tree_store->root)
1218         {
1219           gtk_tree_path_up (path);
1220           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1221         }
1222       gtk_tree_path_free (path);
1223     }
1224   else
1225     {
1226       gtk_tree_store_insert_after (tree_store, iter, parent, NULL);
1227     }
1228
1229   validate_tree ((GtkTreeStore*)tree_store);
1230 }
1231
1232 /**
1233  * gtk_tree_store_append:
1234  * @tree_store: A #GtkTreeStore
1235  * @iter: An unset #GtkTreeIter to set to the appended row
1236  * @parent: A valid #GtkTreeIter, or %NULL
1237  * 
1238  * Appends a new row to @tree_store.  If @parent is non-NULL, then it will append the
1239  * new row after the last child of @parent, otherwise it will append a row to
1240  * the top level.  @iter will be changed to point to this new row.  The row will
1241  * be empty after this function is called.  To fill in values, you need to call
1242  * @gtk_tree_store_set or @gtk_tree_store_set_value.
1243  **/
1244 void
1245 gtk_tree_store_append (GtkTreeStore *tree_store,
1246                        GtkTreeIter  *iter,
1247                        GtkTreeIter  *parent)
1248 {
1249   GNode *parent_node;
1250
1251   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1252   g_return_if_fail (iter != NULL);
1253
1254   if (parent != NULL)
1255     g_return_if_fail (VALID_ITER (parent, tree_store));
1256
1257   if (parent == NULL)
1258     parent_node = tree_store->root;
1259   else
1260     parent_node = parent->user_data;
1261
1262   if (parent_node->children == NULL)
1263     {
1264       GtkTreePath *path;
1265
1266       iter->stamp = tree_store->stamp;
1267       iter->user_data = g_node_new (NULL);
1268
1269       g_node_append (parent_node, G_NODE (iter->user_data));
1270
1271       path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1272       gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1273
1274       if (parent_node != tree_store->root)
1275         {
1276           gtk_tree_path_up (path);
1277           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1278         }
1279       gtk_tree_path_free (path);
1280     }
1281   else
1282     {
1283       gtk_tree_store_insert_before (tree_store, iter, parent, NULL);
1284     }
1285
1286   validate_tree ((GtkTreeStore*)tree_store);
1287 }
1288
1289 /**
1290  * gtk_tree_store_is_ancestor:
1291  * @tree_store: A #GtkTreeStore
1292  * @iter: A valid #GtkTreeIter
1293  * @descendant: A valid #GtkTreeIter
1294  * 
1295  * Returns %TRUE if @iter is an ancestor of @descendant.  That is, @iter is the
1296  * parent (or grandparent or great-grandparent) of @descendant.
1297  * 
1298  * Return value: %TRUE, if @iter is an ancestor of @descendant
1299  **/
1300 gboolean
1301 gtk_tree_store_is_ancestor (GtkTreeStore *tree_store,
1302                             GtkTreeIter  *iter,
1303                             GtkTreeIter  *descendant)
1304 {
1305   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1306   g_return_val_if_fail (VALID_ITER (iter, tree_store), FALSE);
1307   g_return_val_if_fail (VALID_ITER (descendant, tree_store), FALSE);
1308
1309   return g_node_is_ancestor (G_NODE (iter->user_data),
1310                              G_NODE (descendant->user_data));
1311 }
1312
1313
1314 /**
1315  * gtk_tree_store_iter_depth:
1316  * @tree_store: A #GtkTreeStore
1317  * @iter: A valid #GtkTreeIter
1318  * 
1319  * Returns the depth of @iter.  This will be 0 for anything on the root level, 1
1320  * for anything down a level, etc.
1321  * 
1322  * Return value: The depth of @iter
1323  **/
1324 gint
1325 gtk_tree_store_iter_depth (GtkTreeStore *tree_store,
1326                            GtkTreeIter  *iter)
1327 {
1328   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), 0);
1329   g_return_val_if_fail (VALID_ITER (iter, tree_store), 0);
1330
1331   return g_node_depth (G_NODE (iter->user_data)) - 2;
1332 }
1333
1334 /**
1335  * gtk_tree_store_clear:
1336  * @tree_store: @ #GtkTreeStore
1337  * 
1338  * Removes all rows from @tree_store
1339  **/
1340 void
1341 gtk_tree_store_clear (GtkTreeStore *tree_store)
1342 {
1343   GtkTreeIter iter;
1344
1345   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1346
1347   while (G_NODE (tree_store->root)->children)
1348     {
1349       iter.stamp = tree_store->stamp;
1350       iter.user_data = G_NODE (tree_store->root)->children;
1351       gtk_tree_store_remove (tree_store, &iter);
1352     }
1353 }
1354
1355 /* DND */
1356
1357
1358 static gboolean
1359 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1360                                  GtkTreePath       *path)
1361 {
1362   GtkTreeIter iter;
1363
1364   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1365
1366   if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
1367                                &iter,
1368                                path))
1369     {
1370       gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1371                              &iter);
1372       return TRUE;
1373     }
1374   else
1375     {
1376       return FALSE;
1377     }
1378 }
1379
1380 static gboolean
1381 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1382                               GtkTreePath       *path,
1383                               GtkSelectionData  *selection_data)
1384 {
1385   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1386
1387   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1388    * target, because the default handler does it for us, but
1389    * we do anyway for the convenience of someone maybe overriding the
1390    * default handler.
1391    */
1392
1393   if (gtk_selection_data_set_tree_row (selection_data,
1394                                        GTK_TREE_MODEL (drag_source),
1395                                        path))
1396     {
1397       return TRUE;
1398     }
1399   else
1400     {
1401       /* FIXME handle text targets at least. */
1402     }
1403
1404   return FALSE;
1405 }
1406
1407 static void
1408 copy_node_data (GtkTreeStore *tree_store,
1409                 GtkTreeIter  *src_iter,
1410                 GtkTreeIter  *dest_iter)
1411 {
1412   GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1413   GtkTreeDataList *copy_head = NULL;
1414   GtkTreeDataList *copy_prev = NULL;
1415   GtkTreeDataList *copy_iter = NULL;
1416   GtkTreePath *path;
1417   gint col;
1418
1419   col = 0;
1420   while (dl)
1421     {
1422       copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1423
1424       if (copy_head == NULL)
1425         copy_head = copy_iter;
1426
1427       if (copy_prev)
1428         copy_prev->next = copy_iter;
1429
1430       copy_prev = copy_iter;
1431
1432       dl = dl->next;
1433       ++col;
1434     }
1435
1436   G_NODE (dest_iter->user_data)->data = copy_head;
1437
1438   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1439   gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, dest_iter);
1440   gtk_tree_path_free (path);
1441 }
1442
1443 static void
1444 recursive_node_copy (GtkTreeStore *tree_store,
1445                      GtkTreeIter  *src_iter,
1446                      GtkTreeIter  *dest_iter)
1447 {
1448   GtkTreeIter child;
1449   GtkTreeModel *model;
1450
1451   model = GTK_TREE_MODEL (tree_store);
1452
1453   copy_node_data (tree_store, src_iter, dest_iter);
1454
1455   if (gtk_tree_model_iter_children (model,
1456                                     &child,
1457                                     src_iter))
1458     {
1459       /* Need to create children and recurse. Note our
1460        * dependence on persistent iterators here.
1461        */
1462       do
1463         {
1464           GtkTreeIter copy;
1465
1466           /* Gee, a really slow algorithm... ;-) FIXME */
1467           gtk_tree_store_append (tree_store,
1468                                  &copy,
1469                                  dest_iter);
1470
1471           recursive_node_copy (tree_store, &child, &copy);
1472         }
1473       while (gtk_tree_model_iter_next (model, &child));
1474     }
1475 }
1476
1477 static gboolean
1478 gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
1479                                    GtkTreePath       *dest,
1480                                    GtkSelectionData  *selection_data)
1481 {
1482   GtkTreeModel *tree_model;
1483   GtkTreeStore *tree_store;
1484   GtkTreeModel *src_model = NULL;
1485   GtkTreePath *src_path = NULL;
1486   gboolean retval = FALSE;
1487
1488   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
1489
1490   tree_model = GTK_TREE_MODEL (drag_dest);
1491   tree_store = GTK_TREE_STORE (drag_dest);
1492
1493   validate_tree (tree_store);
1494
1495   if (gtk_selection_data_get_tree_row (selection_data,
1496                                        &src_model,
1497                                        &src_path) &&
1498       src_model == tree_model)
1499     {
1500       /* Copy the given row to a new position */
1501       GtkTreeIter src_iter;
1502       GtkTreeIter dest_iter;
1503       GtkTreePath *prev;
1504
1505       if (!gtk_tree_model_get_iter (src_model,
1506                                     &src_iter,
1507                                     src_path))
1508         {
1509           goto out;
1510         }
1511
1512       /* Get the path to insert _after_ (dest is the path to insert _before_) */
1513       prev = gtk_tree_path_copy (dest);
1514
1515       if (!gtk_tree_path_prev (prev))
1516         {
1517           GtkTreeIter dest_parent;
1518           GtkTreePath *parent;
1519           GtkTreeIter *dest_parent_p;
1520
1521           /* dest was the first spot at the current depth; which means
1522            * we are supposed to prepend.
1523            */
1524
1525           /* Get the parent, NULL if parent is the root */
1526           dest_parent_p = NULL;
1527           parent = gtk_tree_path_copy (dest);
1528           if (gtk_tree_path_up (parent))
1529             {
1530               gtk_tree_model_get_iter (tree_model,
1531                                        &dest_parent,
1532                                        parent);
1533               dest_parent_p = &dest_parent;
1534             }
1535           gtk_tree_path_free (parent);
1536           parent = NULL;
1537
1538           gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
1539                                   &dest_iter,
1540                                   dest_parent_p);
1541
1542           retval = TRUE;
1543         }
1544       else
1545         {
1546           if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
1547                                        &dest_iter,
1548                                        prev))
1549             {
1550               GtkTreeIter tmp_iter = dest_iter;
1551               gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
1552                                            &dest_iter,
1553                                            NULL,
1554                                            &tmp_iter);
1555               retval = TRUE;
1556
1557             }
1558         }
1559
1560       gtk_tree_path_free (prev);
1561
1562       /* If we succeeded in creating dest_iter, walk src_iter tree branch,
1563        * duplicating it below dest_iter.
1564        */
1565
1566       if (retval)
1567         {
1568           recursive_node_copy (tree_store,
1569                                &src_iter,
1570                                &dest_iter);
1571         }
1572     }
1573   else
1574     {
1575       /* FIXME maybe add some data targets eventually, or handle text
1576        * targets in the simple case.
1577        */
1578
1579     }
1580
1581  out:
1582
1583   if (src_path)
1584     gtk_tree_path_free (src_path);
1585
1586   return retval;
1587 }
1588
1589 static gboolean
1590 gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
1591                                   GtkTreeModel    *src_model,
1592                                   GtkTreePath     *src_path,
1593                                   GtkTreePath     *dest_path)
1594 {
1595   /* can only drag to ourselves */
1596   if (src_model != GTK_TREE_MODEL (drag_dest))
1597     return FALSE;
1598
1599   /* Can't drop into ourself. */
1600   if (gtk_tree_path_is_ancestor (src_path,
1601                                  dest_path))
1602     return FALSE;
1603
1604   /* Can't drop if dest_path's parent doesn't exist */
1605   {
1606     GtkTreeIter iter;
1607     GtkTreePath *tmp = gtk_tree_path_copy (dest_path);
1608
1609     /* if we can't go up, we know the parent exists, the root
1610      * always exists.
1611      */
1612     if (gtk_tree_path_up (tmp))
1613       {
1614         if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
1615                                       &iter, tmp))
1616           {
1617             if (tmp)
1618               gtk_tree_path_free (tmp);
1619             return FALSE;
1620           }
1621       }
1622
1623     if (tmp)
1624       gtk_tree_path_free (tmp);
1625   }
1626
1627   /* Can otherwise drop anywhere. */
1628   return TRUE;
1629 }
1630
1631 /* Sorting */
1632 typedef struct _SortTuple
1633 {
1634   gint offset;
1635   GNode *node;
1636 } SortTuple;
1637
1638 static gint
1639 gtk_tree_store_compare_func (gconstpointer a,
1640                              gconstpointer b,
1641                              gpointer      user_data)
1642 {
1643   GtkTreeStore *tree_store = user_data;
1644   GNode *node_a;
1645   GNode *node_b;
1646   GtkTreeIterCompareFunc func;
1647   gpointer data;
1648
1649   GtkTreeIter iter_a;
1650   GtkTreeIter iter_b;
1651   gint retval;
1652
1653   if (tree_store->sort_column_id != -1)
1654     {
1655       GtkTreeDataSortHeader *header;
1656
1657       header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1658                                                tree_store->sort_column_id);
1659       g_return_val_if_fail (header != NULL, 0);
1660       g_return_val_if_fail (header->func != NULL, 0);
1661
1662       func = header->func;
1663       data = header->data;
1664     }
1665   else
1666     {
1667       g_return_val_if_fail (tree_store->default_sort_func != NULL, 0);
1668       func = tree_store->default_sort_func;
1669       data = tree_store->default_sort_data;
1670     }
1671
1672   node_a = ((SortTuple *) a)->node;
1673   node_b = ((SortTuple *) b)->node;
1674
1675   iter_a.stamp = tree_store->stamp;
1676   iter_a.user_data = node_a;
1677   iter_b.stamp = tree_store->stamp;
1678   iter_b.user_data = node_b;
1679
1680   retval = (* func) (GTK_TREE_MODEL (user_data), &iter_a, &iter_b, data);
1681
1682   if (tree_store->order == GTK_SORT_DESCENDING)
1683     {
1684       if (retval > 0)
1685         retval = -1;
1686       else if (retval < 0)
1687         retval = 1;
1688     }
1689   return retval;
1690 }
1691
1692 static void
1693 gtk_tree_store_sort_helper (GtkTreeStore *tree_store,
1694                             GNode        *parent,
1695                             gboolean      recurse)
1696 {
1697   GtkTreeIter iter;
1698   GArray *sort_array;
1699   GNode *node;
1700   GNode *tmp_node;
1701   gint list_length;
1702   gint i;
1703   gint *new_order;
1704   GtkTreePath *path;
1705
1706   node = parent->children;
1707   if (node == NULL || node->next == NULL)
1708     return;
1709
1710   g_assert (GTK_TREE_STORE_IS_SORTED (tree_store));
1711
1712   list_length = 0;
1713   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1714     list_length++;
1715
1716   sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), list_length);
1717
1718   i = 0;
1719   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1720     {
1721       SortTuple tuple;
1722
1723       tuple.offset = i;
1724       tuple.node = tmp_node;
1725       g_array_append_val (sort_array, tuple);
1726       i++;
1727     }
1728
1729   g_array_sort_with_data (sort_array, gtk_tree_store_compare_func, tree_store);
1730
1731   for (i = 0; i < list_length - 1; i++)
1732     {
1733       g_array_index (sort_array, SortTuple, i).node->next =
1734         g_array_index (sort_array, SortTuple, i + 1).node;
1735       g_array_index (sort_array, SortTuple, i + 1).node->prev =
1736         g_array_index (sort_array, SortTuple, i).node;
1737     }
1738   g_array_index (sort_array, SortTuple, list_length - 1).node->next = NULL;
1739   g_array_index (sort_array, SortTuple, 0).node->prev = NULL;
1740   parent->children = g_array_index (sort_array, SortTuple, 0).node;
1741
1742   /* Let the world know about our new order */
1743   new_order = g_new (gint, list_length);
1744   for (i = 0; i < list_length; i++)
1745     new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1746
1747   iter.stamp = tree_store->stamp;
1748   iter.user_data = parent;
1749   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &iter);
1750   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
1751                                  path, &iter, new_order);
1752   gtk_tree_path_free (path);
1753   g_free (new_order);
1754   g_array_free (sort_array, TRUE);
1755
1756   if (recurse)
1757     {
1758       for (tmp_node = parent->children; tmp_node; tmp_node = tmp_node->next)
1759         {
1760           if (tmp_node->children)
1761             gtk_tree_store_sort_helper (tree_store, tmp_node, TRUE);
1762         }
1763     }
1764 }
1765
1766 static void
1767 gtk_tree_store_sort (GtkTreeStore *tree_store)
1768 {
1769   if (tree_store->sort_column_id != -1)
1770     {
1771       GtkTreeDataSortHeader *header = NULL;
1772
1773       header = _gtk_tree_data_list_get_header (tree_store->sort_list, tree_store->sort_column_id);
1774
1775       /* We want to make sure that we have a function */
1776       g_return_if_fail (header != NULL);
1777       g_return_if_fail (header->func != NULL);
1778     }
1779   else
1780     {
1781       g_return_if_fail (tree_store->default_sort_func != NULL);
1782     }
1783
1784   gtk_tree_store_sort_helper (tree_store, G_NODE (tree_store->root), TRUE);
1785 }
1786
1787 static void
1788 gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
1789                                   GtkTreeIter  *iter,
1790                                   gint          column)
1791 {
1792   GNode *prev = NULL;
1793   GNode *next = NULL;
1794   GNode *node;
1795   GtkTreePath *tmp_path;
1796   GtkTreeIter tmp_iter;
1797   gint cmp_a = 0;
1798   gint cmp_b = 0;
1799   gint i;
1800   gint old_location;
1801   gint new_location;
1802   gint *new_order;
1803   gint length;
1804   GtkTreeIterCompareFunc func;
1805   gpointer data;
1806
1807   g_return_if_fail (G_NODE (iter->user_data)->parent != NULL);
1808
1809   tmp_iter.stamp = tree_store->stamp;
1810   if (tree_store->sort_column_id != -1)
1811     {
1812       GtkTreeDataSortHeader *header;
1813       header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1814                                                tree_store->sort_column_id);
1815       g_return_if_fail (header != NULL);
1816       g_return_if_fail (header->func != NULL);
1817       func = header->func;
1818       data = header->data;
1819     }
1820   else
1821     {
1822       g_return_if_fail (tree_store->default_sort_func != NULL);
1823       func = tree_store->default_sort_func;
1824       data = tree_store->default_sort_data;
1825     }
1826
1827   /* If it's the built in function, we don't sort. */
1828   if (func == gtk_tree_data_list_compare_func &&
1829       tree_store->sort_column_id != column)
1830     return;
1831
1832   old_location = 0;
1833   node = G_NODE (iter->user_data)->parent->children;
1834   /* First we find the iter, its prev, and its next */
1835   while (node)
1836     {
1837       if (node == G_NODE (iter->user_data))
1838         break;
1839       old_location++;
1840       node = node->next;
1841     }
1842   g_assert (node != NULL);
1843
1844   prev = node->prev;
1845   next = node->next;
1846
1847   /* Check the common case, where we don't need to sort it moved. */
1848   if (prev != NULL)
1849     {
1850       tmp_iter.user_data = prev;
1851       cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1852     }
1853
1854   if (next != NULL)
1855     {
1856       tmp_iter.user_data = next;
1857       cmp_b = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1858     }
1859
1860
1861   if (tree_store->order == GTK_SORT_DESCENDING)
1862     {
1863       if (cmp_a < 0)
1864         cmp_a = 1;
1865       else if (cmp_a > 0)
1866         cmp_a = -1;
1867
1868       if (cmp_b < 0)
1869         cmp_b = 1;
1870       else if (cmp_b > 0)
1871         cmp_b = -1;
1872     }
1873
1874   if (prev == NULL && cmp_b <= 0)
1875     return;
1876   else if (next == NULL && cmp_a <= 0)
1877     return;
1878   else if (prev != NULL && next != NULL &&
1879            cmp_a <= 0 && cmp_b <= 0)
1880     return;
1881
1882   /* We actually need to sort it */
1883   /* First, remove the old link. */
1884
1885   if (prev)
1886     prev->next = next;
1887   else
1888     node->parent->children = next;
1889   if (next)
1890     next->prev = prev;
1891
1892   node->prev = NULL;
1893   node->next = NULL;
1894
1895   /* FIXME: as an optimization, we can potentially start at next */
1896   prev = NULL;
1897   node = node->parent->children;
1898   new_location = 0;
1899   tmp_iter.user_data = node;
1900   if (tree_store->order == GTK_SORT_DESCENDING)
1901     cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1902   else
1903     cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1904
1905   while ((node->next) && (cmp_a > 0))
1906     {
1907       prev = node;
1908       node = node->next;
1909       new_location++;
1910       tmp_iter.user_data = node;
1911       if (tree_store->order == GTK_SORT_DESCENDING)
1912         cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1913       else
1914         cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1915     }
1916
1917   if ((!node->next) && (cmp_a > 0))
1918     {
1919       node->next = G_NODE (iter->user_data);
1920       node->next->prev = node;
1921     }
1922   else if (prev)
1923     {
1924       prev->next = G_NODE (iter->user_data);
1925       prev->next->prev = prev;
1926       G_NODE (iter->user_data)->next = node;
1927       G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
1928     }
1929   else
1930     {
1931       G_NODE (iter->user_data)->next = G_NODE (iter->user_data)->parent->children;
1932       G_NODE (iter->user_data)->parent->children = G_NODE (iter->user_data);
1933     }
1934
1935   /* Emit the reordered signal. */
1936   length = g_node_n_children (node->parent);
1937   new_order = g_new (int, length);
1938   if (old_location < new_location)
1939     for (i = 0; i < length; i++)
1940       {
1941         if (i < old_location ||
1942             i > new_location)
1943           new_order[i] = i;
1944         else if (i >= old_location &&
1945                  i < new_location)
1946           new_order[i] = i + 1;
1947         else if (i == new_location)
1948           new_order[i] = old_location;
1949       }
1950   else
1951     for (i = 0; i < length; i++)
1952       {
1953         if (i < new_location ||
1954             i > old_location)
1955           new_order[i] = i;
1956         else if (i > new_location &&
1957                  i <= old_location)
1958           new_order[i] = i - 1;
1959         else if (i == new_location)
1960           new_order[i] = old_location;
1961       }
1962
1963   tmp_iter.user_data = node->parent;
1964   tmp_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &tmp_iter);
1965
1966   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
1967                                  tmp_path, &tmp_iter,
1968                                  new_order);
1969
1970   gtk_tree_path_free (tmp_path);
1971   g_free (new_order);
1972 }
1973
1974
1975 static gboolean
1976 gtk_tree_store_get_sort_column_id (GtkTreeSortable  *sortable,
1977                                    gint             *sort_column_id,
1978                                    GtkSortType      *order)
1979 {
1980   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
1981
1982   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
1983
1984   if (tree_store->sort_column_id == -1)
1985     return FALSE;
1986
1987   if (sort_column_id)
1988     * sort_column_id = tree_store->sort_column_id;
1989   if (order)
1990     * order = tree_store->order;
1991   return TRUE;
1992
1993 }
1994
1995 static void
1996 gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
1997                                    gint              sort_column_id,
1998                                    GtkSortType       order)
1999 {
2000   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2001
2002   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2003
2004   
2005   if ((tree_store->sort_column_id == sort_column_id) &&
2006       (tree_store->order == order))
2007     return;
2008
2009   if (sort_column_id != -1)
2010     {
2011       GtkTreeDataSortHeader *header = NULL;
2012
2013       header = _gtk_tree_data_list_get_header (tree_store->sort_list, sort_column_id);
2014
2015       /* We want to make sure that we have a function */
2016       g_return_if_fail (header != NULL);
2017       g_return_if_fail (header->func != NULL);
2018     }
2019   else
2020     {
2021       g_return_if_fail (tree_store->default_sort_func != NULL);
2022     }
2023
2024   tree_store->sort_column_id = sort_column_id;
2025   tree_store->order = order;
2026
2027   gtk_tree_store_sort (tree_store);
2028
2029   gtk_tree_sortable_sort_column_changed (sortable);
2030 }
2031
2032 static void
2033 gtk_tree_store_set_sort_func (GtkTreeSortable        *sortable,
2034                               gint                    sort_column_id,
2035                               GtkTreeIterCompareFunc  func,
2036                               gpointer                data,
2037                               GtkDestroyNotify        destroy)
2038 {
2039   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2040   GtkTreeDataSortHeader *header = NULL;
2041   GList *list;
2042
2043   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2044   g_return_if_fail (func != NULL);
2045
2046   for (list = tree_store->sort_list; list; list = list->next)
2047     {
2048       header = (GtkTreeDataSortHeader*) list->data;
2049       if (header->sort_column_id == sort_column_id)
2050         break;
2051     }
2052
2053   if (header == NULL)
2054     {
2055       header = g_new0 (GtkTreeDataSortHeader, 1);
2056       header->sort_column_id = sort_column_id;
2057       tree_store->sort_list = g_list_append (tree_store->sort_list, header);
2058     }
2059
2060   if (header->destroy)
2061     (* header->destroy) (header->data);
2062
2063   header->func = func;
2064   header->data = data;
2065   header->destroy = destroy;
2066
2067 }
2068
2069 static void
2070 gtk_tree_store_set_default_sort_func (GtkTreeSortable        *sortable,
2071                                       GtkTreeIterCompareFunc  func,
2072                                       gpointer                data,
2073                                       GtkDestroyNotify        destroy)
2074 {
2075   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2076
2077   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2078
2079   if (tree_store->default_sort_destroy)
2080     (* tree_store->default_sort_destroy) (tree_store->default_sort_data);
2081
2082   tree_store->default_sort_func = func;
2083   tree_store->default_sort_data = data;
2084   tree_store->default_sort_destroy = destroy;
2085 }
2086
2087 static gboolean
2088 gtk_tree_store_has_default_sort_func (GtkTreeSortable *sortable)
2089 {
2090   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2091
2092   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
2093
2094   return (tree_store->default_sort_func != NULL);
2095 }
2096
2097 static void
2098 validate_gnode (GNode* node)
2099 {
2100   GNode *iter;
2101
2102   iter = node->children;
2103   while (iter != NULL)
2104     {
2105       g_assert (iter->parent == node);
2106       if (iter->prev)
2107         g_assert (iter->prev->next == iter);
2108       validate_gnode (iter);
2109       iter = iter->next;
2110     }
2111 }
2112
2113
2114