]> Pileus Git - ~andy/gtk/blob - gtk/gtktreestore.c
710ba3d6d75bfe1eb350364c86b7aebb098a5598
[~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 != -1)
29
30 static void         gtk_tree_store_init            (GtkTreeStore      *tree_store);
31 static void         gtk_tree_store_class_init      (GtkTreeStoreClass *tree_store_class);
32 static void         gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
33 static void         gtk_tree_store_drag_source_init(GtkTreeDragSourceIface *iface);
34 static void         gtk_tree_store_drag_dest_init  (GtkTreeDragDestIface   *iface);
35 static void         gtk_tree_store_sortable_init   (GtkTreeSortableIface   *iface);
36 static guint        gtk_tree_store_get_flags       (GtkTreeModel      *tree_model);
37 static gint         gtk_tree_store_get_n_columns   (GtkTreeModel      *tree_model);
38 static GType        gtk_tree_store_get_column_type (GtkTreeModel      *tree_model,
39                                                     gint               index);
40 static GtkTreePath *gtk_tree_store_get_path        (GtkTreeModel      *tree_model,
41                                                     GtkTreeIter       *iter);
42 static void         gtk_tree_store_get_value       (GtkTreeModel      *tree_model,
43                                                     GtkTreeIter       *iter,
44                                                     gint               column,
45                                                     GValue            *value);
46 static gboolean     gtk_tree_store_iter_next       (GtkTreeModel      *tree_model,
47                                                     GtkTreeIter       *iter);
48 static gboolean     gtk_tree_store_iter_children   (GtkTreeModel      *tree_model,
49                                                     GtkTreeIter       *iter,
50                                                     GtkTreeIter       *parent);
51 static gboolean     gtk_tree_store_iter_has_child  (GtkTreeModel      *tree_model,
52                                                     GtkTreeIter       *iter);
53 static gint         gtk_tree_store_iter_n_children (GtkTreeModel      *tree_model,
54                                                     GtkTreeIter       *iter);
55 static gboolean     gtk_tree_store_iter_nth_child  (GtkTreeModel      *tree_model,
56                                                     GtkTreeIter       *iter,
57                                                     GtkTreeIter       *parent,
58                                                     gint               n);
59 static gboolean     gtk_tree_store_iter_parent     (GtkTreeModel      *tree_model,
60                                                     GtkTreeIter       *iter,
61                                                     GtkTreeIter       *child);
62
63
64 /* DND interfaces */
65 static gboolean gtk_tree_store_drag_data_delete   (GtkTreeDragSource *drag_source,
66                                                    GtkTreePath       *path);
67 static gboolean gtk_tree_store_drag_data_get      (GtkTreeDragSource *drag_source,
68                                                    GtkTreePath       *path,
69                                                    GtkSelectionData  *selection_data);
70 static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
71                                                    GtkTreePath       *dest,
72                                                    GtkSelectionData  *selection_data);
73 static gboolean gtk_tree_store_row_drop_possible  (GtkTreeDragDest   *drag_dest,
74                                                    GtkTreeModel      *src_model,
75                                                    GtkTreePath       *src_path,
76                                                    GtkTreePath       *dest_path);
77
78 /* Sortable Interfaces */
79
80 static void     gtk_tree_store_sort                    (GtkTreeStore           *tree_store);
81 static void     gtk_tree_store_sort_iter_changed       (GtkTreeStore           *tree_store,
82                                                         GtkTreeIter            *iter,
83                                                         gint                    column);
84 static gboolean gtk_tree_store_get_sort_column_id      (GtkTreeSortable        *sortable,
85                                                         gint                   *sort_column_id,
86                                                         GtkTreeSortOrder       *order);
87 static void     gtk_tree_store_set_sort_column_id      (GtkTreeSortable        *sortable,
88                                                         gint                    sort_column_id,
89                                                         GtkTreeSortOrder        order);
90 static void     gtk_tree_store_sort_column_id_set_func (GtkTreeSortable        *sortable,
91                                                         gint                    sort_column_id,
92                                                         GtkTreeIterCompareFunc  func,
93                                                         gpointer                data,
94                                                         GtkDestroyNotify        destroy);
95
96
97 static void     validate_gnode                    (GNode *node);
98
99 static inline void
100 validate_tree (GtkTreeStore *tree_store)
101 {
102   if (gtk_debug_flags & GTK_DEBUG_TREE)
103     {
104       g_assert (G_NODE (tree_store->root)->parent == NULL);
105
106       validate_gnode (G_NODE (tree_store->root));
107     }
108 }
109
110 GtkType
111 gtk_tree_store_get_type (void)
112 {
113   static GType tree_store_type = 0;
114
115   if (!tree_store_type)
116     {
117       static const GTypeInfo tree_store_info =
118       {
119         sizeof (GtkTreeStoreClass),
120         NULL,           /* base_init */
121         NULL,           /* base_finalize */
122         (GClassInitFunc) gtk_tree_store_class_init,
123         NULL,           /* class_finalize */
124         NULL,           /* class_data */
125         sizeof (GtkTreeStore),
126         0,              /* n_preallocs */
127         (GInstanceInitFunc) gtk_tree_store_init
128       };
129
130       static const GInterfaceInfo tree_model_info =
131       {
132         (GInterfaceInitFunc) gtk_tree_store_tree_model_init,
133         NULL,
134         NULL
135       };
136
137       static const GInterfaceInfo drag_source_info =
138       {
139         (GInterfaceInitFunc) gtk_tree_store_drag_source_init,
140         NULL,
141         NULL
142       };
143
144       static const GInterfaceInfo drag_dest_info =
145       {
146         (GInterfaceInitFunc) gtk_tree_store_drag_dest_init,
147         NULL,
148         NULL
149       };
150
151       static const GInterfaceInfo sortable_info =
152       {
153         (GInterfaceInitFunc) gtk_tree_store_sortable_init,
154         NULL,
155         NULL
156       };
157
158       tree_store_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0);
159
160       g_type_add_interface_static (tree_store_type,
161                                    GTK_TYPE_TREE_MODEL,
162                                    &tree_model_info);
163       g_type_add_interface_static (tree_store_type,
164                                    GTK_TYPE_TREE_DRAG_SOURCE,
165                                    &drag_source_info);
166       g_type_add_interface_static (tree_store_type,
167                                    GTK_TYPE_TREE_DRAG_DEST,
168                                    &drag_dest_info);
169       g_type_add_interface_static (tree_store_type,
170                                    GTK_TYPE_TREE_SORTABLE,
171                                    &sortable_info);
172
173     }
174
175   return tree_store_type;
176 }
177
178 static void
179 gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class)
180 {
181   GObjectClass *object_class;
182
183   object_class = (GObjectClass *) tree_store_class;
184
185 }
186
187 static void
188 gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
189 {
190   iface->get_flags = gtk_tree_store_get_flags;
191   iface->get_n_columns = gtk_tree_store_get_n_columns;
192   iface->get_column_type = gtk_tree_store_get_column_type;
193   iface->get_path = gtk_tree_store_get_path;
194   iface->get_value = gtk_tree_store_get_value;
195   iface->iter_next = gtk_tree_store_iter_next;
196   iface->iter_children = gtk_tree_store_iter_children;
197   iface->iter_has_child = gtk_tree_store_iter_has_child;
198   iface->iter_n_children = gtk_tree_store_iter_n_children;
199   iface->iter_nth_child = gtk_tree_store_iter_nth_child;
200   iface->iter_parent = gtk_tree_store_iter_parent;
201 }
202
203 static void
204 gtk_tree_store_drag_source_init (GtkTreeDragSourceIface *iface)
205 {
206   iface->drag_data_delete = gtk_tree_store_drag_data_delete;
207   iface->drag_data_get = gtk_tree_store_drag_data_get;
208 }
209
210 static void
211 gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface)
212 {
213   iface->drag_data_received = gtk_tree_store_drag_data_received;
214   iface->row_drop_possible = gtk_tree_store_row_drop_possible;
215 }
216
217 static void
218 gtk_tree_store_sortable_init (GtkTreeSortableIface *iface)
219 {
220   iface->get_sort_column_id = gtk_tree_store_get_sort_column_id;
221   iface->set_sort_column_id = gtk_tree_store_set_sort_column_id;
222   iface->sort_column_id_set_func = gtk_tree_store_sort_column_id_set_func;
223 }
224
225 static void
226 gtk_tree_store_init (GtkTreeStore *tree_store)
227 {
228   tree_store->root = g_node_new (NULL);
229   tree_store->stamp = g_random_int ();
230   tree_store->sort_list = NULL;
231 }
232
233 GtkTreeStore *
234 gtk_tree_store_new (void)
235 {
236   return GTK_TREE_STORE (g_object_new (gtk_tree_store_get_type (), NULL));
237 }
238
239 GtkTreeStore *
240 gtk_tree_store_new_with_types (gint n_columns,
241                                ...)
242 {
243   GtkTreeStore *retval;
244   va_list args;
245   gint i;
246
247   g_return_val_if_fail (n_columns > 0, NULL);
248
249   retval = gtk_tree_store_new ();
250   gtk_tree_store_set_n_columns (retval, n_columns);
251
252   va_start (args, n_columns);
253
254   for (i = 0; i < n_columns; i++)
255     {
256       GType type = va_arg (args, GType);
257       if (! _gtk_tree_data_list_check_type (type))
258         {
259           g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (type));
260           g_object_unref (G_OBJECT (retval));
261           return NULL;
262         }
263       gtk_tree_store_set_column_type (retval, i, type);
264     }
265   va_end (args);
266
267   return retval;
268 }
269
270 /**
271  * gtk_tree_store_set_n_columns:
272  * @tree_store: 
273  * @n_columns: 
274  * 
275  * As a side effect of calling this function, all sort columns that overlap with
276  * the current number of columns will be removed.
277  **/
278 void
279 gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
280                               gint          n_columns)
281 {
282   GType *new_columns;
283
284   g_return_if_fail (tree_store != NULL);
285   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
286
287   if (tree_store->n_columns == n_columns)
288     return;
289
290   new_columns = g_new0 (GType, n_columns);
291   if (tree_store->column_headers)
292     {
293       /* copy the old header orders over */
294       if (n_columns >= tree_store->n_columns)
295         memcpy (new_columns, tree_store->column_headers, tree_store->n_columns * sizeof (gchar *));
296       else
297         memcpy (new_columns, tree_store->column_headers, n_columns * sizeof (GType));
298
299       g_free (tree_store->column_headers);
300     }
301
302   if (tree_store->sort_list)
303     _gtk_tree_data_list_header_free (tree_store->sort_list);
304
305   tree_store->sort_list = _gtk_tree_data_list_header_new (n_columns, tree_store->column_headers);
306
307   tree_store->column_headers = new_columns;
308   tree_store->n_columns = n_columns;
309 }
310
311 /**
312  * gtk_tree_store_set_column_type:
313  * @tree_store: a #GtkTreeStore
314  * @column: column number
315  * @type: type of the data to be stored in @column
316  *
317  * Supported types include: %G_TYPE_UINT, %G_TYPE_INT, %G_TYPE_UCHAR,
318  * %G_TYPE_CHAR, %G_TYPE_BOOLEAN, %G_TYPE_POINTER, %G_TYPE_FLOAT,
319  * %G_TYPE_DOUBLE, %G_TYPE_STRING, %G_TYPE_OBJECT, and %G_TYPE_BOXED, along with
320  * subclasses of those types such as %GDK_TYPE_PIXBUF.
321  *
322  **/
323 void
324 gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
325                                 gint          column,
326                                 GType         type)
327 {
328   g_return_if_fail (tree_store != NULL);
329   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
330   g_return_if_fail (column >=0 && column < tree_store->n_columns);
331   if (!_gtk_tree_data_list_check_type (type))
332     {
333       g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (type));
334       return;
335     }
336   tree_store->column_headers[column] = type;
337 }
338
339 /* fulfill the GtkTreeModel requirements */
340 /* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node.  However,
341  * it is not visible to the tree or to the user., and the path "0" refers to the
342  * first child of GtkTreeStore::root.
343  */
344
345
346 static guint
347 gtk_tree_store_get_flags (GtkTreeModel *tree_model)
348 {
349   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
350
351   return GTK_TREE_MODEL_ITERS_PERSIST;
352 }
353
354 static gint
355 gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
356 {
357   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
358
359   return GTK_TREE_STORE (tree_model)->n_columns;
360 }
361
362 static GType
363 gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
364                                 gint          index)
365 {
366   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), G_TYPE_INVALID);
367   g_return_val_if_fail (index < GTK_TREE_STORE (tree_model)->n_columns &&
368                         index >= 0, G_TYPE_INVALID);
369
370   return GTK_TREE_STORE (tree_model)->column_headers[index];
371 }
372
373 static GtkTreePath *
374 gtk_tree_store_get_path (GtkTreeModel *tree_model,
375                          GtkTreeIter  *iter)
376 {
377   GtkTreePath *retval;
378   GNode *tmp_node;
379   gint i = 0;
380
381   g_return_val_if_fail (tree_model != NULL, NULL);
382   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
383   g_return_val_if_fail (iter != NULL, NULL);
384   g_return_val_if_fail (iter->user_data != NULL, NULL);
385
386   validate_tree ((GtkTreeStore*)tree_model);
387
388   g_assert (G_NODE (iter->user_data)->parent != NULL);
389
390   if (G_NODE (iter->user_data)->parent == G_NODE (GTK_TREE_STORE (tree_model)->root))
391     {
392       retval = gtk_tree_path_new ();
393       tmp_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
394     }
395   else
396     {
397       GtkTreeIter tmp_iter = *iter;
398
399       tmp_iter.user_data = G_NODE (iter->user_data)->parent;
400
401       retval = gtk_tree_store_get_path (tree_model,
402                                         &tmp_iter);
403       tmp_node = G_NODE (iter->user_data)->parent->children;
404     }
405
406   if (retval == NULL)
407     return NULL;
408
409   if (tmp_node == NULL)
410     {
411       gtk_tree_path_free (retval);
412       return NULL;
413     }
414
415   for (; tmp_node; tmp_node = tmp_node->next)
416     {
417       if (tmp_node == G_NODE (iter->user_data))
418         break;
419       i++;
420     }
421
422   if (tmp_node == NULL)
423     {
424       /* We couldn't find node, meaning it's prolly not ours */
425       /* Perhaps I should do a g_return_if_fail here. */
426       gtk_tree_path_free (retval);
427       return NULL;
428     }
429
430   gtk_tree_path_append_index (retval, i);
431
432   return retval;
433 }
434
435
436 static void
437 gtk_tree_store_get_value (GtkTreeModel *tree_model,
438                           GtkTreeIter  *iter,
439                           gint          column,
440                           GValue       *value)
441 {
442   GtkTreeDataList *list;
443   gint tmp_column = column;
444
445   g_return_if_fail (tree_model != NULL);
446   g_return_if_fail (GTK_IS_TREE_STORE (tree_model));
447   g_return_if_fail (iter != NULL);
448   g_return_if_fail (column < GTK_TREE_STORE (tree_model)->n_columns);
449
450   list = G_NODE (iter->user_data)->data;
451
452   while (tmp_column-- > 0 && list)
453     list = list->next;
454
455   if (list)
456     {
457       _gtk_tree_data_list_node_to_value (list,
458                                          GTK_TREE_STORE (tree_model)->column_headers[column],
459                                          value);
460     }
461   else
462     {
463       /* We want to return an initialized but empty (default) value */
464       g_value_init (value, GTK_TREE_STORE (tree_model)->column_headers[column]);
465     }
466 }
467
468 static gboolean
469 gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
470                           GtkTreeIter   *iter)
471 {
472   g_return_val_if_fail (iter->user_data != NULL, FALSE);
473
474   if (G_NODE (iter->user_data)->next)
475     {
476       iter->user_data = G_NODE (iter->user_data)->next;
477       return TRUE;
478     }
479   else
480     return FALSE;
481 }
482
483 static gboolean
484 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
485                               GtkTreeIter  *iter,
486                               GtkTreeIter  *parent)
487 {
488   GNode *children;
489
490   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
491
492   if (parent)
493     children = G_NODE (parent->user_data)->children;
494   else
495     children = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
496
497   if (children)
498     {
499       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
500       iter->user_data = children;
501       return TRUE;
502     }
503   else
504     return FALSE;
505 }
506
507 static gboolean
508 gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
509                                GtkTreeIter  *iter)
510 {
511   g_return_val_if_fail (tree_model != NULL, FALSE);
512   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
513   g_return_val_if_fail (iter != NULL, FALSE);
514   g_return_val_if_fail (iter->user_data != NULL, FALSE);
515
516   return G_NODE (iter->user_data)->children != NULL;
517 }
518
519 static gint
520 gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
521                                 GtkTreeIter  *iter)
522 {
523   GNode *node;
524   gint i = 0;
525
526   g_return_val_if_fail (tree_model != NULL, 0);
527   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
528   g_return_val_if_fail (iter != NULL, FALSE);
529   g_return_val_if_fail (iter->user_data != NULL, FALSE);
530
531   if (iter == NULL)
532     node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
533   else
534     node = G_NODE (iter->user_data)->children;
535
536   while (node)
537     {
538       i++;
539       node = node->next;
540     }
541
542   return i;
543 }
544
545 static gboolean
546 gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
547                                GtkTreeIter  *iter,
548                                GtkTreeIter  *parent,
549                                gint          n)
550 {
551   GNode *parent_node;
552   GNode *child;
553
554   g_return_val_if_fail (tree_model != NULL, FALSE);
555   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
556   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
557
558   if (parent == NULL)
559     parent_node = GTK_TREE_STORE (tree_model)->root;
560   else
561     parent_node = parent->user_data;
562
563   child = g_node_nth_child (parent_node, n);
564
565   if (child)
566     {
567       iter->user_data = child;
568       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
569       return TRUE;
570     }
571   else
572     return FALSE;
573 }
574
575 static gboolean
576 gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
577                             GtkTreeIter  *iter,
578                             GtkTreeIter  *child)
579 {
580   GNode *parent;
581
582   g_return_val_if_fail (iter != NULL, FALSE);
583   g_return_val_if_fail (iter->user_data != NULL, FALSE);
584
585   parent = G_NODE (child->user_data)->parent;
586
587   g_assert (parent != NULL);
588
589   if (parent != GTK_TREE_STORE (tree_model)->root)
590     {
591       iter->user_data = parent;
592       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
593       return TRUE;
594     }
595   else
596     return FALSE;
597 }
598
599 /*
600  * This is a somewhat inelegant function that does a lot of list
601  * manipulations on it's own.
602  */
603 void
604 gtk_tree_store_set_value (GtkTreeStore *tree_store,
605                           GtkTreeIter  *iter,
606                           gint          column,
607                           GValue       *value)
608 {
609   GtkTreeDataList *list;
610   GtkTreeDataList *prev;
611   GtkTreePath *path = NULL;
612   GValue real_value = {0, };
613   gboolean converted = FALSE;
614
615   g_return_if_fail (tree_store != NULL);
616   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
617   g_return_if_fail (column >= 0 && column < tree_store->n_columns);
618   g_return_if_fail (G_IS_VALUE (value));
619
620   if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column]))
621     {
622       if (! (g_value_type_compatible (G_VALUE_TYPE (value), tree_store->column_headers[column]) &&
623              g_value_type_compatible (tree_store->column_headers[column], G_VALUE_TYPE (value))))
624         {
625           g_warning ("%s: Unable to convert from %s to %s\n",
626                      G_STRLOC,
627                      g_type_name (G_VALUE_TYPE (value)),
628                      g_type_name (tree_store->column_headers[column]));
629           return;
630         }
631       if (!g_value_transform (value, &real_value))
632         {
633           g_warning ("%s: Unable to make conversion from %s to %s\n",
634                      G_STRLOC,
635                      g_type_name (G_VALUE_TYPE (value)),
636                      g_type_name (tree_store->column_headers[column]));
637           g_value_unset (&real_value);
638           return;
639         }
640       converted = TRUE;
641     }
642
643   prev = list = G_NODE (iter->user_data)->data;
644
645   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
646
647   while (list != NULL)
648     {
649       if (column == 0)
650         {
651           if (converted)
652             _gtk_tree_data_list_value_to_node (list, &real_value);
653           else
654             _gtk_tree_data_list_value_to_node (list, value);
655           gtk_tree_model_range_changed (GTK_TREE_MODEL (tree_store), path, iter, path, iter);
656           gtk_tree_path_free (path);
657           if (converted)
658             g_value_unset (&real_value);
659           return;
660         }
661
662       column--;
663       prev = list;
664       list = list->next;
665     }
666
667   if (G_NODE (iter->user_data)->data == NULL)
668     {
669       G_NODE (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
670       list->next = NULL;
671     }
672   else
673     {
674       list = prev->next = _gtk_tree_data_list_alloc ();
675       list->next = NULL;
676     }
677
678   while (column != 0)
679     {
680       list->next = _gtk_tree_data_list_alloc ();
681       list = list->next;
682       list->next = NULL;
683       column --;
684     }
685   if (converted)
686     _gtk_tree_data_list_value_to_node (list, &real_value);
687   else
688     _gtk_tree_data_list_value_to_node (list, value);
689   gtk_tree_model_range_changed (GTK_TREE_MODEL (tree_store), path, iter, path, iter);
690   gtk_tree_path_free (path);
691   if (converted)
692     g_value_unset (&real_value);
693
694   if (GTK_TREE_STORE_IS_SORTED (tree_store))
695     gtk_tree_store_sort_iter_changed (tree_store, iter, column);
696 }
697
698 /**
699  * gtk_tree_store_set_valist:
700  * @tree_store: a #GtkTreeStore
701  * @iter: row to set data for
702  * @var_args: va_list of column/value pairs
703  *
704  * See gtk_tree_store_set(); this version takes a va_list for
705  * use by language bindings.
706  *
707  **/
708 void
709 gtk_tree_store_set_valist (GtkTreeStore *tree_store,
710                            GtkTreeIter  *iter,
711                            va_list      var_args)
712 {
713   gint column;
714
715   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
716
717   column = va_arg (var_args, gint);
718
719   while (column != -1)
720     {
721       GValue value = { 0, };
722       gchar *error = NULL;
723
724       if (column >= tree_store->n_columns)
725         {
726           g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
727           break;
728         }
729       g_value_init (&value, tree_store->column_headers[column]);
730
731       G_VALUE_COLLECT (&value, var_args, 0, &error);
732       if (error)
733         {
734           g_warning ("%s: %s", G_STRLOC, error);
735           g_free (error);
736
737           /* we purposely leak the value here, it might not be
738            * in a sane state if an error condition occoured
739            */
740           break;
741         }
742
743       gtk_tree_store_set_value (tree_store,
744                                 iter,
745                                 column,
746                                 &value);
747
748       g_value_unset (&value);
749
750       column = va_arg (var_args, gint);
751     }
752 }
753
754 /**
755  * gtk_tree_store_set:
756  * @tree_store: a #GtkTreeStore
757  * @iter: row iterator
758  * @Varargs: pairs of column number and value, terminated with -1
759  *
760  * Sets the value of one or more cells in the row referenced by @iter.
761  * The variable argument list should contain integer column numbers,
762  * each column number followed by the value to be set. For example,
763  * The list is terminated by a -1. For example, to set column 0 with type
764  * %G_TYPE_STRING to "Foo", you would write gtk_tree_store_set (store, iter,
765  * 0, "Foo", -1).
766  **/
767 void
768 gtk_tree_store_set (GtkTreeStore *tree_store,
769                     GtkTreeIter  *iter,
770                     ...)
771 {
772   va_list var_args;
773
774   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
775
776   va_start (var_args, iter);
777   gtk_tree_store_set_valist (tree_store, iter, var_args);
778   va_end (var_args);
779 }
780
781 void
782 gtk_tree_store_remove (GtkTreeStore *model,
783                        GtkTreeIter  *iter)
784 {
785   GtkTreePath *path;
786   GtkTreeIter new_iter = {0,};
787   GNode *parent;
788
789   g_return_if_fail (model != NULL);
790   g_return_if_fail (GTK_IS_TREE_STORE (model));
791
792   parent = G_NODE (iter->user_data)->parent;
793
794   g_assert (parent != NULL);
795
796   if (G_NODE (iter->user_data)->data)
797     _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
798                               model->column_headers);
799
800   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
801   g_node_destroy (G_NODE (iter->user_data));
802
803   model->stamp++;
804   gtk_tree_model_deleted (GTK_TREE_MODEL (model), path);
805
806   if (parent != G_NODE (model->root) && parent->children == NULL)
807     {
808       gtk_tree_path_up (path);
809
810       new_iter.stamp = model->stamp;
811       new_iter.user_data = parent;
812       gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, &new_iter);
813     }
814   gtk_tree_path_free (path);
815 }
816
817 void
818 gtk_tree_store_insert (GtkTreeStore *model,
819                        GtkTreeIter  *iter,
820                        GtkTreeIter  *parent,
821                        gint          position)
822 {
823   GtkTreePath *path;
824   GNode *parent_node;
825
826   g_return_if_fail (model != NULL);
827   g_return_if_fail (GTK_IS_TREE_STORE (model));
828
829   if (parent)
830     parent_node = parent->user_data;
831   else
832     parent_node = model->root;
833
834   iter->stamp = model->stamp;
835   iter->user_data = g_node_new (NULL);
836   g_node_insert (parent_node, position, G_NODE (iter->user_data));
837
838   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
839   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
840
841   gtk_tree_path_free (path);
842
843   validate_tree ((GtkTreeStore*)model);
844 }
845
846 void
847 gtk_tree_store_insert_before (GtkTreeStore *model,
848                               GtkTreeIter  *iter,
849                               GtkTreeIter  *parent,
850                               GtkTreeIter  *sibling)
851 {
852   GtkTreePath *path;
853   GNode *parent_node = NULL;
854   GNode *new_node;
855
856   g_return_if_fail (model != NULL);
857   g_return_if_fail (GTK_IS_TREE_STORE (model));
858   g_return_if_fail (iter != NULL);
859
860   new_node = g_node_new (NULL);
861
862   if (parent == NULL && sibling == NULL)
863     parent_node = model->root;
864   else if (parent == NULL)
865     parent_node = G_NODE (sibling->user_data)->parent;
866   else if (sibling == NULL)
867     parent_node = G_NODE (parent->user_data);
868   else
869     {
870       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
871                         G_NODE (parent->user_data));
872       parent_node = G_NODE (parent->user_data);
873     }
874
875   g_node_insert_before (parent_node,
876                         sibling ? G_NODE (sibling->user_data) : NULL,
877                         new_node);
878
879   iter->stamp = model->stamp;
880   iter->user_data = new_node;
881
882   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
883   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
884
885   gtk_tree_path_free (path);
886
887   validate_tree ((GtkTreeStore*)model);
888 }
889
890 void
891 gtk_tree_store_insert_after (GtkTreeStore *model,
892                              GtkTreeIter  *iter,
893                              GtkTreeIter  *parent,
894                              GtkTreeIter  *sibling)
895 {
896   GtkTreePath *path;
897   GNode *parent_node;
898   GNode *new_node;
899
900   g_return_if_fail (model != NULL);
901   g_return_if_fail (GTK_IS_TREE_STORE (model));
902   g_return_if_fail (iter != NULL);
903
904   new_node = g_node_new (NULL);
905
906   if (parent == NULL && sibling == NULL)
907     parent_node = model->root;
908   else if (parent == NULL)
909     parent_node = G_NODE (sibling->user_data)->parent;
910   else if (sibling == NULL)
911     parent_node = G_NODE (parent->user_data);
912   else
913     {
914       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
915                         G_NODE (parent->user_data));
916       parent_node = G_NODE (parent->user_data);
917     }
918
919
920   g_node_insert_after (parent_node,
921                        sibling ? G_NODE (sibling->user_data) : NULL,
922                        new_node);
923
924   iter->stamp = model->stamp;
925   iter->user_data = new_node;
926
927   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
928   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
929
930   gtk_tree_path_free (path);
931
932   validate_tree ((GtkTreeStore*)model);
933 }
934
935 void
936 gtk_tree_store_prepend (GtkTreeStore *model,
937                         GtkTreeIter  *iter,
938                         GtkTreeIter  *parent)
939 {
940   GNode *parent_node;
941
942   g_return_if_fail (model != NULL);
943   g_return_if_fail (GTK_IS_TREE_STORE (model));
944   g_return_if_fail (iter != NULL);
945
946   if (parent == NULL)
947     parent_node = model->root;
948   else
949     parent_node = parent->user_data;
950
951   if (parent_node->children == NULL)
952     {
953       GtkTreePath *path;
954
955       iter->stamp = model->stamp;
956       iter->user_data = g_node_new (NULL);
957
958       g_node_prepend (parent_node, iter->user_data);
959
960       if (parent_node != model->root)
961         {
962           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
963           gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, parent);
964           gtk_tree_path_append_index (path, 0);
965         }
966       else
967         {
968           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
969         }
970       gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
971       gtk_tree_path_free (path);
972     }
973   else
974     {
975       gtk_tree_store_insert_after (model, iter, parent, NULL);
976     }
977
978   validate_tree ((GtkTreeStore*)model);
979 }
980
981 void
982 gtk_tree_store_append (GtkTreeStore *model,
983                        GtkTreeIter  *iter,
984                        GtkTreeIter  *parent)
985 {
986   GNode *parent_node;
987
988   g_return_if_fail (model != NULL);
989   g_return_if_fail (GTK_IS_TREE_STORE (model));
990   g_return_if_fail (iter != NULL);
991
992   if (parent == NULL)
993     parent_node = model->root;
994   else
995     parent_node = parent->user_data;
996
997   if (parent_node->children == NULL)
998     {
999       GtkTreePath *path;
1000
1001       iter->stamp = model->stamp;
1002       iter->user_data = g_node_new (NULL);
1003
1004       g_node_append (parent_node, G_NODE (iter->user_data));
1005
1006       if (parent_node != model->root)
1007         {
1008           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
1009           gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, parent);
1010           gtk_tree_path_append_index (path, 0);
1011         }
1012       else
1013         {
1014           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
1015         }
1016
1017       gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
1018       gtk_tree_path_free (path);
1019     }
1020   else
1021     {
1022       gtk_tree_store_insert_before (model, iter, parent, NULL);
1023     }
1024
1025   validate_tree ((GtkTreeStore*)model);
1026 }
1027
1028 gboolean
1029 gtk_tree_store_is_ancestor (GtkTreeStore *model,
1030                             GtkTreeIter  *iter,
1031                             GtkTreeIter  *descendant)
1032 {
1033   g_return_val_if_fail (model != NULL, FALSE);
1034   g_return_val_if_fail (GTK_IS_TREE_STORE (model), FALSE);
1035   g_return_val_if_fail (iter != NULL, FALSE);
1036   g_return_val_if_fail (descendant != NULL, FALSE);
1037
1038   return g_node_is_ancestor (G_NODE (iter->user_data),
1039                              G_NODE (descendant->user_data));
1040 }
1041
1042
1043 gint
1044 gtk_tree_store_iter_depth (GtkTreeStore *model,
1045                            GtkTreeIter  *iter)
1046 {
1047   g_return_val_if_fail (model != NULL, 0);
1048   g_return_val_if_fail (GTK_IS_TREE_STORE (model), 0);
1049   g_return_val_if_fail (iter != NULL, 0);
1050
1051   return g_node_depth (G_NODE (iter->user_data)) - 1;
1052 }
1053
1054 /* DND */
1055
1056
1057
1058 static gboolean
1059 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1060                                  GtkTreePath       *path)
1061 {
1062   GtkTreeIter iter;
1063
1064   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1065
1066   if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
1067                                &iter,
1068                                path))
1069     {
1070       gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1071                              &iter);
1072       return TRUE;
1073     }
1074   else
1075     {
1076       return FALSE;
1077     }
1078 }
1079
1080 static gboolean
1081 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1082                               GtkTreePath       *path,
1083                               GtkSelectionData  *selection_data)
1084 {
1085   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1086
1087   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1088    * target, because the default handler does it for us, but
1089    * we do anyway for the convenience of someone maybe overriding the
1090    * default handler.
1091    */
1092
1093   if (gtk_selection_data_set_tree_row (selection_data,
1094                                        GTK_TREE_MODEL (drag_source),
1095                                        path))
1096     {
1097       return TRUE;
1098     }
1099   else
1100     {
1101       /* FIXME handle text targets at least. */
1102     }
1103
1104   return FALSE;
1105 }
1106
1107 static void
1108 copy_node_data (GtkTreeStore *tree_store,
1109                 GtkTreeIter  *src_iter,
1110                 GtkTreeIter  *dest_iter)
1111 {
1112   GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1113   GtkTreeDataList *copy_head = NULL;
1114   GtkTreeDataList *copy_prev = NULL;
1115   GtkTreeDataList *copy_iter = NULL;
1116   GtkTreePath *path;
1117   gint col;
1118
1119   col = 0;
1120   while (dl)
1121     {
1122       copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1123
1124       if (copy_head == NULL)
1125         copy_head = copy_iter;
1126
1127       if (copy_prev)
1128         copy_prev->next = copy_iter;
1129
1130       copy_prev = copy_iter;
1131
1132       dl = dl->next;
1133       ++col;
1134     }
1135
1136   G_NODE (dest_iter->user_data)->data = copy_head;
1137
1138   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1139   gtk_tree_model_range_changed (GTK_TREE_MODEL (tree_store), path, dest_iter, path, dest_iter);
1140   gtk_tree_path_free (path);
1141 }
1142
1143 static void
1144 recursive_node_copy (GtkTreeStore *tree_store,
1145                      GtkTreeIter  *src_iter,
1146                      GtkTreeIter  *dest_iter)
1147 {
1148   GtkTreeIter child;
1149   GtkTreeModel *model;
1150
1151   model = GTK_TREE_MODEL (tree_store);
1152
1153   copy_node_data (tree_store, src_iter, dest_iter);
1154
1155   if (gtk_tree_model_iter_children (model,
1156                                     &child,
1157                                     src_iter))
1158     {
1159       /* Need to create children and recurse. Note our
1160        * dependence on persistent iterators here.
1161        */
1162       do
1163         {
1164           GtkTreeIter copy;
1165
1166           /* Gee, a really slow algorithm... ;-) FIXME */
1167           gtk_tree_store_append (tree_store,
1168                                  &copy,
1169                                  dest_iter);
1170
1171           recursive_node_copy (tree_store, &child, &copy);
1172         }
1173       while (gtk_tree_model_iter_next (model, &child));
1174     }
1175 }
1176
1177 static gboolean
1178 gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
1179                                    GtkTreePath       *dest,
1180                                    GtkSelectionData  *selection_data)
1181 {
1182   GtkTreeModel *tree_model;
1183   GtkTreeStore *tree_store;
1184   GtkTreeModel *src_model = NULL;
1185   GtkTreePath *src_path = NULL;
1186   gboolean retval = FALSE;
1187
1188   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
1189
1190   tree_model = GTK_TREE_MODEL (drag_dest);
1191   tree_store = GTK_TREE_STORE (drag_dest);
1192
1193   validate_tree (tree_store);
1194
1195   if (gtk_selection_data_get_tree_row (selection_data,
1196                                        &src_model,
1197                                        &src_path) &&
1198       src_model == tree_model)
1199     {
1200       /* Copy the given row to a new position */
1201       GtkTreeIter src_iter;
1202       GtkTreeIter dest_iter;
1203       GtkTreePath *prev;
1204
1205       if (!gtk_tree_model_get_iter (src_model,
1206                                     &src_iter,
1207                                     src_path))
1208         {
1209           goto out;
1210         }
1211
1212       /* Get the path to insert _after_ (dest is the path to insert _before_) */
1213       prev = gtk_tree_path_copy (dest);
1214
1215       if (!gtk_tree_path_prev (prev))
1216         {
1217           GtkTreeIter dest_parent;
1218           GtkTreePath *parent;
1219           GtkTreeIter *dest_parent_p;
1220
1221           /* dest was the first spot at the current depth; which means
1222            * we are supposed to prepend.
1223            */
1224
1225           /* Get the parent, NULL if parent is the root */
1226           dest_parent_p = NULL;
1227           parent = gtk_tree_path_copy (dest);
1228           if (gtk_tree_path_up (parent))
1229             {
1230               gtk_tree_model_get_iter (tree_model,
1231                                        &dest_parent,
1232                                        parent);
1233               dest_parent_p = &dest_parent;
1234             }
1235           gtk_tree_path_free (parent);
1236           parent = NULL;
1237
1238           gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
1239                                   &dest_iter,
1240                                   dest_parent_p);
1241
1242           retval = TRUE;
1243         }
1244       else
1245         {
1246           if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
1247                                        &dest_iter,
1248                                        prev))
1249             {
1250               GtkTreeIter tmp_iter = dest_iter;
1251               gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
1252                                            &dest_iter,
1253                                            NULL,
1254                                            &tmp_iter);
1255               retval = TRUE;
1256
1257             }
1258         }
1259
1260       gtk_tree_path_free (prev);
1261
1262       /* If we succeeded in creating dest_iter, walk src_iter tree branch,
1263        * duplicating it below dest_iter.
1264        */
1265
1266       if (retval)
1267         {
1268           recursive_node_copy (tree_store,
1269                                &src_iter,
1270                                &dest_iter);
1271         }
1272     }
1273   else
1274     {
1275       /* FIXME maybe add some data targets eventually, or handle text
1276        * targets in the simple case.
1277        */
1278
1279     }
1280
1281  out:
1282
1283   if (src_path)
1284     gtk_tree_path_free (src_path);
1285
1286   return retval;
1287 }
1288
1289 static gboolean
1290 gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
1291                                   GtkTreeModel    *src_model,
1292                                   GtkTreePath     *src_path,
1293                                   GtkTreePath     *dest_path)
1294 {
1295   /* can only drag to ourselves */
1296   if (src_model != GTK_TREE_MODEL (drag_dest))
1297     return FALSE;
1298
1299   /* Can't drop into ourself. */
1300   if (gtk_tree_path_is_ancestor (src_path,
1301                                  dest_path))
1302     return FALSE;
1303
1304   /* Can't drop if dest_path's parent doesn't exist */
1305   {
1306     GtkTreeIter iter;
1307     GtkTreePath *tmp = gtk_tree_path_copy (dest_path);
1308
1309     /* if we can't go up, we know the parent exists, the root
1310      * always exists.
1311      */
1312     if (gtk_tree_path_up (tmp))
1313       {
1314         if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
1315                                       &iter, tmp))
1316           {
1317             if (tmp)
1318               gtk_tree_path_free (tmp);
1319             return FALSE;
1320           }
1321       }
1322
1323     if (tmp)
1324       gtk_tree_path_free (tmp);
1325   }
1326
1327   /* Can otherwise drop anywhere. */
1328   return TRUE;
1329 }
1330
1331
1332 static void
1333 gtk_tree_store_sort (GtkTreeStore *tree_store)
1334 {
1335
1336 }
1337
1338 static void
1339 gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
1340                                   GtkTreeIter  *iter,
1341                                   gint          column)
1342 {
1343   GtkTreeDataSortHeader *header;
1344   GNode *prev = NULL;
1345   GNode *next = NULL;
1346   GNode *node;
1347   GtkTreePath *tmp_path;
1348   GtkTreeIter tmp_iter;
1349   gint cmp_a = 0;
1350   gint cmp_b = 0;
1351   gint i;
1352   gint old_location;
1353   gint new_location;
1354   gint *new_order;
1355   gint length;
1356
1357   /* FIX*/
1358   if (G_NODE (iter->user_data)->parent)
1359     node = G_NODE (iter->user_data)->parent->children;
1360   else
1361     node = G_NODE (tree_store->root);
1362
1363   tmp_iter.stamp = tree_store->stamp;
1364   header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1365                                            tree_store->sort_column_id);
1366   g_return_if_fail (header != NULL);
1367   g_return_if_fail (header->func != NULL);
1368
1369   /* If it's the built in function, we don't sort. */
1370   if (header->func == gtk_tree_data_list_compare_func &&
1371       tree_store->sort_column_id != column)
1372     return;
1373
1374   old_location = 0;
1375   /* First we find the iter, its prev, and its next */
1376   while (node)
1377     {
1378       if (node == G_NODE (iter->user_data))
1379         break;
1380       prev = node;
1381       node = node->next;
1382       old_location++;
1383     }
1384   g_assert (node != NULL);
1385
1386   next = node->next;
1387
1388   /* Check the common case, where we don't need to sort it moved. */
1389   if (prev != NULL)
1390     {
1391       tmp_iter.user_data = prev;
1392       cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1393                                 &tmp_iter, iter,
1394                                 header->data);
1395     }
1396
1397   if (next != NULL)
1398     {
1399       tmp_iter.user_data = next;
1400       cmp_b = (* header->func) (GTK_TREE_MODEL (tree_store),
1401                                 iter, &tmp_iter,
1402                                 header->data);
1403     }
1404
1405
1406   if (tree_store->order == GTK_TREE_SORT_DESCENDING)
1407     {
1408       if (cmp_a < 0)
1409         cmp_a = 1;
1410       else if (cmp_a > 0)
1411         cmp_a = -1;
1412
1413       if (cmp_b < 0)
1414         cmp_b = 1;
1415       else if (cmp_b > 0)
1416         cmp_b = -1;
1417     }
1418
1419   if (prev == NULL && cmp_b <= 0)
1420     return;
1421   else if (next == NULL && cmp_a <= 0)
1422     return;
1423   else if (prev != NULL && next != NULL &&
1424            cmp_a <= 0 && cmp_b <= 0)
1425     return;
1426
1427   /* We actually need to sort it */
1428   /* First, remove the old link. */
1429
1430   if (prev == NULL)
1431     tree_store->root = next;
1432   else
1433     prev->next = next;
1434   node->next = NULL;
1435   
1436   /* FIXME: as an optimization, we can potentially start at next */
1437   prev = NULL;
1438   node = G_NODE (tree_store->root);
1439   new_location = 0;
1440   tmp_iter.user_data = node;
1441   if (tree_store->order == GTK_TREE_SORT_DESCENDING)
1442     cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1443                               &tmp_iter, iter, header->data);
1444   else
1445     cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1446                               iter, &tmp_iter, header->data);
1447
1448   while ((node->next) && (cmp_a > 0))
1449     {
1450       prev = node;
1451       node = node->next;
1452       new_location++;
1453       tmp_iter.user_data = node;
1454       if (tree_store->order == GTK_TREE_SORT_DESCENDING)
1455         cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1456                                   &tmp_iter, iter, header->data);
1457       else
1458         cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1459                                   iter, &tmp_iter, header->data);
1460     }
1461
1462   if ((!node->next) && (cmp_a > 0))
1463     {
1464       node->next = G_NODE (iter->user_data);
1465     }
1466   else if (prev)
1467     {
1468       prev->next = G_NODE (iter->user_data);
1469       G_NODE (iter->user_data)->next = node;
1470     }
1471   else
1472     {
1473       G_NODE (iter->user_data)->next = G_NODE (tree_store->root);
1474       tree_store->root = G_NODE (iter->user_data);
1475     }
1476
1477   /* Emit the reordered signal. */
1478   length = g_node_n_children (node->parent);
1479   new_order = g_new (int, length);
1480   if (old_location < new_location)
1481     for (i = 0; i < length; i++)
1482       {
1483         if (i < old_location ||
1484             i > new_location)
1485           new_order[i] = i;
1486         else if (i >= old_location &&
1487                  i < new_location)
1488           new_order[i] = i + 1;
1489         else if (i == new_location)
1490           new_order[i] = old_location;
1491       }
1492   else
1493     for (i = 0; i < length; i++)
1494       {
1495         if (i < new_location ||
1496             i > old_location)
1497           new_order[i] = i;
1498         else if (i > new_location &&
1499                  i <= old_location)
1500           new_order[i] = i - 1;
1501         else if (i == new_location)
1502           new_order[i] = old_location;
1503       }
1504
1505
1506   tmp_path = gtk_tree_path_new ();
1507   tmp_iter.user_data = NULL;
1508
1509   gtk_tree_model_reordered (GTK_TREE_MODEL (tree_store),
1510                             tmp_path, &tmp_iter,
1511                             new_order);
1512
1513   gtk_tree_path_free (tmp_path);
1514   g_free (new_order);
1515 }
1516
1517
1518 static gboolean
1519 gtk_tree_store_get_sort_column_id (GtkTreeSortable  *sortable,
1520                                    gint             *sort_column_id,
1521                                    GtkTreeSortOrder *order)
1522 {
1523   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
1524
1525   g_return_val_if_fail (sortable != NULL, FALSE);
1526   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
1527
1528   if (tree_store->sort_column_id == -1)
1529     return FALSE;
1530
1531   if (sort_column_id)
1532     * sort_column_id = tree_store->sort_column_id;
1533   if (order)
1534     * order = tree_store->order;
1535   return TRUE;
1536
1537 }
1538
1539 static void
1540 gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
1541                                    gint              sort_column_id,
1542                                    GtkTreeSortOrder  order)
1543 {
1544   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
1545   GList *list;
1546
1547   g_return_if_fail (sortable != NULL);
1548   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
1549
1550   for (list = tree_store->sort_list; list; list = list->next)
1551     {
1552       GtkTreeDataSortHeader *header = (GtkTreeDataSortHeader*) list->data;
1553       if (header->sort_column_id == sort_column_id)
1554         break;
1555     }
1556   g_return_if_fail (list != NULL);
1557
1558   if ((tree_store->sort_column_id == sort_column_id) &&
1559       (tree_store->order == order))
1560     return;
1561
1562   tree_store->sort_column_id = sort_column_id;
1563   tree_store->order = order;
1564
1565   if (tree_store->sort_column_id >= 0)
1566     gtk_tree_store_sort (tree_store);
1567
1568   gtk_tree_sortable_sort_column_changed (sortable);
1569 }
1570
1571 static void
1572 gtk_tree_store_sort_column_id_set_func (GtkTreeSortable        *sortable,
1573                                         gint                    sort_column_id,
1574                                         GtkTreeIterCompareFunc  func,
1575                                         gpointer                data,
1576                                         GtkDestroyNotify        destroy)
1577 {
1578   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
1579   GtkTreeDataSortHeader *header = NULL;
1580   GList *list;
1581
1582   g_return_if_fail (sortable != NULL);
1583   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
1584   g_return_if_fail (func != NULL);
1585
1586   for (list = tree_store->sort_list; list; list = list->next)
1587     {
1588       header = (GtkTreeDataSortHeader*) list->data;
1589       if (header->sort_column_id == sort_column_id)
1590         break;
1591     }
1592
1593   if (header == NULL)
1594     {
1595       header = g_new0 (GtkTreeDataSortHeader, 1);
1596       header->sort_column_id = sort_column_id;
1597       tree_store->sort_list = g_list_append (tree_store->sort_list, header);
1598     }
1599
1600   if (header->destroy)
1601     (* header->destroy) (header->data);
1602
1603   header->func = func;
1604   header->data = data;
1605   header->destroy = destroy;
1606
1607 }
1608
1609 static void
1610 validate_gnode (GNode* node)
1611 {
1612   GNode *iter;
1613
1614   iter = node->children;
1615   while (iter != NULL)
1616     {
1617       g_assert (iter->parent == node);
1618       if (iter->prev)
1619         g_assert (iter->prev->next == iter);
1620       validate_gnode (iter);
1621       iter = iter->next;
1622     }
1623 }
1624
1625