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