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