]> Pileus Git - ~andy/gtk/blob - gtk/gtktreestore.c
change GTK_MOVEMENT_PARAGRAPHS to go to start/end of paragraph before it
[~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 (column < GTK_TREE_STORE (tree_model)->n_columns);
616
617   list = G_NODE (iter->user_data)->data;
618
619   while (tmp_column-- > 0 && list)
620     list = list->next;
621
622   if (list)
623     {
624       _gtk_tree_data_list_node_to_value (list,
625                                          GTK_TREE_STORE (tree_model)->column_headers[column],
626                                          value);
627     }
628   else
629     {
630       /* We want to return an initialized but empty (default) value */
631       g_value_init (value, GTK_TREE_STORE (tree_model)->column_headers[column]);
632     }
633 }
634
635 static gboolean
636 gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
637                           GtkTreeIter   *iter)
638 {
639   g_return_val_if_fail (iter->user_data != NULL, FALSE);
640
641   if (G_NODE (iter->user_data)->next)
642     {
643       iter->user_data = G_NODE (iter->user_data)->next;
644       return TRUE;
645     }
646   else
647     return FALSE;
648 }
649
650 static gboolean
651 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
652                               GtkTreeIter  *iter,
653                               GtkTreeIter  *parent)
654 {
655   GNode *children;
656
657   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
658
659   if (parent)
660     children = G_NODE (parent->user_data)->children;
661   else
662     children = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
663
664   if (children)
665     {
666       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
667       iter->user_data = children;
668       return TRUE;
669     }
670   else
671     return FALSE;
672 }
673
674 static gboolean
675 gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
676                                GtkTreeIter  *iter)
677 {
678   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
679   g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, FALSE);
680   g_return_val_if_fail (iter->user_data != NULL, FALSE);
681
682   return G_NODE (iter->user_data)->children != NULL;
683 }
684
685 static gint
686 gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
687                                 GtkTreeIter  *iter)
688 {
689   GNode *node;
690   gint i = 0;
691
692   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
693   g_return_val_if_fail (iter == NULL || iter->user_data != NULL, FALSE);
694
695   if (iter == NULL)
696     node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
697   else
698     node = G_NODE (iter->user_data)->children;
699
700   while (node)
701     {
702       i++;
703       node = node->next;
704     }
705
706   return i;
707 }
708
709 static gboolean
710 gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
711                                GtkTreeIter  *iter,
712                                GtkTreeIter  *parent,
713                                gint          n)
714 {
715   GNode *parent_node;
716   GNode *child;
717
718   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
719   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
720
721   if (parent == NULL)
722     parent_node = GTK_TREE_STORE (tree_model)->root;
723   else
724     parent_node = parent->user_data;
725
726   child = g_node_nth_child (parent_node, n);
727
728   if (child)
729     {
730       iter->user_data = child;
731       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
732       return TRUE;
733     }
734   else
735     return FALSE;
736 }
737
738 static gboolean
739 gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
740                             GtkTreeIter  *iter,
741                             GtkTreeIter  *child)
742 {
743   GNode *parent;
744
745   g_return_val_if_fail (iter != NULL, FALSE);
746   g_return_val_if_fail (iter->user_data != NULL, FALSE);
747
748   parent = G_NODE (child->user_data)->parent;
749
750   g_assert (parent != NULL);
751
752   if (parent != GTK_TREE_STORE (tree_model)->root)
753     {
754       iter->user_data = parent;
755       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
756       return TRUE;
757     }
758   else
759     return FALSE;
760 }
761
762
763 /* Does not emit a signal */
764 static gboolean
765 gtk_tree_store_real_set_value (GtkTreeStore *tree_store,
766                                GtkTreeIter  *iter,
767                                gint          column,
768                                GValue       *value)
769 {
770   GtkTreeDataList *list;
771   GtkTreeDataList *prev;
772   GtkTreePath *path = NULL;
773   GValue real_value = {0, };
774   gboolean converted = FALSE;
775   gint orig_column = column;
776   gboolean retval = FALSE;
777
778   if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column]))
779     {
780       if (! (g_value_type_compatible (G_VALUE_TYPE (value), tree_store->column_headers[column]) &&
781              g_value_type_compatible (tree_store->column_headers[column], G_VALUE_TYPE (value))))
782         {
783           g_warning ("%s: Unable to convert from %s to %s\n",
784                      G_STRLOC,
785                      g_type_name (G_VALUE_TYPE (value)),
786                      g_type_name (tree_store->column_headers[column]));
787           return retval;
788         }
789       if (!g_value_transform (value, &real_value))
790         {
791           g_warning ("%s: Unable to make conversion from %s to %s\n",
792                      G_STRLOC,
793                      g_type_name (G_VALUE_TYPE (value)),
794                      g_type_name (tree_store->column_headers[column]));
795           g_value_unset (&real_value);
796           return retval;
797         }
798       converted = TRUE;
799     }
800
801   prev = list = G_NODE (iter->user_data)->data;
802
803   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
804
805   while (list != NULL)
806     {
807       if (column == 0)
808         {
809           if (converted)
810             _gtk_tree_data_list_value_to_node (list, &real_value);
811           else
812             _gtk_tree_data_list_value_to_node (list, value);
813           retval = TRUE;
814           gtk_tree_path_free (path);
815           if (converted)
816             g_value_unset (&real_value);
817           return retval;
818         }
819
820       column--;
821       prev = list;
822       list = list->next;
823     }
824
825   if (G_NODE (iter->user_data)->data == NULL)
826     {
827       G_NODE (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
828       list->next = NULL;
829     }
830   else
831     {
832       list = prev->next = _gtk_tree_data_list_alloc ();
833       list->next = NULL;
834     }
835
836   while (column != 0)
837     {
838       list->next = _gtk_tree_data_list_alloc ();
839       list = list->next;
840       list->next = NULL;
841       column --;
842     }
843   if (converted)
844     _gtk_tree_data_list_value_to_node (list, &real_value);
845   else
846     _gtk_tree_data_list_value_to_node (list, value);
847   
848   retval = TRUE;
849   gtk_tree_path_free (path);
850   if (converted)
851     g_value_unset (&real_value);
852
853   if (GTK_TREE_STORE_IS_SORTED (tree_store))
854     gtk_tree_store_sort_iter_changed (tree_store, iter, orig_column);
855
856   return retval;
857 }
858
859 /**
860  * gtk_tree_store_set_value:
861  * @tree_store: a #GtkTreeStore
862  * @iter: A valid #GtkTreeIter for the row being modified
863  * @column: column number to modify
864  * @value: new value for the cell
865  *
866  * Sets the data in the cell specified by @iter and @column.
867  * The type of @value must be convertible to the type of the
868  * column.
869  *
870  **/
871 void
872 gtk_tree_store_set_value (GtkTreeStore *tree_store,
873                           GtkTreeIter  *iter,
874                           gint          column,
875                           GValue       *value)
876 {
877   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
878   g_return_if_fail (VALID_ITER (iter, tree_store));
879   g_return_if_fail (column >= 0 && column < tree_store->n_columns);
880   g_return_if_fail (G_IS_VALUE (value));
881
882   if (gtk_tree_store_real_set_value (tree_store, iter, column, value))
883     {
884       GtkTreePath *path;
885
886       path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
887       gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
888       gtk_tree_path_free (path);
889     }
890 }
891
892 /**
893  * gtk_tree_store_set_valist:
894  * @tree_store: A #GtkTreeStore
895  * @iter: A valid #GtkTreeIter for the row being modified
896  * @var_args: <type>va_list</type> of column/value pairs
897  *
898  * See gtk_tree_store_set(); this version takes a <type>va_list</type> for
899  * use by language bindings.
900  *
901  **/
902 void
903 gtk_tree_store_set_valist (GtkTreeStore *tree_store,
904                            GtkTreeIter  *iter,
905                            va_list      var_args)
906 {
907   gint column;
908   gboolean emit_signal = FALSE;
909
910   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
911   g_return_if_fail (VALID_ITER (iter, tree_store));
912
913   column = va_arg (var_args, gint);
914
915   while (column != -1)
916     {
917       GValue value = { 0, };
918       gchar *error = NULL;
919
920       if (column >= tree_store->n_columns)
921         {
922           g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
923           break;
924         }
925       g_value_init (&value, tree_store->column_headers[column]);
926
927       G_VALUE_COLLECT (&value, var_args, 0, &error);
928       if (error)
929         {
930           g_warning ("%s: %s", G_STRLOC, error);
931           g_free (error);
932
933           /* we purposely leak the value here, it might not be
934            * in a sane state if an error condition occoured
935            */
936           break;
937         }
938
939       emit_signal = gtk_tree_store_real_set_value (tree_store,
940                                                    iter,
941                                                    column,
942                                                    &value) || emit_signal;
943
944       g_value_unset (&value);
945
946       column = va_arg (var_args, gint);
947     }
948   if (emit_signal)
949     {
950       GtkTreePath *path;
951
952       path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_store), iter);
953       gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
954       gtk_tree_path_free (path);
955     }
956 }
957
958 /**
959  * gtk_tree_store_set:
960  * @tree_store: A #GtkTreeStore
961  * @iter: A valid #GtkTreeIter for the row being modified
962  * @Varargs: pairs of column number and value, terminated with -1
963  *
964  * Sets the value of one or more cells in the row referenced by @iter.
965  * The variable argument list should contain integer column numbers,
966  * each column number followed by the value to be set. 
967  * The list is terminated by a -1. For example, to set column 0 with type
968  * %G_TYPE_STRING to "Foo", you would write 
969  * <literal>gtk_tree_store_set (store, iter, 0, "Foo", -1)</literal>.
970  **/
971 void
972 gtk_tree_store_set (GtkTreeStore *tree_store,
973                     GtkTreeIter  *iter,
974                     ...)
975 {
976   va_list var_args;
977
978   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
979   g_return_if_fail (VALID_ITER (iter, tree_store));
980
981   va_start (var_args, iter);
982   gtk_tree_store_set_valist (tree_store, iter, var_args);
983   va_end (var_args);
984 }
985
986 /**
987  * gtk_tree_store_remove:
988  * @tree_store: A #GtkTreeStore
989  * @iter: A valid #GtkTreeIter
990  * 
991  * Removes @iter from @tree_store.  After being removed, @iter is set to the
992  * next valid row at that level, or invalidated if it previously pointed to the
993  * last one.
994  **/
995 void
996 gtk_tree_store_remove (GtkTreeStore *tree_store,
997                        GtkTreeIter  *iter)
998 {
999   GtkTreePath *path;
1000   GtkTreeIter new_iter = {0,};
1001   GNode *parent;
1002   GNode *next_node;
1003
1004   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1005   g_return_if_fail (VALID_ITER (iter, tree_store));
1006
1007   parent = G_NODE (iter->user_data)->parent;
1008
1009   g_assert (parent != NULL);
1010   next_node = G_NODE (iter->user_data)->next;
1011
1012   if (G_NODE (iter->user_data)->data)
1013     _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
1014                               tree_store->column_headers);
1015
1016   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1017   g_node_destroy (G_NODE (iter->user_data));
1018
1019   gtk_tree_model_row_deleted (GTK_TREE_MODEL (tree_store), path);
1020
1021   if (parent != G_NODE (tree_store->root))
1022     {
1023       /* child_toggled */
1024       if (parent->children == NULL)
1025         {
1026           gtk_tree_path_up (path);
1027
1028           new_iter.stamp = tree_store->stamp;
1029           new_iter.user_data = parent;
1030           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &new_iter);
1031         }
1032     }
1033   gtk_tree_path_free (path);
1034
1035   /* revalidate iter */
1036   if (next_node != NULL)
1037     {
1038       iter->stamp = tree_store->stamp;
1039       iter->user_data = next_node;
1040     }
1041   else
1042     {
1043       iter->stamp = 0;
1044       iter->user_data = NULL;
1045     }
1046 }
1047
1048 /**
1049  * gtk_tree_store_insert:
1050  * @tree_store: A #GtkTreeStore
1051  * @iter: An unset #GtkTreeIter to set to the new row
1052  * @parent: A valid #GtkTreeIter, or %NULL
1053  * @position: position to insert the new row
1054  *
1055  * Creates a new row at @position.  If parent is non-%NULL, then the row will be
1056  * made a child of @parent.  Otherwise, the row will be created at the toplevel.
1057  * If @position is larger than the number of rows at that level, then the new
1058  * row will be inserted to the end of the list.  @iter will be changed to point
1059  * to this new row.  The row will be empty before this function is called.  To
1060  * fill in values, you need to call gtk_tree_store_set() or
1061  * gtk_tree_store_set_value().
1062  *
1063  **/
1064 void
1065 gtk_tree_store_insert (GtkTreeStore *tree_store,
1066                        GtkTreeIter  *iter,
1067                        GtkTreeIter  *parent,
1068                        gint          position)
1069 {
1070   GtkTreePath *path;
1071   GNode *parent_node;
1072
1073   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1074   if (parent)
1075     g_return_if_fail (VALID_ITER (parent, tree_store));
1076
1077   if (parent)
1078     parent_node = parent->user_data;
1079   else
1080     parent_node = tree_store->root;
1081
1082   tree_store->columns_dirty = TRUE;
1083
1084   iter->stamp = tree_store->stamp;
1085   iter->user_data = g_node_new (NULL);
1086   g_node_insert (parent_node, position, G_NODE (iter->user_data));
1087
1088   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1089   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1090
1091   gtk_tree_path_free (path);
1092
1093   validate_tree ((GtkTreeStore*)tree_store);
1094 }
1095
1096 /**
1097  * gtk_tree_store_insert_before:
1098  * @tree_store: A #GtkTreeStore
1099  * @iter: An unset #GtkTreeIter to set to the new row
1100  * @parent: A valid #GtkTreeIter, or %NULL
1101  * @sibling: A valid #GtkTreeIter, or %NULL
1102  *
1103  * Inserts a new row before @sibling.  If @sibling is %NULL, then the row will
1104  * be appended to the beginning of the @parent 's children.  If @parent and
1105  * @sibling are %NULL, then the row will be appended to the toplevel.  If both
1106  * @sibling and @parent are set, then @parent must be the parent of @sibling.
1107  * When @sibling is set, @parent is optional.
1108  *
1109  * @iter will be changed to point to this new row.  The row will be empty after
1110  * this function is called.  To fill in values, you need to call
1111  * gtk_tree_store_set() or gtk_tree_store_set_value().
1112  *
1113  **/
1114 void
1115 gtk_tree_store_insert_before (GtkTreeStore *tree_store,
1116                               GtkTreeIter  *iter,
1117                               GtkTreeIter  *parent,
1118                               GtkTreeIter  *sibling)
1119 {
1120   GtkTreePath *path;
1121   GNode *parent_node = NULL;
1122   GNode *new_node;
1123
1124   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1125   g_return_if_fail (iter != NULL);
1126   if (parent != NULL)
1127     g_return_if_fail (VALID_ITER (parent, tree_store));
1128   if (sibling != NULL)
1129     g_return_if_fail (VALID_ITER (sibling, tree_store));
1130
1131   tree_store->columns_dirty = TRUE;
1132
1133   new_node = g_node_new (NULL);
1134
1135   if (parent == NULL && sibling == NULL)
1136     parent_node = tree_store->root;
1137   else if (parent == NULL)
1138     parent_node = G_NODE (sibling->user_data)->parent;
1139   else if (sibling == NULL)
1140     parent_node = G_NODE (parent->user_data);
1141   else
1142     {
1143       g_return_if_fail (G_NODE (sibling->user_data)->parent == G_NODE (parent->user_data));
1144       parent_node = G_NODE (parent->user_data);
1145     }
1146
1147   g_node_insert_before (parent_node,
1148                         sibling ? G_NODE (sibling->user_data) : NULL,
1149                         new_node);
1150
1151   iter->stamp = tree_store->stamp;
1152   iter->user_data = new_node;
1153
1154   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1155   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1156
1157   gtk_tree_path_free (path);
1158
1159   validate_tree ((GtkTreeStore*)tree_store);
1160 }
1161
1162 /**
1163  * gtk_tree_store_insert_after:
1164  * @tree_store: A #GtkTreeStore
1165  * @iter: An unset #GtkTreeIter to set to the new row
1166  * @parent: A valid #GtkTreeIter, or %NULL
1167  * @sibling: A valid #GtkTreeIter, or %NULL
1168  *
1169  * Inserts a new row after @sibling.  If @sibling is %NULL, then the row will be
1170  * prepended to the beginning of the @parent 's children.  If @parent and
1171  * @sibling are %NULL, then the row will be prepended to the toplevel.  If both
1172  * @sibling and @parent are set, then @parent must be the parent of @sibling.
1173  * When @sibling is set, @parent is optional.
1174  *
1175  * @iter will be changed to point to this new row.  The row will be empty after
1176  * this function is called.  To fill in values, you need to call
1177  * gtk_tree_store_set() or gtk_tree_store_set_value().
1178  *
1179  **/
1180 void
1181 gtk_tree_store_insert_after (GtkTreeStore *tree_store,
1182                              GtkTreeIter  *iter,
1183                              GtkTreeIter  *parent,
1184                              GtkTreeIter  *sibling)
1185 {
1186   GtkTreePath *path;
1187   GNode *parent_node;
1188   GNode *new_node;
1189
1190   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1191   g_return_if_fail (iter != NULL);
1192   if (parent != NULL)
1193     g_return_if_fail (VALID_ITER (parent, tree_store));
1194   if (sibling != NULL)
1195     g_return_if_fail (VALID_ITER (sibling, tree_store));
1196
1197   tree_store->columns_dirty = TRUE;
1198
1199   new_node = g_node_new (NULL);
1200
1201   if (parent == NULL && sibling == NULL)
1202     parent_node = tree_store->root;
1203   else if (parent == NULL)
1204     parent_node = G_NODE (sibling->user_data)->parent;
1205   else if (sibling == NULL)
1206     parent_node = G_NODE (parent->user_data);
1207   else
1208     {
1209       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
1210                         G_NODE (parent->user_data));
1211       parent_node = G_NODE (parent->user_data);
1212     }
1213
1214
1215   g_node_insert_after (parent_node,
1216                        sibling ? G_NODE (sibling->user_data) : NULL,
1217                        new_node);
1218
1219   iter->stamp = tree_store->stamp;
1220   iter->user_data = new_node;
1221
1222   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1223   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1224
1225   gtk_tree_path_free (path);
1226
1227   validate_tree ((GtkTreeStore*)tree_store);
1228 }
1229
1230 /**
1231  * gtk_tree_store_prepend:
1232  * @tree_store: A #GtkTreeStore
1233  * @iter: An unset #GtkTreeIter to set to the prepended row
1234  * @parent: A valid #GtkTreeIter, or %NULL
1235  * 
1236  * Prepends a new row to @tree_store.  If @parent is non-%NULL, then it will prepend
1237  * the new row before the first child of @parent, otherwise it will prepend a row
1238  * to the top level.  @iter will be changed to point to this new row.  The row
1239  * will be empty after this function is called.  To fill in values, you need to
1240  * call gtk_tree_store_set() or gtk_tree_store_set_value().
1241  **/
1242 void
1243 gtk_tree_store_prepend (GtkTreeStore *tree_store,
1244                         GtkTreeIter  *iter,
1245                         GtkTreeIter  *parent)
1246 {
1247   GNode *parent_node;
1248
1249   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1250   g_return_if_fail (iter != NULL);
1251   if (parent != NULL)
1252     g_return_if_fail (VALID_ITER (parent, tree_store));
1253
1254   tree_store->columns_dirty = TRUE;
1255
1256   if (parent == NULL)
1257     parent_node = tree_store->root;
1258   else
1259     parent_node = parent->user_data;
1260
1261   if (parent_node->children == NULL)
1262     {
1263       GtkTreePath *path;
1264       
1265       iter->stamp = tree_store->stamp;
1266       iter->user_data = g_node_new (NULL);
1267
1268       g_node_prepend (parent_node, iter->user_data);
1269
1270       path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1271       gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1272
1273       if (parent_node != tree_store->root)
1274         {
1275           gtk_tree_path_up (path);
1276           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1277         }
1278       gtk_tree_path_free (path);
1279     }
1280   else
1281     {
1282       gtk_tree_store_insert_after (tree_store, iter, parent, NULL);
1283     }
1284
1285   validate_tree ((GtkTreeStore*)tree_store);
1286 }
1287
1288 /**
1289  * gtk_tree_store_append:
1290  * @tree_store: A #GtkTreeStore
1291  * @iter: An unset #GtkTreeIter to set to the appended row
1292  * @parent: A valid #GtkTreeIter, or %NULL
1293  * 
1294  * Appends a new row to @tree_store.  If @parent is non-%NULL, then it will append the
1295  * new row after the last child of @parent, otherwise it will append a row to
1296  * the top level.  @iter will be changed to point to this new row.  The row will
1297  * be empty after this function is called.  To fill in values, you need to call
1298  * gtk_tree_store_set() or gtk_tree_store_set_value().
1299  **/
1300 void
1301 gtk_tree_store_append (GtkTreeStore *tree_store,
1302                        GtkTreeIter  *iter,
1303                        GtkTreeIter  *parent)
1304 {
1305   GNode *parent_node;
1306
1307   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1308   g_return_if_fail (iter != NULL);
1309
1310   if (parent != NULL)
1311     g_return_if_fail (VALID_ITER (parent, tree_store));
1312
1313   if (parent == NULL)
1314     parent_node = tree_store->root;
1315   else
1316     parent_node = parent->user_data;
1317
1318   tree_store->columns_dirty = TRUE;
1319
1320   if (parent_node->children == NULL)
1321     {
1322       GtkTreePath *path;
1323
1324       iter->stamp = tree_store->stamp;
1325       iter->user_data = g_node_new (NULL);
1326
1327       g_node_append (parent_node, G_NODE (iter->user_data));
1328
1329       path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1330       gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1331
1332       if (parent_node != tree_store->root)
1333         {
1334           gtk_tree_path_up (path);
1335           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1336         }
1337       gtk_tree_path_free (path);
1338     }
1339   else
1340     {
1341       gtk_tree_store_insert_before (tree_store, iter, parent, NULL);
1342     }
1343
1344   validate_tree ((GtkTreeStore*)tree_store);
1345 }
1346
1347 /**
1348  * gtk_tree_store_is_ancestor:
1349  * @tree_store: A #GtkTreeStore
1350  * @iter: A valid #GtkTreeIter
1351  * @descendant: A valid #GtkTreeIter
1352  * 
1353  * Returns %TRUE if @iter is an ancestor of @descendant.  That is, @iter is the
1354  * parent (or grandparent or great-grandparent) of @descendant.
1355  * 
1356  * Return value: %TRUE, if @iter is an ancestor of @descendant
1357  **/
1358 gboolean
1359 gtk_tree_store_is_ancestor (GtkTreeStore *tree_store,
1360                             GtkTreeIter  *iter,
1361                             GtkTreeIter  *descendant)
1362 {
1363   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1364   g_return_val_if_fail (VALID_ITER (iter, tree_store), FALSE);
1365   g_return_val_if_fail (VALID_ITER (descendant, tree_store), FALSE);
1366
1367   return g_node_is_ancestor (G_NODE (iter->user_data),
1368                              G_NODE (descendant->user_data));
1369 }
1370
1371
1372 /**
1373  * gtk_tree_store_iter_depth:
1374  * @tree_store: A #GtkTreeStore
1375  * @iter: A valid #GtkTreeIter
1376  * 
1377  * Returns the depth of @iter.  This will be 0 for anything on the root level, 1
1378  * for anything down a level, etc.
1379  * 
1380  * Return value: The depth of @iter
1381  **/
1382 gint
1383 gtk_tree_store_iter_depth (GtkTreeStore *tree_store,
1384                            GtkTreeIter  *iter)
1385 {
1386   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), 0);
1387   g_return_val_if_fail (VALID_ITER (iter, tree_store), 0);
1388
1389   return g_node_depth (G_NODE (iter->user_data)) - 2;
1390 }
1391
1392 /**
1393  * gtk_tree_store_clear:
1394  * @tree_store: a #GtkTreeStore
1395  * 
1396  * Removes all rows from @tree_store
1397  **/
1398 void
1399 gtk_tree_store_clear (GtkTreeStore *tree_store)
1400 {
1401   GtkTreeIter iter;
1402
1403   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1404
1405   while (G_NODE (tree_store->root)->children)
1406     {
1407       iter.stamp = tree_store->stamp;
1408       iter.user_data = G_NODE (tree_store->root)->children;
1409       gtk_tree_store_remove (tree_store, &iter);
1410     }
1411 }
1412
1413 /* DND */
1414
1415
1416 static gboolean
1417 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1418                                  GtkTreePath       *path)
1419 {
1420   GtkTreeIter iter;
1421
1422   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1423
1424   if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
1425                                &iter,
1426                                path))
1427     {
1428       gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1429                              &iter);
1430       return TRUE;
1431     }
1432   else
1433     {
1434       return FALSE;
1435     }
1436 }
1437
1438 static gboolean
1439 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1440                               GtkTreePath       *path,
1441                               GtkSelectionData  *selection_data)
1442 {
1443   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1444
1445   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1446    * target, because the default handler does it for us, but
1447    * we do anyway for the convenience of someone maybe overriding the
1448    * default handler.
1449    */
1450
1451   if (gtk_tree_set_row_drag_data (selection_data,
1452                                   GTK_TREE_MODEL (drag_source),
1453                                   path))
1454     {
1455       return TRUE;
1456     }
1457   else
1458     {
1459       /* FIXME handle text targets at least. */
1460     }
1461
1462   return FALSE;
1463 }
1464
1465 static void
1466 copy_node_data (GtkTreeStore *tree_store,
1467                 GtkTreeIter  *src_iter,
1468                 GtkTreeIter  *dest_iter)
1469 {
1470   GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1471   GtkTreeDataList *copy_head = NULL;
1472   GtkTreeDataList *copy_prev = NULL;
1473   GtkTreeDataList *copy_iter = NULL;
1474   GtkTreePath *path;
1475   gint col;
1476
1477   col = 0;
1478   while (dl)
1479     {
1480       copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1481
1482       if (copy_head == NULL)
1483         copy_head = copy_iter;
1484
1485       if (copy_prev)
1486         copy_prev->next = copy_iter;
1487
1488       copy_prev = copy_iter;
1489
1490       dl = dl->next;
1491       ++col;
1492     }
1493
1494   G_NODE (dest_iter->user_data)->data = copy_head;
1495
1496   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1497   gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, dest_iter);
1498   gtk_tree_path_free (path);
1499 }
1500
1501 static void
1502 recursive_node_copy (GtkTreeStore *tree_store,
1503                      GtkTreeIter  *src_iter,
1504                      GtkTreeIter  *dest_iter)
1505 {
1506   GtkTreeIter child;
1507   GtkTreeModel *model;
1508
1509   model = GTK_TREE_MODEL (tree_store);
1510
1511   copy_node_data (tree_store, src_iter, dest_iter);
1512
1513   if (gtk_tree_model_iter_children (model,
1514                                     &child,
1515                                     src_iter))
1516     {
1517       /* Need to create children and recurse. Note our
1518        * dependence on persistent iterators here.
1519        */
1520       do
1521         {
1522           GtkTreeIter copy;
1523
1524           /* Gee, a really slow algorithm... ;-) FIXME */
1525           gtk_tree_store_append (tree_store,
1526                                  &copy,
1527                                  dest_iter);
1528
1529           recursive_node_copy (tree_store, &child, &copy);
1530         }
1531       while (gtk_tree_model_iter_next (model, &child));
1532     }
1533 }
1534
1535 static gboolean
1536 gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
1537                                    GtkTreePath       *dest,
1538                                    GtkSelectionData  *selection_data)
1539 {
1540   GtkTreeModel *tree_model;
1541   GtkTreeStore *tree_store;
1542   GtkTreeModel *src_model = NULL;
1543   GtkTreePath *src_path = NULL;
1544   gboolean retval = FALSE;
1545
1546   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
1547
1548   tree_model = GTK_TREE_MODEL (drag_dest);
1549   tree_store = GTK_TREE_STORE (drag_dest);
1550
1551   validate_tree (tree_store);
1552
1553   if (gtk_tree_get_row_drag_data (selection_data,
1554                                   &src_model,
1555                                   &src_path) &&
1556       src_model == tree_model)
1557     {
1558       /* Copy the given row to a new position */
1559       GtkTreeIter src_iter;
1560       GtkTreeIter dest_iter;
1561       GtkTreePath *prev;
1562
1563       if (!gtk_tree_model_get_iter (src_model,
1564                                     &src_iter,
1565                                     src_path))
1566         {
1567           goto out;
1568         }
1569
1570       /* Get the path to insert _after_ (dest is the path to insert _before_) */
1571       prev = gtk_tree_path_copy (dest);
1572
1573       if (!gtk_tree_path_prev (prev))
1574         {
1575           GtkTreeIter dest_parent;
1576           GtkTreePath *parent;
1577           GtkTreeIter *dest_parent_p;
1578
1579           /* dest was the first spot at the current depth; which means
1580            * we are supposed to prepend.
1581            */
1582
1583           /* Get the parent, NULL if parent is the root */
1584           dest_parent_p = NULL;
1585           parent = gtk_tree_path_copy (dest);
1586           if (gtk_tree_path_up (parent))
1587             {
1588               gtk_tree_model_get_iter (tree_model,
1589                                        &dest_parent,
1590                                        parent);
1591               dest_parent_p = &dest_parent;
1592             }
1593           gtk_tree_path_free (parent);
1594           parent = NULL;
1595
1596           gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
1597                                   &dest_iter,
1598                                   dest_parent_p);
1599
1600           retval = TRUE;
1601         }
1602       else
1603         {
1604           if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
1605                                        &dest_iter,
1606                                        prev))
1607             {
1608               GtkTreeIter tmp_iter = dest_iter;
1609               gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
1610                                            &dest_iter,
1611                                            NULL,
1612                                            &tmp_iter);
1613               retval = TRUE;
1614
1615             }
1616         }
1617
1618       gtk_tree_path_free (prev);
1619
1620       /* If we succeeded in creating dest_iter, walk src_iter tree branch,
1621        * duplicating it below dest_iter.
1622        */
1623
1624       if (retval)
1625         {
1626           recursive_node_copy (tree_store,
1627                                &src_iter,
1628                                &dest_iter);
1629         }
1630     }
1631   else
1632     {
1633       /* FIXME maybe add some data targets eventually, or handle text
1634        * targets in the simple case.
1635        */
1636
1637     }
1638
1639  out:
1640
1641   if (src_path)
1642     gtk_tree_path_free (src_path);
1643
1644   return retval;
1645 }
1646
1647 static gboolean
1648 gtk_tree_store_row_drop_possible (GtkTreeDragDest  *drag_dest,
1649                                   GtkTreePath      *dest_path,
1650                                   GtkSelectionData *selection_data)
1651 {
1652   GtkTreeModel *src_model = NULL;
1653   GtkTreePath *src_path = NULL;
1654   GtkTreePath *tmp = NULL;
1655   gboolean retval = FALSE;
1656   
1657   if (!gtk_tree_get_row_drag_data (selection_data,
1658                                    &src_model,
1659                                    &src_path))
1660     goto out;
1661     
1662   /* can only drag to ourselves */
1663   if (src_model != GTK_TREE_MODEL (drag_dest))
1664     goto out;
1665
1666   /* Can't drop into ourself. */
1667   if (gtk_tree_path_is_ancestor (src_path,
1668                                  dest_path))
1669     goto out;
1670
1671   /* Can't drop if dest_path's parent doesn't exist */
1672   {
1673     GtkTreeIter iter;
1674
1675     if (gtk_tree_path_get_depth (dest_path) > 1)
1676       {
1677         tmp = gtk_tree_path_copy (dest_path);
1678         gtk_tree_path_up (tmp);
1679         
1680         if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
1681                                       &iter, tmp))
1682           goto out;
1683       }
1684   }
1685   
1686   /* Can otherwise drop anywhere. */
1687   retval = TRUE;
1688
1689  out:
1690
1691   if (src_path)
1692     gtk_tree_path_free (src_path);
1693   if (tmp)
1694     gtk_tree_path_free (tmp);
1695
1696   return retval;
1697 }
1698
1699 /* Sorting */
1700 typedef struct _SortTuple
1701 {
1702   gint offset;
1703   GNode *node;
1704 } SortTuple;
1705
1706 static gint
1707 gtk_tree_store_compare_func (gconstpointer a,
1708                              gconstpointer b,
1709                              gpointer      user_data)
1710 {
1711   GtkTreeStore *tree_store = user_data;
1712   GNode *node_a;
1713   GNode *node_b;
1714   GtkTreeIterCompareFunc func;
1715   gpointer data;
1716
1717   GtkTreeIter iter_a;
1718   GtkTreeIter iter_b;
1719   gint retval;
1720
1721   if (tree_store->sort_column_id != -1)
1722     {
1723       GtkTreeDataSortHeader *header;
1724
1725       header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1726                                                tree_store->sort_column_id);
1727       g_return_val_if_fail (header != NULL, 0);
1728       g_return_val_if_fail (header->func != NULL, 0);
1729
1730       func = header->func;
1731       data = header->data;
1732     }
1733   else
1734     {
1735       g_return_val_if_fail (tree_store->default_sort_func != NULL, 0);
1736       func = tree_store->default_sort_func;
1737       data = tree_store->default_sort_data;
1738     }
1739
1740   node_a = ((SortTuple *) a)->node;
1741   node_b = ((SortTuple *) b)->node;
1742
1743   iter_a.stamp = tree_store->stamp;
1744   iter_a.user_data = node_a;
1745   iter_b.stamp = tree_store->stamp;
1746   iter_b.user_data = node_b;
1747
1748   retval = (* func) (GTK_TREE_MODEL (user_data), &iter_a, &iter_b, data);
1749
1750   if (tree_store->order == GTK_SORT_DESCENDING)
1751     {
1752       if (retval > 0)
1753         retval = -1;
1754       else if (retval < 0)
1755         retval = 1;
1756     }
1757   return retval;
1758 }
1759
1760 static void
1761 gtk_tree_store_sort_helper (GtkTreeStore *tree_store,
1762                             GNode        *parent,
1763                             gboolean      recurse)
1764 {
1765   GtkTreeIter iter;
1766   GArray *sort_array;
1767   GNode *node;
1768   GNode *tmp_node;
1769   gint list_length;
1770   gint i;
1771   gint *new_order;
1772   GtkTreePath *path;
1773
1774   node = parent->children;
1775   if (node == NULL || node->next == NULL)
1776     return;
1777
1778   g_assert (GTK_TREE_STORE_IS_SORTED (tree_store));
1779
1780   list_length = 0;
1781   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1782     list_length++;
1783
1784   sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), list_length);
1785
1786   i = 0;
1787   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1788     {
1789       SortTuple tuple;
1790
1791       tuple.offset = i;
1792       tuple.node = tmp_node;
1793       g_array_append_val (sort_array, tuple);
1794       i++;
1795     }
1796
1797   /* Sort the array */
1798   g_array_sort_with_data (sort_array, gtk_tree_store_compare_func, tree_store);
1799
1800   for (i = 0; i < list_length - 1; i++)
1801     {
1802       g_array_index (sort_array, SortTuple, i).node->next =
1803         g_array_index (sort_array, SortTuple, i + 1).node;
1804       g_array_index (sort_array, SortTuple, i + 1).node->prev =
1805         g_array_index (sort_array, SortTuple, i).node;
1806     }
1807   g_array_index (sort_array, SortTuple, list_length - 1).node->next = NULL;
1808   g_array_index (sort_array, SortTuple, 0).node->prev = NULL;
1809   parent->children = g_array_index (sort_array, SortTuple, 0).node;
1810
1811   /* Let the world know about our new order */
1812   new_order = g_new (gint, list_length);
1813   for (i = 0; i < list_length; i++)
1814     new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1815
1816   iter.stamp = tree_store->stamp;
1817   iter.user_data = parent;
1818   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &iter);
1819   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
1820                                  path, &iter, new_order);
1821   gtk_tree_path_free (path);
1822   g_free (new_order);
1823   g_array_free (sort_array, TRUE);
1824
1825   if (recurse)
1826     {
1827       for (tmp_node = parent->children; tmp_node; tmp_node = tmp_node->next)
1828         {
1829           if (tmp_node->children)
1830             gtk_tree_store_sort_helper (tree_store, tmp_node, TRUE);
1831         }
1832     }
1833 }
1834
1835 static void
1836 gtk_tree_store_sort (GtkTreeStore *tree_store)
1837 {
1838   if (tree_store->sort_column_id != -1)
1839     {
1840       GtkTreeDataSortHeader *header = NULL;
1841
1842       header = _gtk_tree_data_list_get_header (tree_store->sort_list, tree_store->sort_column_id);
1843
1844       /* We want to make sure that we have a function */
1845       g_return_if_fail (header != NULL);
1846       g_return_if_fail (header->func != NULL);
1847     }
1848   else
1849     {
1850       g_return_if_fail (tree_store->default_sort_func != NULL);
1851     }
1852
1853   gtk_tree_store_sort_helper (tree_store, G_NODE (tree_store->root), TRUE);
1854 }
1855
1856 static void
1857 gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
1858                                   GtkTreeIter  *iter,
1859                                   gint          column)
1860 {
1861   GNode *prev = NULL;
1862   GNode *next = NULL;
1863   GNode *node;
1864   GtkTreePath *tmp_path;
1865   GtkTreeIter tmp_iter;
1866   gint cmp_a = 0;
1867   gint cmp_b = 0;
1868   gint i;
1869   gint old_location;
1870   gint new_location;
1871   gint *new_order;
1872   gint length;
1873   GtkTreeIterCompareFunc func;
1874   gpointer data;
1875
1876   g_return_if_fail (G_NODE (iter->user_data)->parent != NULL);
1877
1878   tmp_iter.stamp = tree_store->stamp;
1879   if (tree_store->sort_column_id != -1)
1880     {
1881       GtkTreeDataSortHeader *header;
1882       header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1883                                                tree_store->sort_column_id);
1884       g_return_if_fail (header != NULL);
1885       g_return_if_fail (header->func != NULL);
1886       func = header->func;
1887       data = header->data;
1888     }
1889   else
1890     {
1891       g_return_if_fail (tree_store->default_sort_func != NULL);
1892       func = tree_store->default_sort_func;
1893       data = tree_store->default_sort_data;
1894     }
1895
1896   /* If it's the built in function, we don't sort. */
1897   if (func == gtk_tree_data_list_compare_func &&
1898       tree_store->sort_column_id != column)
1899     return;
1900
1901   old_location = 0;
1902   node = G_NODE (iter->user_data)->parent->children;
1903   /* First we find the iter, its prev, and its next */
1904   while (node)
1905     {
1906       if (node == G_NODE (iter->user_data))
1907         break;
1908       old_location++;
1909       node = node->next;
1910     }
1911   g_assert (node != NULL);
1912
1913   prev = node->prev;
1914   next = node->next;
1915
1916   /* Check the common case, where we don't need to sort it moved. */
1917   if (prev != NULL)
1918     {
1919       tmp_iter.user_data = prev;
1920       cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1921     }
1922
1923   if (next != NULL)
1924     {
1925       tmp_iter.user_data = next;
1926       cmp_b = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1927     }
1928
1929
1930   if (tree_store->order == GTK_SORT_DESCENDING)
1931     {
1932       if (cmp_a < 0)
1933         cmp_a = 1;
1934       else if (cmp_a > 0)
1935         cmp_a = -1;
1936
1937       if (cmp_b < 0)
1938         cmp_b = 1;
1939       else if (cmp_b > 0)
1940         cmp_b = -1;
1941     }
1942
1943   if (prev == NULL && cmp_b <= 0)
1944     return;
1945   else if (next == NULL && cmp_a <= 0)
1946     return;
1947   else if (prev != NULL && next != NULL &&
1948            cmp_a <= 0 && cmp_b <= 0)
1949     return;
1950
1951   /* We actually need to sort it */
1952   /* First, remove the old link. */
1953
1954   if (prev)
1955     prev->next = next;
1956   else
1957     node->parent->children = next;
1958   if (next)
1959     next->prev = prev;
1960
1961   node->prev = NULL;
1962   node->next = NULL;
1963
1964   /* FIXME: as an optimization, we can potentially start at next */
1965   prev = NULL;
1966   node = node->parent->children;
1967   new_location = 0;
1968   tmp_iter.user_data = node;
1969   if (tree_store->order == GTK_SORT_DESCENDING)
1970     cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1971   else
1972     cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1973
1974   while ((node->next) && (cmp_a > 0))
1975     {
1976       prev = node;
1977       node = node->next;
1978       new_location++;
1979       tmp_iter.user_data = node;
1980       if (tree_store->order == GTK_SORT_DESCENDING)
1981         cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
1982       else
1983         cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
1984     }
1985
1986   if ((!node->next) && (cmp_a > 0))
1987     {
1988       node->next = G_NODE (iter->user_data);
1989       node->next->prev = node;
1990     }
1991   else if (prev)
1992     {
1993       prev->next = G_NODE (iter->user_data);
1994       prev->next->prev = prev;
1995       G_NODE (iter->user_data)->next = node;
1996       G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
1997     }
1998   else
1999     {
2000       G_NODE (iter->user_data)->next = G_NODE (iter->user_data)->parent->children;
2001       G_NODE (iter->user_data)->parent->children = G_NODE (iter->user_data);
2002     }
2003
2004   /* Emit the reordered signal. */
2005   length = g_node_n_children (node->parent);
2006   new_order = g_new (int, length);
2007   if (old_location < new_location)
2008     for (i = 0; i < length; i++)
2009       {
2010         if (i < old_location ||
2011             i > new_location)
2012           new_order[i] = i;
2013         else if (i >= old_location &&
2014                  i < new_location)
2015           new_order[i] = i + 1;
2016         else if (i == new_location)
2017           new_order[i] = old_location;
2018       }
2019   else
2020     for (i = 0; i < length; i++)
2021       {
2022         if (i < new_location ||
2023             i > old_location)
2024           new_order[i] = i;
2025         else if (i > new_location &&
2026                  i <= old_location)
2027           new_order[i] = i - 1;
2028         else if (i == new_location)
2029           new_order[i] = old_location;
2030       }
2031
2032   tmp_iter.user_data = node->parent;
2033   tmp_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &tmp_iter);
2034
2035   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
2036                                  tmp_path, &tmp_iter,
2037                                  new_order);
2038
2039   gtk_tree_path_free (tmp_path);
2040   g_free (new_order);
2041 }
2042
2043
2044 static gboolean
2045 gtk_tree_store_get_sort_column_id (GtkTreeSortable  *sortable,
2046                                    gint             *sort_column_id,
2047                                    GtkSortType      *order)
2048 {
2049   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2050
2051   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
2052
2053   if (tree_store->sort_column_id == -1)
2054     return FALSE;
2055
2056   if (sort_column_id)
2057     * sort_column_id = tree_store->sort_column_id;
2058   if (order)
2059     * order = tree_store->order;
2060   return TRUE;
2061
2062 }
2063
2064 static void
2065 gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
2066                                    gint              sort_column_id,
2067                                    GtkSortType       order)
2068 {
2069   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2070
2071   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2072
2073   
2074   if ((tree_store->sort_column_id == sort_column_id) &&
2075       (tree_store->order == order))
2076     return;
2077
2078   if (sort_column_id != -1)
2079     {
2080       GtkTreeDataSortHeader *header = NULL;
2081
2082       header = _gtk_tree_data_list_get_header (tree_store->sort_list, sort_column_id);
2083
2084       /* We want to make sure that we have a function */
2085       g_return_if_fail (header != NULL);
2086       g_return_if_fail (header->func != NULL);
2087     }
2088   else
2089     {
2090       g_return_if_fail (tree_store->default_sort_func != NULL);
2091     }
2092
2093   tree_store->sort_column_id = sort_column_id;
2094   tree_store->order = order;
2095
2096   gtk_tree_store_sort (tree_store);
2097
2098   gtk_tree_sortable_sort_column_changed (sortable);
2099 }
2100
2101 static void
2102 gtk_tree_store_set_sort_func (GtkTreeSortable        *sortable,
2103                               gint                    sort_column_id,
2104                               GtkTreeIterCompareFunc  func,
2105                               gpointer                data,
2106                               GtkDestroyNotify        destroy)
2107 {
2108   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2109   GtkTreeDataSortHeader *header = NULL;
2110   GList *list;
2111
2112   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2113   g_return_if_fail (func != NULL);
2114
2115   for (list = tree_store->sort_list; list; list = list->next)
2116     {
2117       header = (GtkTreeDataSortHeader*) list->data;
2118       if (header->sort_column_id == sort_column_id)
2119         break;
2120     }
2121
2122   if (header == NULL)
2123     {
2124       header = g_new0 (GtkTreeDataSortHeader, 1);
2125       header->sort_column_id = sort_column_id;
2126       tree_store->sort_list = g_list_append (tree_store->sort_list, header);
2127     }
2128
2129   if (header->destroy)
2130     (* header->destroy) (header->data);
2131
2132   header->func = func;
2133   header->data = data;
2134   header->destroy = destroy;
2135
2136 }
2137
2138 static void
2139 gtk_tree_store_set_default_sort_func (GtkTreeSortable        *sortable,
2140                                       GtkTreeIterCompareFunc  func,
2141                                       gpointer                data,
2142                                       GtkDestroyNotify        destroy)
2143 {
2144   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2145
2146   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2147
2148   if (tree_store->default_sort_destroy)
2149     (* tree_store->default_sort_destroy) (tree_store->default_sort_data);
2150
2151   tree_store->default_sort_func = func;
2152   tree_store->default_sort_data = data;
2153   tree_store->default_sort_destroy = destroy;
2154 }
2155
2156 static gboolean
2157 gtk_tree_store_has_default_sort_func (GtkTreeSortable *sortable)
2158 {
2159   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2160
2161   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
2162
2163   return (tree_store->default_sort_func != NULL);
2164 }
2165
2166 static void
2167 validate_gnode (GNode* node)
2168 {
2169   GNode *iter;
2170
2171   iter = node->children;
2172   while (iter != NULL)
2173     {
2174       g_assert (iter->parent == node);
2175       if (iter->prev)
2176         g_assert (iter->prev->next == iter);
2177       validate_gnode (iter);
2178       iter = iter->next;
2179     }
2180 }
2181
2182
2183