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