]> Pileus Git - ~andy/gtk/blob - gtk/gtktreestore.c
579c8f394681196681f59277a4b0bb542ec2fda6
[~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_ALL, 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  * Return value: %TRUE if @iter is still valid, %FALSE if not.
1032  **/
1033 gboolean
1034 gtk_tree_store_remove (GtkTreeStore *tree_store,
1035                        GtkTreeIter  *iter)
1036 {
1037   GtkTreePath *path;
1038   GtkTreeIter new_iter = {0,};
1039   GNode *parent;
1040   GNode *next_node;
1041
1042   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1043   g_return_val_if_fail (VALID_ITER (iter, tree_store), FALSE);
1044
1045   parent = G_NODE (iter->user_data)->parent;
1046
1047   g_assert (parent != NULL);
1048   next_node = G_NODE (iter->user_data)->next;
1049
1050   if (G_NODE (iter->user_data)->data)
1051     _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
1052                               tree_store->column_headers);
1053
1054   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1055   g_node_destroy (G_NODE (iter->user_data));
1056
1057   gtk_tree_model_row_deleted (GTK_TREE_MODEL (tree_store), path);
1058
1059   if (parent != G_NODE (tree_store->root))
1060     {
1061       /* child_toggled */
1062       if (parent->children == NULL)
1063         {
1064           gtk_tree_path_up (path);
1065
1066           new_iter.stamp = tree_store->stamp;
1067           new_iter.user_data = parent;
1068           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &new_iter);
1069         }
1070     }
1071   gtk_tree_path_free (path);
1072
1073   /* revalidate iter */
1074   if (next_node != NULL)
1075     {
1076       iter->stamp = tree_store->stamp;
1077       iter->user_data = next_node;
1078       return TRUE;
1079     }
1080   else
1081     {
1082       iter->stamp = 0;
1083       iter->user_data = NULL;
1084     }
1085
1086   return FALSE;
1087 }
1088
1089 /**
1090  * gtk_tree_store_insert:
1091  * @tree_store: A #GtkTreeStore
1092  * @iter: An unset #GtkTreeIter to set to the new row
1093  * @parent: A valid #GtkTreeIter, or %NULL
1094  * @position: position to insert the new row
1095  *
1096  * Creates a new row at @position.  If parent is non-%NULL, then the row will be
1097  * made a child of @parent.  Otherwise, the row will be created at the toplevel.
1098  * If @position is larger than the number of rows at that level, then the new
1099  * row will be inserted to the end of the list.  @iter will be changed to point
1100  * to this new row.  The row will be empty after this function is called.  To
1101  * fill in values, you need to call gtk_tree_store_set() or
1102  * gtk_tree_store_set_value().
1103  *
1104  **/
1105 void
1106 gtk_tree_store_insert (GtkTreeStore *tree_store,
1107                        GtkTreeIter  *iter,
1108                        GtkTreeIter  *parent,
1109                        gint          position)
1110 {
1111   GtkTreePath *path;
1112   GNode *parent_node;
1113
1114   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1115   if (parent)
1116     g_return_if_fail (VALID_ITER (parent, tree_store));
1117
1118   if (parent)
1119     parent_node = parent->user_data;
1120   else
1121     parent_node = tree_store->root;
1122
1123   tree_store->columns_dirty = TRUE;
1124
1125   iter->stamp = tree_store->stamp;
1126   iter->user_data = g_node_new (NULL);
1127   g_node_insert (parent_node, position, G_NODE (iter->user_data));
1128
1129   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1130   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1131
1132   gtk_tree_path_free (path);
1133
1134   validate_tree ((GtkTreeStore*)tree_store);
1135 }
1136
1137 /**
1138  * gtk_tree_store_insert_before:
1139  * @tree_store: A #GtkTreeStore
1140  * @iter: An unset #GtkTreeIter to set to the new row
1141  * @parent: A valid #GtkTreeIter, or %NULL
1142  * @sibling: A valid #GtkTreeIter, or %NULL
1143  *
1144  * Inserts a new row before @sibling.  If @sibling is %NULL, then the row will
1145  * be appended to @parent 's children.  If @parent and @sibling are %NULL, then
1146  * the row will be appended to the toplevel.  If both @sibling and @parent are
1147  * set, then @parent must be the parent of @sibling.  When @sibling is set,
1148  * @parent is optional.
1149  *
1150  * @iter will be changed to point to this new row.  The row will be empty after
1151  * this function is called.  To fill in values, you need to call
1152  * gtk_tree_store_set() or gtk_tree_store_set_value().
1153  *
1154  **/
1155 void
1156 gtk_tree_store_insert_before (GtkTreeStore *tree_store,
1157                               GtkTreeIter  *iter,
1158                               GtkTreeIter  *parent,
1159                               GtkTreeIter  *sibling)
1160 {
1161   GtkTreePath *path;
1162   GNode *parent_node = NULL;
1163   GNode *new_node;
1164
1165   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1166   g_return_if_fail (iter != NULL);
1167   if (parent != NULL)
1168     g_return_if_fail (VALID_ITER (parent, tree_store));
1169   if (sibling != NULL)
1170     g_return_if_fail (VALID_ITER (sibling, tree_store));
1171
1172   tree_store->columns_dirty = TRUE;
1173
1174   new_node = g_node_new (NULL);
1175
1176   if (parent == NULL && sibling == NULL)
1177     parent_node = tree_store->root;
1178   else if (parent == NULL)
1179     parent_node = G_NODE (sibling->user_data)->parent;
1180   else if (sibling == NULL)
1181     parent_node = G_NODE (parent->user_data);
1182   else
1183     {
1184       g_return_if_fail (G_NODE (sibling->user_data)->parent == G_NODE (parent->user_data));
1185       parent_node = G_NODE (parent->user_data);
1186     }
1187
1188   g_node_insert_before (parent_node,
1189                         sibling ? G_NODE (sibling->user_data) : NULL,
1190                         new_node);
1191
1192   iter->stamp = tree_store->stamp;
1193   iter->user_data = new_node;
1194
1195   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1196   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1197
1198   gtk_tree_path_free (path);
1199
1200   validate_tree ((GtkTreeStore*)tree_store);
1201 }
1202
1203 /**
1204  * gtk_tree_store_insert_after:
1205  * @tree_store: A #GtkTreeStore
1206  * @iter: An unset #GtkTreeIter to set to the new row
1207  * @parent: A valid #GtkTreeIter, or %NULL
1208  * @sibling: A valid #GtkTreeIter, or %NULL
1209  *
1210  * Inserts a new row after @sibling.  If @sibling is %NULL, then the row will be
1211  * prepended to the beginning of the @parent 's children.  If @parent and
1212  * @sibling are %NULL, then the row will be prepended to the toplevel.  If both
1213  * @sibling and @parent are set, then @parent must be the parent of @sibling.
1214  * When @sibling is set, @parent is optional.
1215  *
1216  * @iter will be changed to point to this new row.  The row will be empty after
1217  * this function is called.  To fill in values, you need to call
1218  * gtk_tree_store_set() or gtk_tree_store_set_value().
1219  *
1220  **/
1221 void
1222 gtk_tree_store_insert_after (GtkTreeStore *tree_store,
1223                              GtkTreeIter  *iter,
1224                              GtkTreeIter  *parent,
1225                              GtkTreeIter  *sibling)
1226 {
1227   GtkTreePath *path;
1228   GNode *parent_node;
1229   GNode *new_node;
1230
1231   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1232   g_return_if_fail (iter != NULL);
1233   if (parent != NULL)
1234     g_return_if_fail (VALID_ITER (parent, tree_store));
1235   if (sibling != NULL)
1236     g_return_if_fail (VALID_ITER (sibling, tree_store));
1237
1238   tree_store->columns_dirty = TRUE;
1239
1240   new_node = g_node_new (NULL);
1241
1242   if (parent == NULL && sibling == NULL)
1243     parent_node = tree_store->root;
1244   else if (parent == NULL)
1245     parent_node = G_NODE (sibling->user_data)->parent;
1246   else if (sibling == NULL)
1247     parent_node = G_NODE (parent->user_data);
1248   else
1249     {
1250       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
1251                         G_NODE (parent->user_data));
1252       parent_node = G_NODE (parent->user_data);
1253     }
1254
1255
1256   g_node_insert_after (parent_node,
1257                        sibling ? G_NODE (sibling->user_data) : NULL,
1258                        new_node);
1259
1260   iter->stamp = tree_store->stamp;
1261   iter->user_data = new_node;
1262
1263   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1264   gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1265
1266   gtk_tree_path_free (path);
1267
1268   validate_tree ((GtkTreeStore*)tree_store);
1269 }
1270
1271 /**
1272  * gtk_tree_store_prepend:
1273  * @tree_store: A #GtkTreeStore
1274  * @iter: An unset #GtkTreeIter to set to the prepended row
1275  * @parent: A valid #GtkTreeIter, or %NULL
1276  * 
1277  * Prepends a new row to @tree_store.  If @parent is non-%NULL, then it will prepend
1278  * the new row before the first child of @parent, otherwise it will prepend a row
1279  * to the top level.  @iter will be changed to point to this new row.  The row
1280  * will be empty after this function is called.  To fill in values, you need to
1281  * call gtk_tree_store_set() or gtk_tree_store_set_value().
1282  **/
1283 void
1284 gtk_tree_store_prepend (GtkTreeStore *tree_store,
1285                         GtkTreeIter  *iter,
1286                         GtkTreeIter  *parent)
1287 {
1288   GNode *parent_node;
1289
1290   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1291   g_return_if_fail (iter != NULL);
1292   if (parent != NULL)
1293     g_return_if_fail (VALID_ITER (parent, tree_store));
1294
1295   tree_store->columns_dirty = TRUE;
1296
1297   if (parent == NULL)
1298     parent_node = tree_store->root;
1299   else
1300     parent_node = parent->user_data;
1301
1302   if (parent_node->children == NULL)
1303     {
1304       GtkTreePath *path;
1305       
1306       iter->stamp = tree_store->stamp;
1307       iter->user_data = g_node_new (NULL);
1308
1309       g_node_prepend (parent_node, G_NODE (iter->user_data));
1310
1311       path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1312       gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1313
1314       if (parent_node != tree_store->root)
1315         {
1316           gtk_tree_path_up (path);
1317           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1318         }
1319       gtk_tree_path_free (path);
1320     }
1321   else
1322     {
1323       gtk_tree_store_insert_after (tree_store, iter, parent, NULL);
1324     }
1325
1326   validate_tree ((GtkTreeStore*)tree_store);
1327 }
1328
1329 /**
1330  * gtk_tree_store_append:
1331  * @tree_store: A #GtkTreeStore
1332  * @iter: An unset #GtkTreeIter to set to the appended row
1333  * @parent: A valid #GtkTreeIter, or %NULL
1334  * 
1335  * Appends a new row to @tree_store.  If @parent is non-%NULL, then it will append the
1336  * new row after the last child of @parent, otherwise it will append a row to
1337  * the top level.  @iter will be changed to point to this new row.  The row will
1338  * be empty after this function is called.  To fill in values, you need to call
1339  * gtk_tree_store_set() or gtk_tree_store_set_value().
1340  **/
1341 void
1342 gtk_tree_store_append (GtkTreeStore *tree_store,
1343                        GtkTreeIter  *iter,
1344                        GtkTreeIter  *parent)
1345 {
1346   GNode *parent_node;
1347
1348   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1349   g_return_if_fail (iter != NULL);
1350
1351   if (parent != NULL)
1352     g_return_if_fail (VALID_ITER (parent, tree_store));
1353
1354   if (parent == NULL)
1355     parent_node = tree_store->root;
1356   else
1357     parent_node = parent->user_data;
1358
1359   tree_store->columns_dirty = TRUE;
1360
1361   if (parent_node->children == NULL)
1362     {
1363       GtkTreePath *path;
1364
1365       iter->stamp = tree_store->stamp;
1366       iter->user_data = g_node_new (NULL);
1367
1368       g_node_append (parent_node, G_NODE (iter->user_data));
1369
1370       path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1371       gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1372
1373       if (parent_node != tree_store->root)
1374         {
1375           gtk_tree_path_up (path);
1376           gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1377         }
1378       gtk_tree_path_free (path);
1379     }
1380   else
1381     {
1382       gtk_tree_store_insert_before (tree_store, iter, parent, NULL);
1383     }
1384
1385   validate_tree ((GtkTreeStore*)tree_store);
1386 }
1387
1388 /**
1389  * gtk_tree_store_is_ancestor:
1390  * @tree_store: A #GtkTreeStore
1391  * @iter: A valid #GtkTreeIter
1392  * @descendant: A valid #GtkTreeIter
1393  * 
1394  * Returns %TRUE if @iter is an ancestor of @descendant.  That is, @iter is the
1395  * parent (or grandparent or great-grandparent) of @descendant.
1396  * 
1397  * Return value: %TRUE, if @iter is an ancestor of @descendant
1398  **/
1399 gboolean
1400 gtk_tree_store_is_ancestor (GtkTreeStore *tree_store,
1401                             GtkTreeIter  *iter,
1402                             GtkTreeIter  *descendant)
1403 {
1404   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1405   g_return_val_if_fail (VALID_ITER (iter, tree_store), FALSE);
1406   g_return_val_if_fail (VALID_ITER (descendant, tree_store), FALSE);
1407
1408   return g_node_is_ancestor (G_NODE (iter->user_data),
1409                              G_NODE (descendant->user_data));
1410 }
1411
1412
1413 /**
1414  * gtk_tree_store_iter_depth:
1415  * @tree_store: A #GtkTreeStore
1416  * @iter: A valid #GtkTreeIter
1417  * 
1418  * Returns the depth of @iter.  This will be 0 for anything on the root level, 1
1419  * for anything down a level, etc.
1420  * 
1421  * Return value: The depth of @iter
1422  **/
1423 gint
1424 gtk_tree_store_iter_depth (GtkTreeStore *tree_store,
1425                            GtkTreeIter  *iter)
1426 {
1427   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), 0);
1428   g_return_val_if_fail (VALID_ITER (iter, tree_store), 0);
1429
1430   return g_node_depth (G_NODE (iter->user_data)) - 2;
1431 }
1432
1433 /* simple ripoff from g_node_traverse_post_order */
1434 static gboolean
1435 gtk_tree_store_clear_traverse (GNode *node,
1436                                GtkTreeStore *store)
1437 {
1438   GtkTreeIter iter;
1439
1440   if (node->children)
1441     {
1442       GNode *child;
1443
1444       child = node->children;
1445       while (child)
1446         {
1447           register GNode *current;
1448
1449           current = child;
1450           child = current->next;
1451           if (gtk_tree_store_clear_traverse (current, store))
1452             return TRUE;
1453         }
1454
1455       if (node->parent)
1456         {
1457           iter.stamp = store->stamp;
1458           iter.user_data = node;
1459
1460           gtk_tree_store_remove (store, &iter);
1461         }
1462     }
1463   else if (node->parent)
1464     {
1465       iter.stamp = store->stamp;
1466       iter.user_data = node;
1467
1468       gtk_tree_store_remove (store, &iter);
1469     }
1470
1471   return FALSE;
1472 }
1473
1474 /**
1475  * gtk_tree_store_clear:
1476  * @tree_store: a #GtkTreeStore
1477  * 
1478  * Removes all rows from @tree_store
1479  **/
1480 void
1481 gtk_tree_store_clear (GtkTreeStore *tree_store)
1482 {
1483   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1484
1485   gtk_tree_store_clear_traverse (tree_store->root, tree_store);
1486 }
1487
1488 static gboolean
1489 gtk_tree_store_iter_is_valid_helper (GtkTreeIter *iter,
1490                                      GNode       *first)
1491 {
1492   GNode *node;
1493
1494   node = first;
1495
1496   do
1497     {
1498       if (node == iter->user_data)
1499         return TRUE;
1500
1501       if (node->children)
1502         if (gtk_tree_store_iter_is_valid_helper (iter, node->children))
1503           return TRUE;
1504
1505       node = node->next;
1506     }
1507   while (node);
1508
1509   return FALSE;
1510 }
1511
1512 /**
1513  * gtk_tree_store_iter_is_valid:
1514  * @tree_store: A #GtkTreeStore.
1515  * @iter: A #GtkTreeIter.
1516  *
1517  * WARNING: This function is slow. Only use it for debugging and/or testing
1518  * purposes.
1519  *
1520  * Checks if the given iter is a valid iter for this #GtkTreeStore.
1521  *
1522  * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
1523  **/
1524 gboolean
1525 gtk_tree_store_iter_is_valid (GtkTreeStore *tree_store,
1526                               GtkTreeIter  *iter)
1527 {
1528   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1529   g_return_val_if_fail (iter != NULL, FALSE);
1530
1531   if (!VALID_ITER (iter, tree_store))
1532     return FALSE;
1533
1534   return gtk_tree_store_iter_is_valid_helper (iter, tree_store->root);
1535 }
1536
1537 /* DND */
1538
1539
1540 static gboolean
1541 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1542                                  GtkTreePath       *path)
1543 {
1544   GtkTreeIter iter;
1545
1546   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1547
1548   if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
1549                                &iter,
1550                                path))
1551     {
1552       gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1553                              &iter);
1554       return TRUE;
1555     }
1556   else
1557     {
1558       return FALSE;
1559     }
1560 }
1561
1562 static gboolean
1563 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1564                               GtkTreePath       *path,
1565                               GtkSelectionData  *selection_data)
1566 {
1567   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1568
1569   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1570    * target, because the default handler does it for us, but
1571    * we do anyway for the convenience of someone maybe overriding the
1572    * default handler.
1573    */
1574
1575   if (gtk_tree_set_row_drag_data (selection_data,
1576                                   GTK_TREE_MODEL (drag_source),
1577                                   path))
1578     {
1579       return TRUE;
1580     }
1581   else
1582     {
1583       /* FIXME handle text targets at least. */
1584     }
1585
1586   return FALSE;
1587 }
1588
1589 static void
1590 copy_node_data (GtkTreeStore *tree_store,
1591                 GtkTreeIter  *src_iter,
1592                 GtkTreeIter  *dest_iter)
1593 {
1594   GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1595   GtkTreeDataList *copy_head = NULL;
1596   GtkTreeDataList *copy_prev = NULL;
1597   GtkTreeDataList *copy_iter = NULL;
1598   GtkTreePath *path;
1599   gint col;
1600
1601   col = 0;
1602   while (dl)
1603     {
1604       copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1605
1606       if (copy_head == NULL)
1607         copy_head = copy_iter;
1608
1609       if (copy_prev)
1610         copy_prev->next = copy_iter;
1611
1612       copy_prev = copy_iter;
1613
1614       dl = dl->next;
1615       ++col;
1616     }
1617
1618   G_NODE (dest_iter->user_data)->data = copy_head;
1619
1620   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1621   gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, dest_iter);
1622   gtk_tree_path_free (path);
1623 }
1624
1625 static void
1626 recursive_node_copy (GtkTreeStore *tree_store,
1627                      GtkTreeIter  *src_iter,
1628                      GtkTreeIter  *dest_iter)
1629 {
1630   GtkTreeIter child;
1631   GtkTreeModel *model;
1632
1633   model = GTK_TREE_MODEL (tree_store);
1634
1635   copy_node_data (tree_store, src_iter, dest_iter);
1636
1637   if (gtk_tree_model_iter_children (model,
1638                                     &child,
1639                                     src_iter))
1640     {
1641       /* Need to create children and recurse. Note our
1642        * dependence on persistent iterators here.
1643        */
1644       do
1645         {
1646           GtkTreeIter copy;
1647
1648           /* Gee, a really slow algorithm... ;-) FIXME */
1649           gtk_tree_store_append (tree_store,
1650                                  &copy,
1651                                  dest_iter);
1652
1653           recursive_node_copy (tree_store, &child, &copy);
1654         }
1655       while (gtk_tree_model_iter_next (model, &child));
1656     }
1657 }
1658
1659 static gboolean
1660 gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
1661                                    GtkTreePath       *dest,
1662                                    GtkSelectionData  *selection_data)
1663 {
1664   GtkTreeModel *tree_model;
1665   GtkTreeStore *tree_store;
1666   GtkTreeModel *src_model = NULL;
1667   GtkTreePath *src_path = NULL;
1668   gboolean retval = FALSE;
1669
1670   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
1671
1672   tree_model = GTK_TREE_MODEL (drag_dest);
1673   tree_store = GTK_TREE_STORE (drag_dest);
1674
1675   validate_tree (tree_store);
1676
1677   if (gtk_tree_get_row_drag_data (selection_data,
1678                                   &src_model,
1679                                   &src_path) &&
1680       src_model == tree_model)
1681     {
1682       /* Copy the given row to a new position */
1683       GtkTreeIter src_iter;
1684       GtkTreeIter dest_iter;
1685       GtkTreePath *prev;
1686
1687       if (!gtk_tree_model_get_iter (src_model,
1688                                     &src_iter,
1689                                     src_path))
1690         {
1691           goto out;
1692         }
1693
1694       /* Get the path to insert _after_ (dest is the path to insert _before_) */
1695       prev = gtk_tree_path_copy (dest);
1696
1697       if (!gtk_tree_path_prev (prev))
1698         {
1699           GtkTreeIter dest_parent;
1700           GtkTreePath *parent;
1701           GtkTreeIter *dest_parent_p;
1702
1703           /* dest was the first spot at the current depth; which means
1704            * we are supposed to prepend.
1705            */
1706
1707           /* Get the parent, NULL if parent is the root */
1708           dest_parent_p = NULL;
1709           parent = gtk_tree_path_copy (dest);
1710           if (gtk_tree_path_up (parent) &&
1711               gtk_tree_path_get_depth (parent) > 0)
1712             {
1713               gtk_tree_model_get_iter (tree_model,
1714                                        &dest_parent,
1715                                        parent);
1716               dest_parent_p = &dest_parent;
1717             }
1718           gtk_tree_path_free (parent);
1719           parent = NULL;
1720
1721           gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
1722                                   &dest_iter,
1723                                   dest_parent_p);
1724
1725           retval = TRUE;
1726         }
1727       else
1728         {
1729           if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
1730                                        &dest_iter,
1731                                        prev))
1732             {
1733               GtkTreeIter tmp_iter = dest_iter;
1734
1735               if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_model), "gtk-tree-model-drop-append")))
1736                 {
1737                   GtkTreeIter parent;
1738
1739                   if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (tree_model), &parent, &tmp_iter))
1740                     gtk_tree_store_append (GTK_TREE_STORE (tree_model),
1741                                            &dest_iter, &parent);
1742                   else
1743                     gtk_tree_store_append (GTK_TREE_STORE (tree_model),
1744                                            &dest_iter, NULL);
1745                 }
1746               else
1747                 gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
1748                                              &dest_iter,
1749                                              NULL,
1750                                              &tmp_iter);
1751               retval = TRUE;
1752
1753             }
1754         }
1755
1756       g_object_set_data (G_OBJECT (tree_model), "gtk-tree-model-drop-append",
1757                          NULL);
1758
1759       gtk_tree_path_free (prev);
1760
1761       /* If we succeeded in creating dest_iter, walk src_iter tree branch,
1762        * duplicating it below dest_iter.
1763        */
1764
1765       if (retval)
1766         {
1767           recursive_node_copy (tree_store,
1768                                &src_iter,
1769                                &dest_iter);
1770         }
1771     }
1772   else
1773     {
1774       /* FIXME maybe add some data targets eventually, or handle text
1775        * targets in the simple case.
1776        */
1777
1778     }
1779
1780  out:
1781
1782   if (src_path)
1783     gtk_tree_path_free (src_path);
1784
1785   return retval;
1786 }
1787
1788 static gboolean
1789 gtk_tree_store_row_drop_possible (GtkTreeDragDest  *drag_dest,
1790                                   GtkTreePath      *dest_path,
1791                                   GtkSelectionData *selection_data)
1792 {
1793   GtkTreeModel *src_model = NULL;
1794   GtkTreePath *src_path = NULL;
1795   GtkTreePath *tmp = NULL;
1796   gboolean retval = FALSE;
1797   
1798   if (!gtk_tree_get_row_drag_data (selection_data,
1799                                    &src_model,
1800                                    &src_path))
1801     goto out;
1802     
1803   /* can only drag to ourselves */
1804   if (src_model != GTK_TREE_MODEL (drag_dest))
1805     goto out;
1806
1807   /* Can't drop into ourself. */
1808   if (gtk_tree_path_is_ancestor (src_path,
1809                                  dest_path))
1810     goto out;
1811
1812   /* Can't drop if dest_path's parent doesn't exist */
1813   {
1814     GtkTreeIter iter;
1815
1816     if (gtk_tree_path_get_depth (dest_path) > 1)
1817       {
1818         tmp = gtk_tree_path_copy (dest_path);
1819         gtk_tree_path_up (tmp);
1820         
1821         if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
1822                                       &iter, tmp))
1823           goto out;
1824       }
1825   }
1826   
1827   /* Can otherwise drop anywhere. */
1828   retval = TRUE;
1829
1830  out:
1831
1832   if (src_path)
1833     gtk_tree_path_free (src_path);
1834   if (tmp)
1835     gtk_tree_path_free (tmp);
1836
1837   return retval;
1838 }
1839
1840 /* Sorting */
1841 typedef struct _SortTuple
1842 {
1843   gint offset;
1844   GNode *node;
1845 } SortTuple;
1846
1847 static gint
1848 gtk_tree_store_compare_func (gconstpointer a,
1849                              gconstpointer b,
1850                              gpointer      user_data)
1851 {
1852   GtkTreeStore *tree_store = user_data;
1853   GNode *node_a;
1854   GNode *node_b;
1855   GtkTreeIterCompareFunc func;
1856   gpointer data;
1857
1858   GtkTreeIter iter_a;
1859   GtkTreeIter iter_b;
1860   gint retval;
1861
1862   if (tree_store->sort_column_id != -1)
1863     {
1864       GtkTreeDataSortHeader *header;
1865
1866       header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1867                                                tree_store->sort_column_id);
1868       g_return_val_if_fail (header != NULL, 0);
1869       g_return_val_if_fail (header->func != NULL, 0);
1870
1871       func = header->func;
1872       data = header->data;
1873     }
1874   else
1875     {
1876       g_return_val_if_fail (tree_store->default_sort_func != NULL, 0);
1877       func = tree_store->default_sort_func;
1878       data = tree_store->default_sort_data;
1879     }
1880
1881   node_a = ((SortTuple *) a)->node;
1882   node_b = ((SortTuple *) b)->node;
1883
1884   iter_a.stamp = tree_store->stamp;
1885   iter_a.user_data = node_a;
1886   iter_b.stamp = tree_store->stamp;
1887   iter_b.user_data = node_b;
1888
1889   retval = (* func) (GTK_TREE_MODEL (user_data), &iter_a, &iter_b, data);
1890
1891   if (tree_store->order == GTK_SORT_DESCENDING)
1892     {
1893       if (retval > 0)
1894         retval = -1;
1895       else if (retval < 0)
1896         retval = 1;
1897     }
1898   return retval;
1899 }
1900
1901 static void
1902 gtk_tree_store_sort_helper (GtkTreeStore *tree_store,
1903                             GNode        *parent,
1904                             gboolean      recurse)
1905 {
1906   GtkTreeIter iter;
1907   GArray *sort_array;
1908   GNode *node;
1909   GNode *tmp_node;
1910   gint list_length;
1911   gint i;
1912   gint *new_order;
1913   GtkTreePath *path;
1914
1915   node = parent->children;
1916   if (node == NULL || node->next == NULL)
1917     return;
1918
1919   g_assert (GTK_TREE_STORE_IS_SORTED (tree_store));
1920
1921   list_length = 0;
1922   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1923     list_length++;
1924
1925   sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), list_length);
1926
1927   i = 0;
1928   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1929     {
1930       SortTuple tuple;
1931
1932       tuple.offset = i;
1933       tuple.node = tmp_node;
1934       g_array_append_val (sort_array, tuple);
1935       i++;
1936     }
1937
1938   /* Sort the array */
1939   g_array_sort_with_data (sort_array, gtk_tree_store_compare_func, tree_store);
1940
1941   for (i = 0; i < list_length - 1; i++)
1942     {
1943       g_array_index (sort_array, SortTuple, i).node->next =
1944         g_array_index (sort_array, SortTuple, i + 1).node;
1945       g_array_index (sort_array, SortTuple, i + 1).node->prev =
1946         g_array_index (sort_array, SortTuple, i).node;
1947     }
1948   g_array_index (sort_array, SortTuple, list_length - 1).node->next = NULL;
1949   g_array_index (sort_array, SortTuple, 0).node->prev = NULL;
1950   parent->children = g_array_index (sort_array, SortTuple, 0).node;
1951
1952   /* Let the world know about our new order */
1953   new_order = g_new (gint, list_length);
1954   for (i = 0; i < list_length; i++)
1955     new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1956
1957   iter.stamp = tree_store->stamp;
1958   iter.user_data = parent;
1959   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &iter);
1960   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
1961                                  path, &iter, new_order);
1962   gtk_tree_path_free (path);
1963   g_free (new_order);
1964   g_array_free (sort_array, TRUE);
1965
1966   if (recurse)
1967     {
1968       for (tmp_node = parent->children; tmp_node; tmp_node = tmp_node->next)
1969         {
1970           if (tmp_node->children)
1971             gtk_tree_store_sort_helper (tree_store, tmp_node, TRUE);
1972         }
1973     }
1974 }
1975
1976 static void
1977 gtk_tree_store_sort (GtkTreeStore *tree_store)
1978 {
1979   if (tree_store->sort_column_id != -1)
1980     {
1981       GtkTreeDataSortHeader *header = NULL;
1982
1983       header = _gtk_tree_data_list_get_header (tree_store->sort_list, tree_store->sort_column_id);
1984
1985       /* We want to make sure that we have a function */
1986       g_return_if_fail (header != NULL);
1987       g_return_if_fail (header->func != NULL);
1988     }
1989   else
1990     {
1991       g_return_if_fail (tree_store->default_sort_func != NULL);
1992     }
1993
1994   gtk_tree_store_sort_helper (tree_store, G_NODE (tree_store->root), TRUE);
1995 }
1996
1997 static void
1998 gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
1999                                   GtkTreeIter  *iter,
2000                                   gint          column)
2001 {
2002   GNode *prev = NULL;
2003   GNode *next = NULL;
2004   GNode *node;
2005   GtkTreePath *tmp_path;
2006   GtkTreeIter tmp_iter;
2007   gint cmp_a = 0;
2008   gint cmp_b = 0;
2009   gint i;
2010   gint old_location;
2011   gint new_location;
2012   gint *new_order;
2013   gint length;
2014   GtkTreeIterCompareFunc func;
2015   gpointer data;
2016
2017   g_return_if_fail (G_NODE (iter->user_data)->parent != NULL);
2018
2019   tmp_iter.stamp = tree_store->stamp;
2020   if (tree_store->sort_column_id != -1)
2021     {
2022       GtkTreeDataSortHeader *header;
2023       header = _gtk_tree_data_list_get_header (tree_store->sort_list,
2024                                                tree_store->sort_column_id);
2025       g_return_if_fail (header != NULL);
2026       g_return_if_fail (header->func != NULL);
2027       func = header->func;
2028       data = header->data;
2029     }
2030   else
2031     {
2032       g_return_if_fail (tree_store->default_sort_func != NULL);
2033       func = tree_store->default_sort_func;
2034       data = tree_store->default_sort_data;
2035     }
2036
2037   /* If it's the built in function, we don't sort. */
2038   if (func == gtk_tree_data_list_compare_func &&
2039       tree_store->sort_column_id != column)
2040     return;
2041
2042   old_location = 0;
2043   node = G_NODE (iter->user_data)->parent->children;
2044   /* First we find the iter, its prev, and its next */
2045   while (node)
2046     {
2047       if (node == G_NODE (iter->user_data))
2048         break;
2049       old_location++;
2050       node = node->next;
2051     }
2052   g_assert (node != NULL);
2053
2054   prev = node->prev;
2055   next = node->next;
2056
2057   /* Check the common case, where we don't need to sort it moved. */
2058   if (prev != NULL)
2059     {
2060       tmp_iter.user_data = prev;
2061       cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
2062     }
2063
2064   if (next != NULL)
2065     {
2066       tmp_iter.user_data = next;
2067       cmp_b = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
2068     }
2069
2070
2071   if (tree_store->order == GTK_SORT_DESCENDING)
2072     {
2073       if (cmp_a < 0)
2074         cmp_a = 1;
2075       else if (cmp_a > 0)
2076         cmp_a = -1;
2077
2078       if (cmp_b < 0)
2079         cmp_b = 1;
2080       else if (cmp_b > 0)
2081         cmp_b = -1;
2082     }
2083
2084   if (prev == NULL && cmp_b <= 0)
2085     return;
2086   else if (next == NULL && cmp_a <= 0)
2087     return;
2088   else if (prev != NULL && next != NULL &&
2089            cmp_a <= 0 && cmp_b <= 0)
2090     return;
2091
2092   /* We actually need to sort it */
2093   /* First, remove the old link. */
2094
2095   if (prev)
2096     prev->next = next;
2097   else
2098     node->parent->children = next;
2099
2100   if (next)
2101     next->prev = prev;
2102
2103   node->prev = NULL;
2104   node->next = NULL;
2105
2106   /* FIXME: as an optimization, we can potentially start at next */
2107   prev = NULL;
2108   node = node->parent->children;
2109   new_location = 0;
2110   tmp_iter.user_data = node;
2111   if (tree_store->order == GTK_SORT_DESCENDING)
2112     cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
2113   else
2114     cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
2115
2116   while ((node->next) && (cmp_a > 0))
2117     {
2118       prev = node;
2119       node = node->next;
2120       new_location++;
2121       tmp_iter.user_data = node;
2122       if (tree_store->order == GTK_SORT_DESCENDING)
2123         cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
2124       else
2125         cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
2126     }
2127
2128   if ((!node->next) && (cmp_a > 0))
2129     {
2130       new_location++;
2131       node->next = G_NODE (iter->user_data);
2132       node->next->prev = node;
2133     }
2134   else if (prev)
2135     {
2136       prev->next = G_NODE (iter->user_data);
2137       prev->next->prev = prev;
2138       G_NODE (iter->user_data)->next = node;
2139       G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
2140     }
2141   else
2142     {
2143       G_NODE (iter->user_data)->next = G_NODE (iter->user_data)->parent->children;
2144       G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
2145       G_NODE (iter->user_data)->parent->children = G_NODE (iter->user_data);
2146     }
2147
2148   /* Emit the reordered signal. */
2149   length = g_node_n_children (node->parent);
2150   new_order = g_new (int, length);
2151   if (old_location < new_location)
2152     for (i = 0; i < length; i++)
2153       {
2154         if (i < old_location ||
2155             i > new_location)
2156           new_order[i] = i;
2157         else if (i >= old_location &&
2158                  i < new_location)
2159           new_order[i] = i + 1;
2160         else if (i == new_location)
2161           new_order[i] = old_location;
2162       }
2163   else
2164     for (i = 0; i < length; i++)
2165       {
2166         if (i < new_location ||
2167             i > old_location)
2168           new_order[i] = i;
2169         else if (i > new_location &&
2170                  i <= old_location)
2171           new_order[i] = i - 1;
2172         else if (i == new_location)
2173           new_order[i] = old_location;
2174       }
2175
2176   tmp_iter.user_data = node->parent;
2177   tmp_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &tmp_iter);
2178
2179   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
2180                                  tmp_path, &tmp_iter,
2181                                  new_order);
2182
2183   gtk_tree_path_free (tmp_path);
2184   g_free (new_order);
2185 }
2186
2187
2188 static gboolean
2189 gtk_tree_store_get_sort_column_id (GtkTreeSortable  *sortable,
2190                                    gint             *sort_column_id,
2191                                    GtkSortType      *order)
2192 {
2193   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2194
2195   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
2196
2197   if (tree_store->sort_column_id == -1)
2198     return FALSE;
2199
2200   if (sort_column_id)
2201     * sort_column_id = tree_store->sort_column_id;
2202   if (order)
2203     * order = tree_store->order;
2204   return TRUE;
2205
2206 }
2207
2208 static void
2209 gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
2210                                    gint              sort_column_id,
2211                                    GtkSortType       order)
2212 {
2213   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2214
2215   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2216
2217   
2218   if ((tree_store->sort_column_id == sort_column_id) &&
2219       (tree_store->order == order))
2220     return;
2221
2222   if (sort_column_id != -1)
2223     {
2224       GtkTreeDataSortHeader *header = NULL;
2225
2226       header = _gtk_tree_data_list_get_header (tree_store->sort_list, sort_column_id);
2227
2228       /* We want to make sure that we have a function */
2229       g_return_if_fail (header != NULL);
2230       g_return_if_fail (header->func != NULL);
2231     }
2232   else
2233     {
2234       g_return_if_fail (tree_store->default_sort_func != NULL);
2235     }
2236
2237   tree_store->sort_column_id = sort_column_id;
2238   tree_store->order = order;
2239
2240   gtk_tree_store_sort (tree_store);
2241
2242   gtk_tree_sortable_sort_column_changed (sortable);
2243 }
2244
2245 static void
2246 gtk_tree_store_set_sort_func (GtkTreeSortable        *sortable,
2247                               gint                    sort_column_id,
2248                               GtkTreeIterCompareFunc  func,
2249                               gpointer                data,
2250                               GtkDestroyNotify        destroy)
2251 {
2252   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2253   GtkTreeDataSortHeader *header = NULL;
2254   GList *list;
2255
2256   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2257   g_return_if_fail (func != NULL);
2258
2259   for (list = tree_store->sort_list; list; list = list->next)
2260     {
2261       GtkTreeDataSortHeader *list_header;
2262
2263       list_header = (GtkTreeDataSortHeader*) list->data;
2264       if (list_header->sort_column_id == sort_column_id)
2265         {
2266           header = list_header;
2267           break;
2268         }
2269     }
2270
2271   if (header == NULL)
2272     {
2273       header = g_new0 (GtkTreeDataSortHeader, 1);
2274       header->sort_column_id = sort_column_id;
2275       tree_store->sort_list = g_list_append (tree_store->sort_list, header);
2276     }
2277
2278   if (header->destroy)
2279     {
2280       GtkDestroyNotify d = header->destroy;
2281
2282       header->destroy = NULL;
2283       d (header->data);
2284     }
2285
2286   header->func = func;
2287   header->data = data;
2288   header->destroy = destroy;
2289 }
2290
2291 static void
2292 gtk_tree_store_set_default_sort_func (GtkTreeSortable        *sortable,
2293                                       GtkTreeIterCompareFunc  func,
2294                                       gpointer                data,
2295                                       GtkDestroyNotify        destroy)
2296 {
2297   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2298
2299   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
2300
2301   if (tree_store->default_sort_destroy)
2302     {
2303       GtkDestroyNotify d = tree_store->default_sort_destroy;
2304
2305       tree_store->default_sort_destroy = NULL;
2306       d (tree_store->default_sort_data);
2307     }
2308
2309   tree_store->default_sort_func = func;
2310   tree_store->default_sort_data = data;
2311   tree_store->default_sort_destroy = destroy;
2312 }
2313
2314 static gboolean
2315 gtk_tree_store_has_default_sort_func (GtkTreeSortable *sortable)
2316 {
2317   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
2318
2319   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
2320
2321   return (tree_store->default_sort_func != NULL);
2322 }
2323
2324 static void
2325 validate_gnode (GNode* node)
2326 {
2327   GNode *iter;
2328
2329   iter = node->children;
2330   while (iter != NULL)
2331     {
2332       g_assert (iter->parent == node);
2333       if (iter->prev)
2334         g_assert (iter->prev->next == iter);
2335       validate_gnode (iter);
2336       iter = iter->next;
2337     }
2338 }
2339
2340
2341