]> Pileus Git - ~andy/gtk/blob - gtk/gtktreestore.c
fix small bug reported by (Oleg Maiboroda), #62600
[~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 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 last 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)) - 1;
1332 }
1333
1334
1335 /**
1336  * gtk_tree_store_clear:
1337  * @tree_store: @ #GtkTreeStore
1338  * 
1339  * Removes all rows from @tree_store
1340  **/
1341 void
1342 gtk_tree_store_clear (GtkTreeStore *tree_store)
1343 {
1344   GtkTreeIter iter;
1345
1346   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1347
1348   while (G_NODE (tree_store->root)->children)
1349     {
1350       iter.stamp = tree_store->stamp;
1351       iter.user_data = G_NODE (tree_store->root)->children;
1352       gtk_tree_store_remove (tree_store, &iter);
1353     }
1354 }
1355
1356 /* DND */
1357
1358
1359 static gboolean
1360 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1361                                  GtkTreePath       *path)
1362 {
1363   GtkTreeIter iter;
1364
1365   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1366
1367   if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
1368                                &iter,
1369                                path))
1370     {
1371       gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1372                              &iter);
1373       return TRUE;
1374     }
1375   else
1376     {
1377       return FALSE;
1378     }
1379 }
1380
1381 static gboolean
1382 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1383                               GtkTreePath       *path,
1384                               GtkSelectionData  *selection_data)
1385 {
1386   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1387
1388   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1389    * target, because the default handler does it for us, but
1390    * we do anyway for the convenience of someone maybe overriding the
1391    * default handler.
1392    */
1393
1394   if (gtk_selection_data_set_tree_row (selection_data,
1395                                        GTK_TREE_MODEL (drag_source),
1396                                        path))
1397     {
1398       return TRUE;
1399     }
1400   else
1401     {
1402       /* FIXME handle text targets at least. */
1403     }
1404
1405   return FALSE;
1406 }
1407
1408 static void
1409 copy_node_data (GtkTreeStore *tree_store,
1410                 GtkTreeIter  *src_iter,
1411                 GtkTreeIter  *dest_iter)
1412 {
1413   GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1414   GtkTreeDataList *copy_head = NULL;
1415   GtkTreeDataList *copy_prev = NULL;
1416   GtkTreeDataList *copy_iter = NULL;
1417   GtkTreePath *path;
1418   gint col;
1419
1420   col = 0;
1421   while (dl)
1422     {
1423       copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1424
1425       if (copy_head == NULL)
1426         copy_head = copy_iter;
1427
1428       if (copy_prev)
1429         copy_prev->next = copy_iter;
1430
1431       copy_prev = copy_iter;
1432
1433       dl = dl->next;
1434       ++col;
1435     }
1436
1437   G_NODE (dest_iter->user_data)->data = copy_head;
1438
1439   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1440   gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, dest_iter);
1441   gtk_tree_path_free (path);
1442 }
1443
1444 static void
1445 recursive_node_copy (GtkTreeStore *tree_store,
1446                      GtkTreeIter  *src_iter,
1447                      GtkTreeIter  *dest_iter)
1448 {
1449   GtkTreeIter child;
1450   GtkTreeModel *model;
1451
1452   model = GTK_TREE_MODEL (tree_store);
1453
1454   copy_node_data (tree_store, src_iter, dest_iter);
1455
1456   if (gtk_tree_model_iter_children (model,
1457                                     &child,
1458                                     src_iter))
1459     {
1460       /* Need to create children and recurse. Note our
1461        * dependence on persistent iterators here.
1462        */
1463       do
1464         {
1465           GtkTreeIter copy;
1466
1467           /* Gee, a really slow algorithm... ;-) FIXME */
1468           gtk_tree_store_append (tree_store,
1469                                  &copy,
1470                                  dest_iter);
1471
1472           recursive_node_copy (tree_store, &child, &copy);
1473         }
1474       while (gtk_tree_model_iter_next (model, &child));
1475     }
1476 }
1477
1478 static gboolean
1479 gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
1480                                    GtkTreePath       *dest,
1481                                    GtkSelectionData  *selection_data)
1482 {
1483   GtkTreeModel *tree_model;
1484   GtkTreeStore *tree_store;
1485   GtkTreeModel *src_model = NULL;
1486   GtkTreePath *src_path = NULL;
1487   gboolean retval = FALSE;
1488
1489   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
1490
1491   tree_model = GTK_TREE_MODEL (drag_dest);
1492   tree_store = GTK_TREE_STORE (drag_dest);
1493
1494   validate_tree (tree_store);
1495
1496   if (gtk_selection_data_get_tree_row (selection_data,
1497                                        &src_model,
1498                                        &src_path) &&
1499       src_model == tree_model)
1500     {
1501       /* Copy the given row to a new position */
1502       GtkTreeIter src_iter;
1503       GtkTreeIter dest_iter;
1504       GtkTreePath *prev;
1505
1506       if (!gtk_tree_model_get_iter (src_model,
1507                                     &src_iter,
1508                                     src_path))
1509         {
1510           goto out;
1511         }
1512
1513       /* Get the path to insert _after_ (dest is the path to insert _before_) */
1514       prev = gtk_tree_path_copy (dest);
1515
1516       if (!gtk_tree_path_prev (prev))
1517         {
1518           GtkTreeIter dest_parent;
1519           GtkTreePath *parent;
1520           GtkTreeIter *dest_parent_p;
1521
1522           /* dest was the first spot at the current depth; which means
1523            * we are supposed to prepend.
1524            */
1525
1526           /* Get the parent, NULL if parent is the root */
1527           dest_parent_p = NULL;
1528           parent = gtk_tree_path_copy (dest);
1529           if (gtk_tree_path_up (parent))
1530             {
1531               gtk_tree_model_get_iter (tree_model,
1532                                        &dest_parent,
1533                                        parent);
1534               dest_parent_p = &dest_parent;
1535             }
1536           gtk_tree_path_free (parent);
1537           parent = NULL;
1538
1539           gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
1540                                   &dest_iter,
1541                                   dest_parent_p);
1542
1543           retval = TRUE;
1544         }
1545       else
1546         {
1547           if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
1548                                        &dest_iter,
1549                                        prev))
1550             {
1551               GtkTreeIter tmp_iter = dest_iter;
1552               gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
1553                                            &dest_iter,
1554                                            NULL,
1555                                            &tmp_iter);
1556               retval = TRUE;
1557
1558             }
1559         }
1560
1561       gtk_tree_path_free (prev);
1562
1563       /* If we succeeded in creating dest_iter, walk src_iter tree branch,
1564        * duplicating it below dest_iter.
1565        */
1566
1567       if (retval)
1568         {
1569           recursive_node_copy (tree_store,
1570                                &src_iter,
1571                                &dest_iter);
1572         }
1573     }
1574   else
1575     {
1576       /* FIXME maybe add some data targets eventually, or handle text
1577        * targets in the simple case.
1578        */
1579
1580     }
1581
1582  out:
1583
1584   if (src_path)
1585     gtk_tree_path_free (src_path);
1586
1587   return retval;
1588 }
1589
1590 static gboolean
1591 gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
1592                                   GtkTreeModel    *src_model,
1593                                   GtkTreePath     *src_path,
1594                                   GtkTreePath     *dest_path)
1595 {
1596   /* can only drag to ourselves */
1597   if (src_model != GTK_TREE_MODEL (drag_dest))
1598     return FALSE;
1599
1600   /* Can't drop into ourself. */
1601   if (gtk_tree_path_is_ancestor (src_path,
1602                                  dest_path))
1603     return FALSE;
1604
1605   /* Can't drop if dest_path's parent doesn't exist */
1606   {
1607     GtkTreeIter iter;
1608     GtkTreePath *tmp = gtk_tree_path_copy (dest_path);
1609
1610     /* if we can't go up, we know the parent exists, the root
1611      * always exists.
1612      */
1613     if (gtk_tree_path_up (tmp))
1614       {
1615         if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
1616                                       &iter, tmp))
1617           {
1618             if (tmp)
1619               gtk_tree_path_free (tmp);
1620             return FALSE;
1621           }
1622       }
1623
1624     if (tmp)
1625       gtk_tree_path_free (tmp);
1626   }
1627
1628   /* Can otherwise drop anywhere. */
1629   return TRUE;
1630 }
1631
1632 /* Sorting */
1633 typedef struct _SortTuple
1634 {
1635   gint offset;
1636   GNode *node;
1637 } SortTuple;
1638
1639 static gint
1640 gtk_tree_store_compare_func (gconstpointer a,
1641                              gconstpointer b,
1642                              gpointer      user_data)
1643 {
1644   GtkTreeStore *tree_store = user_data;
1645   GNode *node_a;
1646   GNode *node_b;
1647   GtkTreeIterCompareFunc func;
1648   gpointer data;
1649
1650   GtkTreeIter iter_a;
1651   GtkTreeIter iter_b;
1652   gint retval;
1653
1654   if (tree_store->sort_column_id != -1)
1655     {
1656       GtkTreeDataSortHeader *header;
1657
1658       header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1659                                                tree_store->sort_column_id);
1660       g_return_val_if_fail (header != NULL, 0);
1661       g_return_val_if_fail (header->func != NULL, 0);
1662
1663       func = header->func;
1664       data = header->data;
1665     }
1666   else
1667     {
1668       g_return_val_if_fail (tree_store->default_sort_func != NULL, 0);
1669       func = tree_store->default_sort_func;
1670       data = tree_store->default_sort_data;
1671     }
1672
1673   node_a = ((SortTuple *) a)->node;
1674   node_b = ((SortTuple *) b)->node;
1675
1676   iter_a.stamp = tree_store->stamp;
1677   iter_a.user_data = node_a;
1678   iter_b.stamp = tree_store->stamp;
1679   iter_b.user_data = node_b;
1680
1681   retval = (* func) (GTK_TREE_MODEL (user_data), &iter_a, &iter_b, data);
1682
1683   if (tree_store->order == GTK_SORT_DESCENDING)
1684     {
1685       if (retval > 0)
1686         retval = -1;
1687       else if (retval < 0)
1688         retval = 1;
1689     }
1690   return retval;
1691 }
1692
1693 static void
1694 gtk_tree_store_sort_helper (GtkTreeStore *tree_store,
1695                             GNode        *parent,
1696                             gboolean      recurse)
1697 {
1698   GtkTreeIter iter;
1699   GArray *sort_array;
1700   GNode *node;
1701   GNode *tmp_node;
1702   gint list_length;
1703   gint i;
1704   gint *new_order;
1705   GtkTreePath *path;
1706
1707   node = parent->children;
1708   if (node == NULL || node->next == NULL)
1709     return;
1710
1711   g_assert (GTK_TREE_STORE_IS_SORTED (tree_store));
1712
1713   list_length = 0;
1714   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1715     list_length++;
1716
1717   sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), list_length);
1718
1719   i = 0;
1720   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1721     {
1722       SortTuple tuple;
1723
1724       tuple.offset = i;
1725       tuple.node = tmp_node;
1726       g_array_append_val (sort_array, tuple);
1727       i++;
1728     }
1729
1730   g_array_sort_with_data (sort_array, gtk_tree_store_compare_func, tree_store);
1731
1732   for (i = 0; i < list_length - 1; i++)
1733     {
1734       g_array_index (sort_array, SortTuple, i).node->next =
1735         g_array_index (sort_array, SortTuple, i + 1).node;
1736       g_array_index (sort_array, SortTuple, i + 1).node->prev =
1737         g_array_index (sort_array, SortTuple, i).node;
1738     }
1739   g_array_index (sort_array, SortTuple, list_length - 1).node->next = NULL;
1740   g_array_index (sort_array, SortTuple, 0).node->prev = NULL;
1741   parent->children = g_array_index (sort_array, SortTuple, 0).node;
1742
1743   /* Let the world know about our new order */
1744   new_order = g_new (gint, list_length);
1745   for (i = 0; i < list_length; i++)
1746     new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1747
1748   iter.stamp = tree_store->stamp;
1749   iter.user_data = parent;
1750   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &iter);
1751   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
1752                                  path, &iter, new_order);
1753   gtk_tree_path_free (path);
1754   g_free (new_order);
1755   g_array_free (sort_array, TRUE);
1756
1757   if (recurse)
1758     {
1759       for (tmp_node = parent->children; tmp_node; tmp_node = tmp_node->next)
1760         {
1761           if (tmp_node->children)
1762             gtk_tree_store_sort_helper (tree_store, tmp_node, TRUE);
1763         }
1764     }
1765 }
1766
1767 static void
1768 gtk_tree_store_sort (GtkTreeStore *tree_store)
1769 {
1770   if (tree_store->sort_column_id != -1)
1771     {
1772       GtkTreeDataSortHeader *header = NULL;
1773
1774       header = _gtk_tree_data_list_get_header (tree_store->sort_list, tree_store->sort_column_id);
1775
1776       /* We want to make sure that we have a function */
1777       g_return_if_fail (header != NULL);
1778       g_return_if_fail (header->func != NULL);
1779     }
1780   else
1781     {
1782       g_return_if_fail (tree_store->default_sort_func != NULL);
1783     }
1784
1785   gtk_tree_store_sort_helper (tree_store, G_NODE (tree_store->root), TRUE);
1786 }
1787
1788 static void
1789 gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
1790                                   GtkTreeIter  *iter,
1791                                   gint          column)
1792 {
1793   GNode *prev = NULL;
1794   GNode *next = NULL;
1795   GNode *node;
1796   GtkTreePath *tmp_path;
1797   GtkTreeIter tmp_iter;
1798   gint cmp_a = 0;
1799   gint cmp_b = 0;
1800   gint i;
1801   gint old_location;
1802   gint new_location;
1803   gint *new_order;
1804   gint length;
1805   GtkTreeIterCompareFunc func;
1806   gpointer data;
1807
1808   g_return_if_fail (G_NODE (iter->user_data)->parent != NULL);
1809
1810   tmp_iter.stamp = tree_store->stamp;
1811   if (tree_store->sort_column_id != -1)
1812     {
1813       GtkTreeDataSortHeader *header;
1814       header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1815                                                tree_store->sort_column_id);
1816       g_return_if_fail (header != NULL);
1817       g_return_if_fail (header->func != NULL);
1818       func = header->func;
1819       data = header->data;
1820     }
1821   else
1822     {
1823       g_return_if_fail (tree_store->default_sort_func != NULL);
1824       func = tree_store->default_sort_func;
1825       data = tree_store->default_sort_data;
1826     }
1827
1828   /* If it's the built in function, we don't sort. */
1829   if (func == gtk_tree_data_list_compare_func &&
1830       tree_store->sort_column_id != column)
1831     return;
1832
1833   old_location = 0;
1834   node = G_NODE (iter->user_data)->parent->children;
1835   /* First we find the iter, its prev, and its next */
1836   while (node)
1837     {
1838       if (node == G_NODE (iter->user_data))
1839         break;
1840       old_location++;
1841       node = node->next;
1842     }
1843   g_assert (node != NULL);
1844
1845   prev = node->prev;
1846   next = node->next;
1847
1848   /* Check the common case, where we don't need to sort it moved. */
1849   if (prev != NULL)
1850     {
1851       tmp_iter.user_data = prev;
1852       cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1853     }
1854
1855   if (next != NULL)
1856     {
1857       tmp_iter.user_data = next;
1858       cmp_b = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1859     }
1860
1861
1862   if (tree_store->order == GTK_SORT_DESCENDING)
1863     {
1864       if (cmp_a < 0)
1865         cmp_a = 1;
1866       else if (cmp_a > 0)
1867         cmp_a = -1;
1868
1869       if (cmp_b < 0)
1870         cmp_b = 1;
1871       else if (cmp_b > 0)
1872         cmp_b = -1;
1873     }
1874
1875   if (prev == NULL && cmp_b <= 0)
1876     return;
1877   else if (next == NULL && cmp_a <= 0)
1878     return;
1879   else if (prev != NULL && next != NULL &&
1880            cmp_a <= 0 && cmp_b <= 0)
1881     return;
1882
1883   /* We actually need to sort it */
1884   /* First, remove the old link. */
1885
1886   if (prev)
1887     prev->next = next;
1888   else
1889     node->parent->children = next;
1890   if (next)
1891     next->prev = prev;
1892
1893   node->prev = NULL;
1894   node->next = NULL;
1895
1896   /* FIXME: as an optimization, we can potentially start at next */
1897   prev = NULL;
1898   node = node->parent->children;
1899   new_location = 0;
1900   tmp_iter.user_data = node;
1901   if (tree_store->order == GTK_SORT_DESCENDING)
1902     cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1903   else
1904     cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1905
1906   while ((node->next) && (cmp_a > 0))
1907     {
1908       prev = node;
1909       node = node->next;
1910       new_location++;
1911       tmp_iter.user_data = node;
1912       if (tree_store->order == GTK_SORT_DESCENDING)
1913         cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1914       else
1915         cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1916     }
1917
1918   if ((!node->next) && (cmp_a > 0))
1919     {
1920       node->next = G_NODE (iter->user_data);
1921       node->next->prev = node;
1922     }
1923   else if (prev)
1924     {
1925       prev->next = G_NODE (iter->user_data);
1926       prev->next->prev = prev;
1927       G_NODE (iter->user_data)->next = node;
1928       G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
1929     }
1930   else
1931     {
1932       G_NODE (iter->user_data)->next = G_NODE (iter->user_data)->parent->children;
1933       G_NODE (iter->user_data)->parent->children = G_NODE (iter->user_data);
1934     }
1935
1936   /* Emit the reordered signal. */
1937   length = g_node_n_children (node->parent);
1938   new_order = g_new (int, length);
1939   if (old_location < new_location)
1940     for (i = 0; i < length; i++)
1941       {
1942         if (i < old_location ||
1943             i > new_location)
1944           new_order[i] = i;
1945         else if (i >= old_location &&
1946                  i < new_location)
1947           new_order[i] = i + 1;
1948         else if (i == new_location)
1949           new_order[i] = old_location;
1950       }
1951   else
1952     for (i = 0; i < length; i++)
1953       {
1954         if (i < new_location ||
1955             i > old_location)
1956           new_order[i] = i;
1957         else if (i > new_location &&
1958                  i <= old_location)
1959           new_order[i] = i - 1;
1960         else if (i == new_location)
1961           new_order[i] = old_location;
1962       }
1963
1964   tmp_iter.user_data = node->parent;
1965   tmp_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &tmp_iter);
1966
1967   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
1968                                  tmp_path, &tmp_iter,
1969                                  new_order);
1970
1971   gtk_tree_path_free (tmp_path);
1972   g_free (new_order);
1973 }
1974
1975
1976 static gboolean
1977 gtk_tree_store_get_sort_column_id (GtkTreeSortable  *sortable,
1978                                    gint             *sort_column_id,
1979                                    GtkSortType      *order)
1980 {
1981   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
1982
1983   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
1984
1985   if (tree_store->sort_column_id == -1)
1986     return FALSE;
1987
1988   if (sort_column_id)
1989     * sort_column_id = tree_store->sort_column_id;
1990   if (order)
1991     * order = tree_store->order;
1992   return TRUE;
1993
1994 }
1995
1996 static void
1997 gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
1998                                    gint              sort_column_id,
1999                                    GtkSortType       order)
2000 {
2001   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2002
2003   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2004
2005   
2006   if ((tree_store->sort_column_id == sort_column_id) &&
2007       (tree_store->order == order))
2008     return;
2009
2010   if (sort_column_id != -1)
2011     {
2012       GtkTreeDataSortHeader *header = NULL;
2013
2014       header = _gtk_tree_data_list_get_header (tree_store->sort_list, sort_column_id);
2015
2016       /* We want to make sure that we have a function */
2017       g_return_if_fail (header != NULL);
2018       g_return_if_fail (header->func != NULL);
2019     }
2020   else
2021     {
2022       g_return_if_fail (tree_store->default_sort_func != NULL);
2023     }
2024
2025   tree_store->sort_column_id = sort_column_id;
2026   tree_store->order = order;
2027
2028   gtk_tree_store_sort (tree_store);
2029
2030   gtk_tree_sortable_sort_column_changed (sortable);
2031 }
2032
2033 static void
2034 gtk_tree_store_set_sort_func (GtkTreeSortable        *sortable,
2035                               gint                    sort_column_id,
2036                               GtkTreeIterCompareFunc  func,
2037                               gpointer                data,
2038                               GtkDestroyNotify        destroy)
2039 {
2040   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2041   GtkTreeDataSortHeader *header = NULL;
2042   GList *list;
2043
2044   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2045   g_return_if_fail (func != NULL);
2046
2047   for (list = tree_store->sort_list; list; list = list->next)
2048     {
2049       header = (GtkTreeDataSortHeader*) list->data;
2050       if (header->sort_column_id == sort_column_id)
2051         break;
2052     }
2053
2054   if (header == NULL)
2055     {
2056       header = g_new0 (GtkTreeDataSortHeader, 1);
2057       header->sort_column_id = sort_column_id;
2058       tree_store->sort_list = g_list_append (tree_store->sort_list, header);
2059     }
2060
2061   if (header->destroy)
2062     (* header->destroy) (header->data);
2063
2064   header->func = func;
2065   header->data = data;
2066   header->destroy = destroy;
2067
2068 }
2069
2070 static void
2071 gtk_tree_store_set_default_sort_func (GtkTreeSortable        *sortable,
2072                                       GtkTreeIterCompareFunc  func,
2073                                       gpointer                data,
2074                                       GtkDestroyNotify        destroy)
2075 {
2076   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2077
2078   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2079
2080   if (tree_store->default_sort_destroy)
2081     (* tree_store->default_sort_destroy) (tree_store->default_sort_data);
2082
2083   tree_store->default_sort_func = func;
2084   tree_store->default_sort_data = data;
2085   tree_store->default_sort_destroy = destroy;
2086 }
2087
2088 static gboolean
2089 gtk_tree_store_has_default_sort_func (GtkTreeSortable *sortable)
2090 {
2091   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2092
2093   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
2094
2095   return (tree_store->default_sort_func != NULL);
2096 }
2097
2098 static void
2099 validate_gnode (GNode* node)
2100 {
2101   GNode *iter;
2102
2103   iter = node->children;
2104   while (iter != NULL)
2105     {
2106       g_assert (iter->parent == node);
2107       if (iter->prev)
2108         g_assert (iter->prev->next == iter);
2109       validate_gnode (iter);
2110       iter = iter->next;
2111     }
2112 }
2113
2114
2115