2 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
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.
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.
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.
22 #include <gobject/gvaluecollector.h>
23 #include "gtktreemodel.h"
24 #include "gtktreestore.h"
25 #include "gtktreedatalist.h"
26 #include "gtktreednd.h"
27 #include "gtkbuildable.h"
31 #define G_NODE(node) ((GNode *)node)
32 #define GTK_TREE_STORE_IS_SORTED(tree) (((GtkTreeStore*)(tree))->sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
33 #define VALID_ITER(iter, tree_store) ((iter)!= NULL && (iter)->user_data != NULL && ((GtkTreeStore*)(tree_store))->stamp == (iter)->stamp)
35 static void gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
36 static void gtk_tree_store_drag_source_init(GtkTreeDragSourceIface *iface);
37 static void gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface);
38 static void gtk_tree_store_sortable_init (GtkTreeSortableIface *iface);
39 static void gtk_tree_store_buildable_init (GtkBuildableIface *iface);
40 static void gtk_tree_store_finalize (GObject *object);
41 static GtkTreeModelFlags gtk_tree_store_get_flags (GtkTreeModel *tree_model);
42 static gint gtk_tree_store_get_n_columns (GtkTreeModel *tree_model);
43 static GType gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
45 static gboolean gtk_tree_store_get_iter (GtkTreeModel *tree_model,
48 static GtkTreePath *gtk_tree_store_get_path (GtkTreeModel *tree_model,
50 static void gtk_tree_store_get_value (GtkTreeModel *tree_model,
54 static gboolean gtk_tree_store_iter_next (GtkTreeModel *tree_model,
56 static gboolean gtk_tree_store_iter_children (GtkTreeModel *tree_model,
59 static gboolean gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
61 static gint gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
63 static gboolean gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
67 static gboolean gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
72 static void gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
74 static void gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
78 static void gtk_tree_store_increment_stamp (GtkTreeStore *tree_store);
82 static gboolean real_gtk_tree_store_row_draggable (GtkTreeDragSource *drag_source,
84 static gboolean gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
86 static gboolean gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
88 GtkSelectionData *selection_data);
89 static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest,
91 GtkSelectionData *selection_data);
92 static gboolean gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
93 GtkTreePath *dest_path,
94 GtkSelectionData *selection_data);
96 /* Sortable Interfaces */
98 static void gtk_tree_store_sort (GtkTreeStore *tree_store);
99 static void gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
102 gboolean emit_signal);
103 static gboolean gtk_tree_store_get_sort_column_id (GtkTreeSortable *sortable,
104 gint *sort_column_id,
106 static void gtk_tree_store_set_sort_column_id (GtkTreeSortable *sortable,
109 static void gtk_tree_store_set_sort_func (GtkTreeSortable *sortable,
111 GtkTreeIterCompareFunc func,
113 GDestroyNotify destroy);
114 static void gtk_tree_store_set_default_sort_func (GtkTreeSortable *sortable,
115 GtkTreeIterCompareFunc func,
117 GDestroyNotify destroy);
118 static gboolean gtk_tree_store_has_default_sort_func (GtkTreeSortable *sortable);
123 static gboolean gtk_tree_store_buildable_custom_tag_start (GtkBuildable *buildable,
126 const gchar *tagname,
127 GMarkupParser *parser,
129 static void gtk_tree_store_buildable_custom_finished (GtkBuildable *buildable,
132 const gchar *tagname,
135 static void validate_gnode (GNode *node);
137 static void gtk_tree_store_move (GtkTreeStore *tree_store,
139 GtkTreeIter *position,
144 validate_tree (GtkTreeStore *tree_store)
146 if (gtk_debug_flags & GTK_DEBUG_TREE)
148 g_assert (G_NODE (tree_store->root)->parent == NULL);
150 validate_gnode (G_NODE (tree_store->root));
154 G_DEFINE_TYPE_WITH_CODE (GtkTreeStore, gtk_tree_store, G_TYPE_OBJECT,
155 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
156 gtk_tree_store_tree_model_init)
157 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
158 gtk_tree_store_drag_source_init)
159 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_DEST,
160 gtk_tree_store_drag_dest_init)
161 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
162 gtk_tree_store_sortable_init)
163 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
164 gtk_tree_store_buildable_init))
167 gtk_tree_store_class_init (GtkTreeStoreClass *class)
169 GObjectClass *object_class;
171 object_class = (GObjectClass *) class;
173 object_class->finalize = gtk_tree_store_finalize;
177 gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
179 iface->get_flags = gtk_tree_store_get_flags;
180 iface->get_n_columns = gtk_tree_store_get_n_columns;
181 iface->get_column_type = gtk_tree_store_get_column_type;
182 iface->get_iter = gtk_tree_store_get_iter;
183 iface->get_path = gtk_tree_store_get_path;
184 iface->get_value = gtk_tree_store_get_value;
185 iface->iter_next = gtk_tree_store_iter_next;
186 iface->iter_children = gtk_tree_store_iter_children;
187 iface->iter_has_child = gtk_tree_store_iter_has_child;
188 iface->iter_n_children = gtk_tree_store_iter_n_children;
189 iface->iter_nth_child = gtk_tree_store_iter_nth_child;
190 iface->iter_parent = gtk_tree_store_iter_parent;
194 gtk_tree_store_drag_source_init (GtkTreeDragSourceIface *iface)
196 iface->row_draggable = real_gtk_tree_store_row_draggable;
197 iface->drag_data_delete = gtk_tree_store_drag_data_delete;
198 iface->drag_data_get = gtk_tree_store_drag_data_get;
202 gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface)
204 iface->drag_data_received = gtk_tree_store_drag_data_received;
205 iface->row_drop_possible = gtk_tree_store_row_drop_possible;
209 gtk_tree_store_sortable_init (GtkTreeSortableIface *iface)
211 iface->get_sort_column_id = gtk_tree_store_get_sort_column_id;
212 iface->set_sort_column_id = gtk_tree_store_set_sort_column_id;
213 iface->set_sort_func = gtk_tree_store_set_sort_func;
214 iface->set_default_sort_func = gtk_tree_store_set_default_sort_func;
215 iface->has_default_sort_func = gtk_tree_store_has_default_sort_func;
219 gtk_tree_store_buildable_init (GtkBuildableIface *iface)
221 iface->custom_tag_start = gtk_tree_store_buildable_custom_tag_start;
222 iface->custom_finished = gtk_tree_store_buildable_custom_finished;
226 gtk_tree_store_init (GtkTreeStore *tree_store)
228 tree_store->root = g_node_new (NULL);
229 /* While the odds are against us getting 0...
233 tree_store->stamp = g_random_int ();
235 while (tree_store->stamp == 0);
237 tree_store->sort_list = NULL;
238 tree_store->sort_column_id = -2;
239 tree_store->columns_dirty = FALSE;
243 * gtk_tree_store_new:
244 * @n_columns: number of columns in the tree store
245 * @Varargs: all #GType types for the columns, from first to last
247 * Creates a new tree store as with @n_columns columns each of the types passed
248 * in. Note that only types derived from standard GObject fundamental types
251 * As an example, <literal>gtk_tree_store_new (3, G_TYPE_INT, G_TYPE_STRING,
252 * GDK_TYPE_PIXBUF);</literal> will create a new #GtkTreeStore with three columns, of type
253 * <type>int</type>, <type>string</type> and #GdkPixbuf respectively.
255 * Return value: a new #GtkTreeStore
258 gtk_tree_store_new (gint n_columns,
261 GtkTreeStore *retval;
265 g_return_val_if_fail (n_columns > 0, NULL);
267 retval = g_object_new (GTK_TYPE_TREE_STORE, NULL);
268 gtk_tree_store_set_n_columns (retval, n_columns);
270 va_start (args, n_columns);
272 for (i = 0; i < n_columns; i++)
274 GType type = va_arg (args, GType);
275 if (! _gtk_tree_data_list_check_type (type))
277 g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (type));
278 g_object_unref (retval);
281 gtk_tree_store_set_column_type (retval, i, type);
288 * gtk_tree_store_newv:
289 * @n_columns: number of columns in the tree store
290 * @types: an array of #GType types for the columns, from first to last
292 * Non vararg creation function. Used primarily by language bindings.
294 * Return value: a new #GtkTreeStore
297 gtk_tree_store_newv (gint n_columns,
300 GtkTreeStore *retval;
303 g_return_val_if_fail (n_columns > 0, NULL);
305 retval = g_object_new (GTK_TYPE_TREE_STORE, NULL);
306 gtk_tree_store_set_n_columns (retval, n_columns);
308 for (i = 0; i < n_columns; i++)
310 if (! _gtk_tree_data_list_check_type (types[i]))
312 g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (types[i]));
313 g_object_unref (retval);
316 gtk_tree_store_set_column_type (retval, i, types[i]);
324 * gtk_tree_store_set_column_types:
325 * @tree_store: A #GtkTreeStore
326 * @n_columns: Number of columns for the tree store
327 * @types: An array of #GType types, one for each column
329 * This function is meant primarily for #GObjects that inherit from
330 * #GtkTreeStore, and should only be used when constructing a new
331 * #GtkTreeStore. It will not function after a row has been added,
332 * or a method on the #GtkTreeModel interface is called.
335 gtk_tree_store_set_column_types (GtkTreeStore *tree_store,
341 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
342 g_return_if_fail (tree_store->columns_dirty == 0);
344 gtk_tree_store_set_n_columns (tree_store, n_columns);
345 for (i = 0; i < n_columns; i++)
347 if (! _gtk_tree_data_list_check_type (types[i]))
349 g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (types[i]));
352 gtk_tree_store_set_column_type (tree_store, i, types[i]);
357 gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
362 if (tree_store->n_columns == n_columns)
365 new_columns = g_new0 (GType, n_columns);
366 if (tree_store->column_headers)
368 /* copy the old header orders over */
369 if (n_columns >= tree_store->n_columns)
370 memcpy (new_columns, tree_store->column_headers, tree_store->n_columns * sizeof (gchar *));
372 memcpy (new_columns, tree_store->column_headers, n_columns * sizeof (GType));
374 g_free (tree_store->column_headers);
377 if (tree_store->sort_list)
378 _gtk_tree_data_list_header_free (tree_store->sort_list);
380 tree_store->sort_list = _gtk_tree_data_list_header_new (n_columns, tree_store->column_headers);
382 tree_store->column_headers = new_columns;
383 tree_store->n_columns = n_columns;
387 * gtk_tree_store_set_column_type:
388 * @tree_store: a #GtkTreeStore
389 * @column: column number
390 * @type: type of the data to be stored in @column
392 * Supported types include: %G_TYPE_UINT, %G_TYPE_INT, %G_TYPE_UCHAR,
393 * %G_TYPE_CHAR, %G_TYPE_BOOLEAN, %G_TYPE_POINTER, %G_TYPE_FLOAT,
394 * %G_TYPE_DOUBLE, %G_TYPE_STRING, %G_TYPE_OBJECT, and %G_TYPE_BOXED, along with
395 * subclasses of those types such as %GDK_TYPE_PIXBUF.
399 gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
403 if (!_gtk_tree_data_list_check_type (type))
405 g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (type));
408 tree_store->column_headers[column] = type;
412 node_free (GNode *node, gpointer data)
415 _gtk_tree_data_list_free (node->data, (GType*)data);
422 gtk_tree_store_finalize (GObject *object)
424 GtkTreeStore *tree_store = GTK_TREE_STORE (object);
426 g_node_traverse (tree_store->root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
427 node_free, tree_store->column_headers);
428 g_node_destroy (tree_store->root);
429 _gtk_tree_data_list_header_free (tree_store->sort_list);
430 g_free (tree_store->column_headers);
432 if (tree_store->default_sort_destroy)
434 GDestroyNotify d = tree_store->default_sort_destroy;
436 tree_store->default_sort_destroy = NULL;
437 d (tree_store->default_sort_data);
438 tree_store->default_sort_data = NULL;
442 G_OBJECT_CLASS (gtk_tree_store_parent_class)->finalize (object);
445 /* fulfill the GtkTreeModel requirements */
446 /* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node. However,
447 * it is not visible to the tree or to the user., and the path "0" refers to the
448 * first child of GtkTreeStore::root.
452 static GtkTreeModelFlags
453 gtk_tree_store_get_flags (GtkTreeModel *tree_model)
455 return GTK_TREE_MODEL_ITERS_PERSIST;
459 gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
461 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
463 tree_store->columns_dirty = TRUE;
465 return tree_store->n_columns;
469 gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
472 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
474 g_return_val_if_fail (index < tree_store->n_columns, G_TYPE_INVALID);
476 tree_store->columns_dirty = TRUE;
478 return tree_store->column_headers[index];
482 gtk_tree_store_get_iter (GtkTreeModel *tree_model,
486 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
491 tree_store->columns_dirty = TRUE;
493 indices = gtk_tree_path_get_indices (path);
494 depth = gtk_tree_path_get_depth (path);
496 g_return_val_if_fail (depth > 0, FALSE);
498 parent.stamp = tree_store->stamp;
499 parent.user_data = tree_store->root;
501 if (!gtk_tree_store_iter_nth_child (tree_model, iter, &parent, indices[0]))
504 for (i = 1; i < depth; i++)
507 if (!gtk_tree_store_iter_nth_child (tree_model, iter, &parent, indices[i]))
515 gtk_tree_store_get_path (GtkTreeModel *tree_model,
518 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
523 g_return_val_if_fail (iter->user_data != NULL, NULL);
524 g_return_val_if_fail (iter->stamp == tree_store->stamp, NULL);
526 validate_tree (tree_store);
528 if (G_NODE (iter->user_data)->parent == NULL &&
529 G_NODE (iter->user_data) == tree_store->root)
530 return gtk_tree_path_new ();
531 g_assert (G_NODE (iter->user_data)->parent != NULL);
533 if (G_NODE (iter->user_data)->parent == G_NODE (tree_store->root))
535 retval = gtk_tree_path_new ();
536 tmp_node = G_NODE (tree_store->root)->children;
540 GtkTreeIter tmp_iter = *iter;
542 tmp_iter.user_data = G_NODE (iter->user_data)->parent;
544 retval = gtk_tree_store_get_path (tree_model, &tmp_iter);
545 tmp_node = G_NODE (iter->user_data)->parent->children;
551 if (tmp_node == NULL)
553 gtk_tree_path_free (retval);
557 for (; tmp_node; tmp_node = tmp_node->next)
559 if (tmp_node == G_NODE (iter->user_data))
564 if (tmp_node == NULL)
566 /* We couldn't find node, meaning it's prolly not ours */
567 /* Perhaps I should do a g_return_if_fail here. */
568 gtk_tree_path_free (retval);
572 gtk_tree_path_append_index (retval, i);
579 gtk_tree_store_get_value (GtkTreeModel *tree_model,
584 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
585 GtkTreeDataList *list;
586 gint tmp_column = column;
588 g_return_if_fail (column < tree_store->n_columns);
589 g_return_if_fail (VALID_ITER (iter, tree_store));
591 list = G_NODE (iter->user_data)->data;
593 while (tmp_column-- > 0 && list)
598 _gtk_tree_data_list_node_to_value (list,
599 tree_store->column_headers[column],
604 /* We want to return an initialized but empty (default) value */
605 g_value_init (value, tree_store->column_headers[column]);
610 gtk_tree_store_iter_next (GtkTreeModel *tree_model,
613 g_return_val_if_fail (iter->user_data != NULL, FALSE);
614 g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, FALSE);
616 if (G_NODE (iter->user_data)->next)
618 iter->user_data = G_NODE (iter->user_data)->next;
626 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
630 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
634 g_return_val_if_fail (VALID_ITER (parent, tree_store), FALSE);
637 children = G_NODE (parent->user_data)->children;
639 children = G_NODE (tree_store->root)->children;
643 iter->stamp = tree_store->stamp;
644 iter->user_data = children;
652 gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
655 g_return_val_if_fail (iter->user_data != NULL, FALSE);
656 g_return_val_if_fail (VALID_ITER (iter, tree_model), FALSE);
658 return G_NODE (iter->user_data)->children != NULL;
662 gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
668 g_return_val_if_fail (iter == NULL || iter->user_data != NULL, 0);
671 node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
673 node = G_NODE (iter->user_data)->children;
685 gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
690 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
694 g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
697 parent_node = tree_store->root;
699 parent_node = parent->user_data;
701 child = g_node_nth_child (parent_node, n);
705 iter->user_data = child;
706 iter->stamp = tree_store->stamp;
714 gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
718 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
721 g_return_val_if_fail (iter != NULL, FALSE);
722 g_return_val_if_fail (VALID_ITER (child, tree_store), FALSE);
724 parent = G_NODE (child->user_data)->parent;
726 g_assert (parent != NULL);
728 if (parent != tree_store->root)
730 iter->user_data = parent;
731 iter->stamp = tree_store->stamp;
739 /* Does not emit a signal */
741 gtk_tree_store_real_set_value (GtkTreeStore *tree_store,
747 GtkTreeDataList *list;
748 GtkTreeDataList *prev;
749 gint old_column = column;
750 GValue real_value = {0, };
751 gboolean converted = FALSE;
752 gboolean retval = FALSE;
754 if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column]))
756 if (! (g_value_type_compatible (G_VALUE_TYPE (value), tree_store->column_headers[column]) &&
757 g_value_type_compatible (tree_store->column_headers[column], G_VALUE_TYPE (value))))
759 g_warning ("%s: Unable to convert from %s to %s\n",
761 g_type_name (G_VALUE_TYPE (value)),
762 g_type_name (tree_store->column_headers[column]));
765 if (!g_value_transform (value, &real_value))
767 g_warning ("%s: Unable to make conversion from %s to %s\n",
769 g_type_name (G_VALUE_TYPE (value)),
770 g_type_name (tree_store->column_headers[column]));
771 g_value_unset (&real_value);
777 prev = list = G_NODE (iter->user_data)->data;
784 _gtk_tree_data_list_value_to_node (list, &real_value);
786 _gtk_tree_data_list_value_to_node (list, value);
789 g_value_unset (&real_value);
790 if (sort && GTK_TREE_STORE_IS_SORTED (tree_store))
791 gtk_tree_store_sort_iter_changed (tree_store, iter, old_column, TRUE);
800 if (G_NODE (iter->user_data)->data == NULL)
802 G_NODE (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
807 list = prev->next = _gtk_tree_data_list_alloc ();
813 list->next = _gtk_tree_data_list_alloc ();
820 _gtk_tree_data_list_value_to_node (list, &real_value);
822 _gtk_tree_data_list_value_to_node (list, value);
826 g_value_unset (&real_value);
828 if (sort && GTK_TREE_STORE_IS_SORTED (tree_store))
829 gtk_tree_store_sort_iter_changed (tree_store, iter, old_column, TRUE);
835 * gtk_tree_store_set_value:
836 * @tree_store: a #GtkTreeStore
837 * @iter: A valid #GtkTreeIter for the row being modified
838 * @column: column number to modify
839 * @value: new value for the cell
841 * Sets the data in the cell specified by @iter and @column.
842 * The type of @value must be convertible to the type of the
847 gtk_tree_store_set_value (GtkTreeStore *tree_store,
852 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
853 g_return_if_fail (VALID_ITER (iter, tree_store));
854 g_return_if_fail (column >= 0 && column < tree_store->n_columns);
855 g_return_if_fail (G_IS_VALUE (value));
857 if (gtk_tree_store_real_set_value (tree_store, iter, column, value, TRUE))
861 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
862 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
863 gtk_tree_path_free (path);
867 static GtkTreeIterCompareFunc
868 gtk_tree_store_get_compare_func (GtkTreeStore *tree_store)
870 GtkTreeIterCompareFunc func = NULL;
872 if (GTK_TREE_STORE_IS_SORTED (tree_store))
874 if (tree_store->sort_column_id != -1)
876 GtkTreeDataSortHeader *header;
877 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
878 tree_store->sort_column_id);
879 g_return_val_if_fail (header != NULL, NULL);
880 g_return_val_if_fail (header->func != NULL, NULL);
885 func = tree_store->default_sort_func;
893 gtk_tree_store_set_vector_internal (GtkTreeStore *tree_store,
895 gboolean *emit_signal,
896 gboolean *maybe_need_sort,
902 GtkTreeIterCompareFunc func = NULL;
904 func = gtk_tree_store_get_compare_func (tree_store);
905 if (func != _gtk_tree_data_list_compare_func)
906 *maybe_need_sort = TRUE;
908 for (i = 0; i < n_values; i++)
910 *emit_signal = gtk_tree_store_real_set_value (tree_store, iter,
911 columns[i], &values[i],
912 FALSE) || *emit_signal;
914 if (func == _gtk_tree_data_list_compare_func &&
915 columns[i] == tree_store->sort_column_id)
916 *maybe_need_sort = TRUE;
921 gtk_tree_store_set_valist_internal (GtkTreeStore *tree_store,
923 gboolean *emit_signal,
924 gboolean *maybe_need_sort,
928 GtkTreeIterCompareFunc func = NULL;
930 column = va_arg (var_args, gint);
932 func = gtk_tree_store_get_compare_func (tree_store);
933 if (func != _gtk_tree_data_list_compare_func)
934 *maybe_need_sort = TRUE;
938 GValue value = { 0, };
941 if (column < 0 || column >= tree_store->n_columns)
943 g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
946 g_value_init (&value, tree_store->column_headers[column]);
948 G_VALUE_COLLECT (&value, var_args, 0, &error);
951 g_warning ("%s: %s", G_STRLOC, error);
954 /* we purposely leak the value here, it might not be
955 * in a sane state if an error condition occoured
960 *emit_signal = gtk_tree_store_real_set_value (tree_store,
964 FALSE) || *emit_signal;
966 if (func == _gtk_tree_data_list_compare_func &&
967 column == tree_store->sort_column_id)
968 *maybe_need_sort = TRUE;
970 g_value_unset (&value);
972 column = va_arg (var_args, gint);
977 * gtk_tree_store_set_valuesv:
978 * @tree_store: A #GtkTreeStore
979 * @iter: A valid #GtkTreeIter for the row being modified
980 * @columns: an array of column numbers
981 * @values: an array of GValues
982 * @n_values: the length of the @columns and @values arrays
984 * A variant of gtk_tree_store_set_valist() which takes
985 * the columns and values as two arrays, instead of varargs. This
986 * function is mainly intended for language bindings or in case
987 * the number of columns to change is not known until run-time.
992 gtk_tree_store_set_valuesv (GtkTreeStore *tree_store,
998 gboolean emit_signal = FALSE;
999 gboolean maybe_need_sort = FALSE;
1001 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1002 g_return_if_fail (VALID_ITER (iter, tree_store));
1004 gtk_tree_store_set_vector_internal (tree_store, iter,
1007 columns, values, n_values);
1009 if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store))
1010 gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, TRUE);
1016 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1017 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
1018 gtk_tree_path_free (path);
1023 * gtk_tree_store_set_valist:
1024 * @tree_store: A #GtkTreeStore
1025 * @iter: A valid #GtkTreeIter for the row being modified
1026 * @var_args: <type>va_list</type> of column/value pairs
1028 * See gtk_tree_store_set(); this version takes a <type>va_list</type> for
1029 * use by language bindings.
1033 gtk_tree_store_set_valist (GtkTreeStore *tree_store,
1037 gboolean emit_signal = FALSE;
1038 gboolean maybe_need_sort = FALSE;
1040 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1041 g_return_if_fail (VALID_ITER (iter, tree_store));
1043 gtk_tree_store_set_valist_internal (tree_store, iter,
1048 if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store))
1049 gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, TRUE);
1055 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1056 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
1057 gtk_tree_path_free (path);
1062 * gtk_tree_store_set:
1063 * @tree_store: A #GtkTreeStore
1064 * @iter: A valid #GtkTreeIter for the row being modified
1065 * @Varargs: pairs of column number and value, terminated with -1
1067 * Sets the value of one or more cells in the row referenced by @iter.
1068 * The variable argument list should contain integer column numbers,
1069 * each column number followed by the value to be set.
1070 * The list is terminated by a -1. For example, to set column 0 with type
1071 * %G_TYPE_STRING to "Foo", you would write
1072 * <literal>gtk_tree_store_set (store, iter, 0, "Foo", -1)</literal>.
1073 * The value will be copied or referenced by the store if appropriate.
1076 gtk_tree_store_set (GtkTreeStore *tree_store,
1082 va_start (var_args, iter);
1083 gtk_tree_store_set_valist (tree_store, iter, var_args);
1088 * gtk_tree_store_remove:
1089 * @tree_store: A #GtkTreeStore
1090 * @iter: A valid #GtkTreeIter
1092 * Removes @iter from @tree_store. After being removed, @iter is set to the
1093 * next valid row at that level, or invalidated if it previously pointed to the
1096 * Return value: %TRUE if @iter is still valid, %FALSE if not.
1099 gtk_tree_store_remove (GtkTreeStore *tree_store,
1103 GtkTreeIter new_iter = {0,};
1107 g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1108 g_return_val_if_fail (VALID_ITER (iter, tree_store), FALSE);
1110 parent = G_NODE (iter->user_data)->parent;
1112 g_assert (parent != NULL);
1113 next_node = G_NODE (iter->user_data)->next;
1115 if (G_NODE (iter->user_data)->data)
1116 g_node_traverse (G_NODE (iter->user_data), G_POST_ORDER, G_TRAVERSE_ALL,
1117 -1, node_free, tree_store->column_headers);
1119 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1120 g_node_destroy (G_NODE (iter->user_data));
1122 gtk_tree_model_row_deleted (GTK_TREE_MODEL (tree_store), path);
1124 if (parent != G_NODE (tree_store->root))
1127 if (parent->children == NULL)
1129 gtk_tree_path_up (path);
1131 new_iter.stamp = tree_store->stamp;
1132 new_iter.user_data = parent;
1133 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &new_iter);
1136 gtk_tree_path_free (path);
1138 /* revalidate iter */
1139 if (next_node != NULL)
1141 iter->stamp = tree_store->stamp;
1142 iter->user_data = next_node;
1148 iter->user_data = NULL;
1155 * gtk_tree_store_insert:
1156 * @tree_store: A #GtkTreeStore
1157 * @iter: An unset #GtkTreeIter to set to the new row
1158 * @parent: A valid #GtkTreeIter, or %NULL
1159 * @position: position to insert the new row
1161 * Creates a new row at @position. If parent is non-%NULL, then the row will be
1162 * made a child of @parent. Otherwise, the row will be created at the toplevel.
1163 * If @position is larger than the number of rows at that level, then the new
1164 * row will be inserted to the end of the list. @iter will be changed to point
1165 * to this new row. The row will be empty after this function is called. To
1166 * fill in values, you need to call gtk_tree_store_set() or
1167 * gtk_tree_store_set_value().
1171 gtk_tree_store_insert (GtkTreeStore *tree_store,
1173 GtkTreeIter *parent,
1180 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1181 g_return_if_fail (iter != NULL);
1183 g_return_if_fail (VALID_ITER (parent, tree_store));
1186 parent_node = parent->user_data;
1188 parent_node = tree_store->root;
1190 tree_store->columns_dirty = TRUE;
1192 new_node = g_node_new (NULL);
1194 iter->stamp = tree_store->stamp;
1195 iter->user_data = new_node;
1196 g_node_insert (parent_node, position, new_node);
1198 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1199 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1201 if (parent_node != tree_store->root)
1203 if (new_node->prev == NULL && new_node->next == NULL)
1205 gtk_tree_path_up (path);
1206 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1210 gtk_tree_path_free (path);
1212 validate_tree ((GtkTreeStore*)tree_store);
1216 * gtk_tree_store_insert_before:
1217 * @tree_store: A #GtkTreeStore
1218 * @iter: An unset #GtkTreeIter to set to the new row
1219 * @parent: A valid #GtkTreeIter, or %NULL
1220 * @sibling: A valid #GtkTreeIter, or %NULL
1222 * Inserts a new row before @sibling. If @sibling is %NULL, then the row will
1223 * be appended to @parent 's children. If @parent and @sibling are %NULL, then
1224 * the row will be appended to the toplevel. If both @sibling and @parent are
1225 * set, then @parent must be the parent of @sibling. When @sibling is set,
1226 * @parent is optional.
1228 * @iter will be changed to point to this new row. The row will be empty after
1229 * this function is called. To fill in values, you need to call
1230 * gtk_tree_store_set() or gtk_tree_store_set_value().
1234 gtk_tree_store_insert_before (GtkTreeStore *tree_store,
1236 GtkTreeIter *parent,
1237 GtkTreeIter *sibling)
1240 GNode *parent_node = NULL;
1243 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1244 g_return_if_fail (iter != NULL);
1246 g_return_if_fail (VALID_ITER (parent, tree_store));
1247 if (sibling != NULL)
1248 g_return_if_fail (VALID_ITER (sibling, tree_store));
1250 if (parent == NULL && sibling == NULL)
1251 parent_node = tree_store->root;
1252 else if (parent == NULL)
1253 parent_node = G_NODE (sibling->user_data)->parent;
1254 else if (sibling == NULL)
1255 parent_node = G_NODE (parent->user_data);
1258 g_return_if_fail (G_NODE (sibling->user_data)->parent == G_NODE (parent->user_data));
1259 parent_node = G_NODE (parent->user_data);
1262 tree_store->columns_dirty = TRUE;
1264 new_node = g_node_new (NULL);
1266 g_node_insert_before (parent_node,
1267 sibling ? G_NODE (sibling->user_data) : NULL,
1270 iter->stamp = tree_store->stamp;
1271 iter->user_data = new_node;
1273 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1274 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1276 if (parent_node != tree_store->root)
1278 if (new_node->prev == NULL && new_node->next == NULL)
1280 GtkTreeIter parent_iter;
1282 parent_iter.stamp = tree_store->stamp;
1283 parent_iter.user_data = parent_node;
1285 gtk_tree_path_up (path);
1286 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &parent_iter);
1290 gtk_tree_path_free (path);
1292 validate_tree (tree_store);
1296 * gtk_tree_store_insert_after:
1297 * @tree_store: A #GtkTreeStore
1298 * @iter: An unset #GtkTreeIter to set to the new row
1299 * @parent: A valid #GtkTreeIter, or %NULL
1300 * @sibling: A valid #GtkTreeIter, or %NULL
1302 * Inserts a new row after @sibling. If @sibling is %NULL, then the row will be
1303 * prepended to @parent 's children. If @parent and @sibling are %NULL, then
1304 * the row will be prepended to the toplevel. If both @sibling and @parent are
1305 * set, then @parent must be the parent of @sibling. When @sibling is set,
1306 * @parent is optional.
1308 * @iter will be changed to point to this new row. The row will be empty after
1309 * this function is called. To fill in values, you need to call
1310 * gtk_tree_store_set() or gtk_tree_store_set_value().
1314 gtk_tree_store_insert_after (GtkTreeStore *tree_store,
1316 GtkTreeIter *parent,
1317 GtkTreeIter *sibling)
1323 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1324 g_return_if_fail (iter != NULL);
1326 g_return_if_fail (VALID_ITER (parent, tree_store));
1327 if (sibling != NULL)
1328 g_return_if_fail (VALID_ITER (sibling, tree_store));
1330 if (parent == NULL && sibling == NULL)
1331 parent_node = tree_store->root;
1332 else if (parent == NULL)
1333 parent_node = G_NODE (sibling->user_data)->parent;
1334 else if (sibling == NULL)
1335 parent_node = G_NODE (parent->user_data);
1338 g_return_if_fail (G_NODE (sibling->user_data)->parent ==
1339 G_NODE (parent->user_data));
1340 parent_node = G_NODE (parent->user_data);
1343 tree_store->columns_dirty = TRUE;
1345 new_node = g_node_new (NULL);
1347 g_node_insert_after (parent_node,
1348 sibling ? G_NODE (sibling->user_data) : NULL,
1351 iter->stamp = tree_store->stamp;
1352 iter->user_data = new_node;
1354 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1355 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1357 if (parent_node != tree_store->root)
1359 if (new_node->prev == NULL && new_node->next == NULL)
1361 GtkTreeIter parent_iter;
1363 parent_iter.stamp = tree_store->stamp;
1364 parent_iter.user_data = parent_node;
1366 gtk_tree_path_up (path);
1367 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &parent_iter);
1371 gtk_tree_path_free (path);
1373 validate_tree (tree_store);
1377 * gtk_tree_store_insert_with_values:
1378 * @tree_store: A #GtkTreeStore
1379 * @iter: An unset #GtkTreeIter to set the new row, or %NULL.
1380 * @parent: A valid #GtkTreeIter, or %NULL
1381 * @position: position to insert the new row
1382 * @Varargs: pairs of column number and value, terminated with -1
1384 * Creates a new row at @position. @iter will be changed to point to this
1385 * new row. If @position is larger than the number of rows on the list, then
1386 * the new row will be appended to the list. The row will be filled with
1387 * the values given to this function.
1390 * <literal>gtk_tree_store_insert_with_values (tree_store, iter, position, ...)</literal>
1391 * has the same effect as calling
1393 * gtk_tree_store_insert (tree_store, iter, position);
1394 * gtk_tree_store_set (tree_store, iter, ...);
1396 * with the different that the former will only emit a row_inserted signal,
1397 * while the latter will emit row_inserted, row_changed and if the tree store
1398 * is sorted, rows_reordered. Since emitting the rows_reordered signal
1399 * repeatedly can affect the performance of the program,
1400 * gtk_tree_store_insert_with_values() should generally be preferred when
1401 * inserting rows in a sorted tree store.
1406 gtk_tree_store_insert_with_values (GtkTreeStore *tree_store,
1408 GtkTreeIter *parent,
1415 GtkTreeIter tmp_iter;
1417 gboolean changed = FALSE;
1418 gboolean maybe_need_sort = FALSE;
1420 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1426 g_return_if_fail (VALID_ITER (parent, tree_store));
1429 parent_node = parent->user_data;
1431 parent_node = tree_store->root;
1433 tree_store->columns_dirty = TRUE;
1435 new_node = g_node_new (NULL);
1437 iter->stamp = tree_store->stamp;
1438 iter->user_data = new_node;
1439 g_node_insert (parent_node, position, new_node);
1441 va_start (var_args, position);
1442 gtk_tree_store_set_valist_internal (tree_store, iter,
1443 &changed, &maybe_need_sort,
1447 if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store))
1448 gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, FALSE);
1450 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1451 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1453 if (parent_node != tree_store->root)
1455 if (new_node->prev == NULL && new_node->next == NULL)
1457 gtk_tree_path_up (path);
1458 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1462 gtk_tree_path_free (path);
1464 validate_tree ((GtkTreeStore *)tree_store);
1468 * gtk_tree_store_insert_with_valuesv:
1469 * @tree_store: A #GtkTreeStore
1470 * @iter: An unset #GtkTreeIter to set the new row, or %NULL.
1471 * @parent: A valid #GtkTreeIter, or %NULL
1472 * @position: position to insert the new row
1473 * @columns: an array of column numbers
1474 * @values: an array of GValues
1475 * @n_values: the length of the @columns and @values arrays
1477 * A variant of gtk_tree_store_insert_with_values() which takes
1478 * the columns and values as two arrays, instead of varargs. This
1479 * function is mainly intended for language bindings.
1484 gtk_tree_store_insert_with_valuesv (GtkTreeStore *tree_store,
1486 GtkTreeIter *parent,
1495 GtkTreeIter tmp_iter;
1496 gboolean changed = FALSE;
1497 gboolean maybe_need_sort = FALSE;
1499 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1505 g_return_if_fail (VALID_ITER (parent, tree_store));
1508 parent_node = parent->user_data;
1510 parent_node = tree_store->root;
1512 tree_store->columns_dirty = TRUE;
1514 new_node = g_node_new (NULL);
1516 iter->stamp = tree_store->stamp;
1517 iter->user_data = new_node;
1518 g_node_insert (parent_node, position, new_node);
1520 gtk_tree_store_set_vector_internal (tree_store, iter,
1521 &changed, &maybe_need_sort,
1522 columns, values, n_values);
1524 if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store))
1525 gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, FALSE);
1527 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1528 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1530 if (parent_node != tree_store->root)
1532 if (new_node->prev == NULL && new_node->next == NULL)
1534 gtk_tree_path_up (path);
1535 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1539 gtk_tree_path_free (path);
1541 validate_tree ((GtkTreeStore *)tree_store);
1545 * gtk_tree_store_prepend:
1546 * @tree_store: A #GtkTreeStore
1547 * @iter: An unset #GtkTreeIter to set to the prepended row
1548 * @parent: A valid #GtkTreeIter, or %NULL
1550 * Prepends a new row to @tree_store. If @parent is non-%NULL, then it will prepend
1551 * the new row before the first child of @parent, otherwise it will prepend a row
1552 * to the top level. @iter will be changed to point to this new row. The row
1553 * will be empty after this function is called. To fill in values, you need to
1554 * call gtk_tree_store_set() or gtk_tree_store_set_value().
1557 gtk_tree_store_prepend (GtkTreeStore *tree_store,
1559 GtkTreeIter *parent)
1563 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1564 g_return_if_fail (iter != NULL);
1566 g_return_if_fail (VALID_ITER (parent, tree_store));
1568 tree_store->columns_dirty = TRUE;
1571 parent_node = tree_store->root;
1573 parent_node = parent->user_data;
1575 if (parent_node->children == NULL)
1579 iter->stamp = tree_store->stamp;
1580 iter->user_data = g_node_new (NULL);
1582 g_node_prepend (parent_node, G_NODE (iter->user_data));
1584 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1585 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1587 if (parent_node != tree_store->root)
1589 gtk_tree_path_up (path);
1590 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1592 gtk_tree_path_free (path);
1596 gtk_tree_store_insert_after (tree_store, iter, parent, NULL);
1599 validate_tree (tree_store);
1603 * gtk_tree_store_append:
1604 * @tree_store: A #GtkTreeStore
1605 * @iter: An unset #GtkTreeIter to set to the appended row
1606 * @parent: A valid #GtkTreeIter, or %NULL
1608 * Appends a new row to @tree_store. If @parent is non-%NULL, then it will append the
1609 * new row after the last child of @parent, otherwise it will append a row to
1610 * the top level. @iter will be changed to point to this new row. The row will
1611 * be empty after this function is called. To fill in values, you need to call
1612 * gtk_tree_store_set() or gtk_tree_store_set_value().
1615 gtk_tree_store_append (GtkTreeStore *tree_store,
1617 GtkTreeIter *parent)
1621 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1622 g_return_if_fail (iter != NULL);
1624 g_return_if_fail (VALID_ITER (parent, tree_store));
1627 parent_node = tree_store->root;
1629 parent_node = parent->user_data;
1631 tree_store->columns_dirty = TRUE;
1633 if (parent_node->children == NULL)
1637 iter->stamp = tree_store->stamp;
1638 iter->user_data = g_node_new (NULL);
1640 g_node_append (parent_node, G_NODE (iter->user_data));
1642 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1643 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1645 if (parent_node != tree_store->root)
1647 gtk_tree_path_up (path);
1648 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1650 gtk_tree_path_free (path);
1654 gtk_tree_store_insert_before (tree_store, iter, parent, NULL);
1657 validate_tree (tree_store);
1661 * gtk_tree_store_is_ancestor:
1662 * @tree_store: A #GtkTreeStore
1663 * @iter: A valid #GtkTreeIter
1664 * @descendant: A valid #GtkTreeIter
1666 * Returns %TRUE if @iter is an ancestor of @descendant. That is, @iter is the
1667 * parent (or grandparent or great-grandparent) of @descendant.
1669 * Return value: %TRUE, if @iter is an ancestor of @descendant
1672 gtk_tree_store_is_ancestor (GtkTreeStore *tree_store,
1674 GtkTreeIter *descendant)
1676 g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1677 g_return_val_if_fail (VALID_ITER (iter, tree_store), FALSE);
1678 g_return_val_if_fail (VALID_ITER (descendant, tree_store), FALSE);
1680 return g_node_is_ancestor (G_NODE (iter->user_data),
1681 G_NODE (descendant->user_data));
1686 * gtk_tree_store_iter_depth:
1687 * @tree_store: A #GtkTreeStore
1688 * @iter: A valid #GtkTreeIter
1690 * Returns the depth of @iter. This will be 0 for anything on the root level, 1
1691 * for anything down a level, etc.
1693 * Return value: The depth of @iter
1696 gtk_tree_store_iter_depth (GtkTreeStore *tree_store,
1699 g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), 0);
1700 g_return_val_if_fail (VALID_ITER (iter, tree_store), 0);
1702 return g_node_depth (G_NODE (iter->user_data)) - 2;
1705 /* simple ripoff from g_node_traverse_post_order */
1707 gtk_tree_store_clear_traverse (GNode *node,
1708 GtkTreeStore *store)
1716 child = node->children;
1719 register GNode *current;
1722 child = current->next;
1723 if (gtk_tree_store_clear_traverse (current, store))
1729 iter.stamp = store->stamp;
1730 iter.user_data = node;
1732 gtk_tree_store_remove (store, &iter);
1735 else if (node->parent)
1737 iter.stamp = store->stamp;
1738 iter.user_data = node;
1740 gtk_tree_store_remove (store, &iter);
1747 gtk_tree_store_increment_stamp (GtkTreeStore *tree_store)
1751 tree_store->stamp++;
1753 while (tree_store->stamp == 0);
1757 * gtk_tree_store_clear:
1758 * @tree_store: a #GtkTreeStore
1760 * Removes all rows from @tree_store
1763 gtk_tree_store_clear (GtkTreeStore *tree_store)
1765 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1767 gtk_tree_store_clear_traverse (tree_store->root, tree_store);
1768 gtk_tree_store_increment_stamp (tree_store);
1772 gtk_tree_store_iter_is_valid_helper (GtkTreeIter *iter,
1781 if (node == iter->user_data)
1785 if (gtk_tree_store_iter_is_valid_helper (iter, node->children))
1796 * gtk_tree_store_iter_is_valid:
1797 * @tree_store: A #GtkTreeStore.
1798 * @iter: A #GtkTreeIter.
1800 * WARNING: This function is slow. Only use it for debugging and/or testing
1803 * Checks if the given iter is a valid iter for this #GtkTreeStore.
1805 * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
1810 gtk_tree_store_iter_is_valid (GtkTreeStore *tree_store,
1813 g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1814 g_return_val_if_fail (iter != NULL, FALSE);
1816 if (!VALID_ITER (iter, tree_store))
1819 return gtk_tree_store_iter_is_valid_helper (iter, tree_store->root);
1825 static gboolean real_gtk_tree_store_row_draggable (GtkTreeDragSource *drag_source,
1832 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1837 if (gtk_tree_store_get_iter (GTK_TREE_MODEL (drag_source),
1841 gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1852 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1854 GtkSelectionData *selection_data)
1856 /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1857 * target, because the default handler does it for us, but
1858 * we do anyway for the convenience of someone maybe overriding the
1862 if (gtk_tree_set_row_drag_data (selection_data,
1863 GTK_TREE_MODEL (drag_source),
1870 /* FIXME handle text targets at least. */
1877 copy_node_data (GtkTreeStore *tree_store,
1878 GtkTreeIter *src_iter,
1879 GtkTreeIter *dest_iter)
1881 GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1882 GtkTreeDataList *copy_head = NULL;
1883 GtkTreeDataList *copy_prev = NULL;
1884 GtkTreeDataList *copy_iter = NULL;
1891 copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1893 if (copy_head == NULL)
1894 copy_head = copy_iter;
1897 copy_prev->next = copy_iter;
1899 copy_prev = copy_iter;
1905 G_NODE (dest_iter->user_data)->data = copy_head;
1907 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1908 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, dest_iter);
1909 gtk_tree_path_free (path);
1913 recursive_node_copy (GtkTreeStore *tree_store,
1914 GtkTreeIter *src_iter,
1915 GtkTreeIter *dest_iter)
1918 GtkTreeModel *model;
1920 model = GTK_TREE_MODEL (tree_store);
1922 copy_node_data (tree_store, src_iter, dest_iter);
1924 if (gtk_tree_store_iter_children (model,
1928 /* Need to create children and recurse. Note our
1929 * dependence on persistent iterators here.
1935 /* Gee, a really slow algorithm... ;-) FIXME */
1936 gtk_tree_store_append (tree_store,
1940 recursive_node_copy (tree_store, &child, ©);
1942 while (gtk_tree_store_iter_next (model, &child));
1947 gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest,
1949 GtkSelectionData *selection_data)
1951 GtkTreeModel *tree_model;
1952 GtkTreeStore *tree_store;
1953 GtkTreeModel *src_model = NULL;
1954 GtkTreePath *src_path = NULL;
1955 gboolean retval = FALSE;
1957 tree_model = GTK_TREE_MODEL (drag_dest);
1958 tree_store = GTK_TREE_STORE (drag_dest);
1960 validate_tree (tree_store);
1962 if (gtk_tree_get_row_drag_data (selection_data,
1965 src_model == tree_model)
1967 /* Copy the given row to a new position */
1968 GtkTreeIter src_iter;
1969 GtkTreeIter dest_iter;
1972 if (!gtk_tree_store_get_iter (src_model,
1979 /* Get the path to insert _after_ (dest is the path to insert _before_) */
1980 prev = gtk_tree_path_copy (dest);
1982 if (!gtk_tree_path_prev (prev))
1984 GtkTreeIter dest_parent;
1985 GtkTreePath *parent;
1986 GtkTreeIter *dest_parent_p;
1988 /* dest was the first spot at the current depth; which means
1989 * we are supposed to prepend.
1992 /* Get the parent, NULL if parent is the root */
1993 dest_parent_p = NULL;
1994 parent = gtk_tree_path_copy (dest);
1995 if (gtk_tree_path_up (parent) &&
1996 gtk_tree_path_get_depth (parent) > 0)
1998 gtk_tree_store_get_iter (tree_model,
2001 dest_parent_p = &dest_parent;
2003 gtk_tree_path_free (parent);
2006 gtk_tree_store_prepend (tree_store,
2014 if (gtk_tree_store_get_iter (tree_model, &dest_iter, prev))
2016 GtkTreeIter tmp_iter = dest_iter;
2018 gtk_tree_store_insert_after (tree_store, &dest_iter, NULL,
2025 gtk_tree_path_free (prev);
2027 /* If we succeeded in creating dest_iter, walk src_iter tree branch,
2028 * duplicating it below dest_iter.
2033 recursive_node_copy (tree_store,
2040 /* FIXME maybe add some data targets eventually, or handle text
2041 * targets in the simple case.
2049 gtk_tree_path_free (src_path);
2055 gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
2056 GtkTreePath *dest_path,
2057 GtkSelectionData *selection_data)
2059 GtkTreeModel *src_model = NULL;
2060 GtkTreePath *src_path = NULL;
2061 GtkTreePath *tmp = NULL;
2062 gboolean retval = FALSE;
2064 /* don't accept drops if the tree has been sorted */
2065 if (GTK_TREE_STORE_IS_SORTED (drag_dest))
2068 if (!gtk_tree_get_row_drag_data (selection_data,
2073 /* can only drag to ourselves */
2074 if (src_model != GTK_TREE_MODEL (drag_dest))
2077 /* Can't drop into ourself. */
2078 if (gtk_tree_path_is_ancestor (src_path,
2082 /* Can't drop if dest_path's parent doesn't exist */
2086 if (gtk_tree_path_get_depth (dest_path) > 1)
2088 tmp = gtk_tree_path_copy (dest_path);
2089 gtk_tree_path_up (tmp);
2091 if (!gtk_tree_store_get_iter (GTK_TREE_MODEL (drag_dest),
2097 /* Can otherwise drop anywhere. */
2103 gtk_tree_path_free (src_path);
2105 gtk_tree_path_free (tmp);
2110 /* Sorting and reordering */
2111 typedef struct _SortTuple
2119 gtk_tree_store_reorder_func (gconstpointer a,
2123 SortTuple *a_reorder;
2124 SortTuple *b_reorder;
2126 a_reorder = (SortTuple *)a;
2127 b_reorder = (SortTuple *)b;
2129 if (a_reorder->offset < b_reorder->offset)
2131 if (a_reorder->offset > b_reorder->offset)
2138 * gtk_tree_store_reorder:
2139 * @tree_store: A #GtkTreeStore.
2140 * @parent: A #GtkTreeIter.
2141 * @new_order: an array of integers mapping the new position of each child
2142 * to its old position before the re-ordering,
2143 * i.e. @new_order<literal>[newpos] = oldpos</literal>.
2145 * Reorders the children of @parent in @tree_store to follow the order
2146 * indicated by @new_order. Note that this function only works with
2152 gtk_tree_store_reorder (GtkTreeStore *tree_store,
2153 GtkTreeIter *parent,
2157 GNode *level, *node;
2159 SortTuple *sort_array;
2161 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
2162 g_return_if_fail (!GTK_TREE_STORE_IS_SORTED (tree_store));
2163 g_return_if_fail (parent == NULL || VALID_ITER (parent, tree_store));
2164 g_return_if_fail (new_order != NULL);
2167 level = G_NODE (tree_store->root)->children;
2169 level = G_NODE (parent->user_data)->children;
2179 /* set up sortarray */
2180 sort_array = g_new (SortTuple, length);
2183 for (i = 0; i < length; i++)
2185 sort_array[new_order[i]].offset = i;
2186 sort_array[i].node = node;
2191 g_qsort_with_data (sort_array,
2194 gtk_tree_store_reorder_func,
2198 for (i = 0; i < length - 1; i++)
2200 sort_array[i].node->next = sort_array[i+1].node;
2201 sort_array[i+1].node->prev = sort_array[i].node;
2204 sort_array[length-1].node->next = NULL;
2205 sort_array[0].node->prev = NULL;
2207 G_NODE (parent->user_data)->children = sort_array[0].node;
2209 G_NODE (tree_store->root)->children = sort_array[0].node;
2213 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), parent);
2215 path = gtk_tree_path_new ();
2216 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store), path,
2218 gtk_tree_path_free (path);
2219 g_free (sort_array);
2223 * gtk_tree_store_swap:
2224 * @tree_store: A #GtkTreeStore.
2225 * @a: A #GtkTreeIter.
2226 * @b: Another #GtkTreeIter.
2228 * Swaps @a and @b in the same level of @tree_store. Note that this function
2229 * only works with unsorted stores.
2234 gtk_tree_store_swap (GtkTreeStore *tree_store,
2238 GNode *tmp, *node_a, *node_b, *parent_node;
2239 GNode *a_prev, *a_next, *b_prev, *b_next;
2240 gint i, a_count, b_count, length, *order;
2241 GtkTreePath *path_a, *path_b;
2244 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
2245 g_return_if_fail (VALID_ITER (a, tree_store));
2246 g_return_if_fail (VALID_ITER (b, tree_store));
2248 node_a = G_NODE (a->user_data);
2249 node_b = G_NODE (b->user_data);
2251 /* basic sanity checking */
2252 if (node_a == node_b)
2255 path_a = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), a);
2256 path_b = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), b);
2258 g_return_if_fail (path_a && path_b);
2260 gtk_tree_path_up (path_a);
2261 gtk_tree_path_up (path_b);
2263 if (gtk_tree_path_get_depth (path_a) == 0
2264 || gtk_tree_path_get_depth (path_b) == 0)
2266 if (gtk_tree_path_get_depth (path_a) != gtk_tree_path_get_depth (path_b))
2268 gtk_tree_path_free (path_a);
2269 gtk_tree_path_free (path_b);
2271 g_warning ("Given children are not in the same level\n");
2274 parent_node = G_NODE (tree_store->root);
2278 if (gtk_tree_path_compare (path_a, path_b))
2280 gtk_tree_path_free (path_a);
2281 gtk_tree_path_free (path_b);
2283 g_warning ("Given children don't have a common parent\n");
2286 gtk_tree_store_get_iter (GTK_TREE_MODEL (tree_store), &parent,
2288 parent_node = G_NODE (parent.user_data);
2290 gtk_tree_path_free (path_b);
2292 /* old links which we have to keep around */
2293 a_prev = node_a->prev;
2294 a_next = node_a->next;
2296 b_prev = node_b->prev;
2297 b_next = node_b->next;
2299 /* fix up links if the nodes are next to eachother */
2300 if (a_prev == node_b)
2302 if (a_next == node_b)
2305 if (b_prev == node_a)
2307 if (b_next == node_a)
2310 /* counting nodes */
2311 tmp = parent_node->children;
2312 i = a_count = b_count = 0;
2325 /* hacking the tree */
2327 parent_node->children = node_b;
2329 a_prev->next = node_b;
2332 a_next->prev = node_b;
2335 parent_node->children = node_a;
2337 b_prev->next = node_a;
2340 b_next->prev = node_a;
2342 node_a->prev = b_prev;
2343 node_a->next = b_next;
2345 node_b->prev = a_prev;
2346 node_b->next = a_next;
2349 order = g_new (gint, length);
2350 for (i = 0; i < length; i++)
2353 else if (i == b_count)
2358 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store), path_a,
2359 parent_node == tree_store->root
2360 ? NULL : &parent, order);
2361 gtk_tree_path_free (path_a);
2365 /* WARNING: this function is *incredibly* fragile. Please smashtest after
2366 * making changes here.
2370 gtk_tree_store_move (GtkTreeStore *tree_store,
2372 GtkTreeIter *position,
2375 GNode *parent, *node, *a, *b, *tmp, *tmp_a, *tmp_b;
2376 gint old_pos, new_pos, length, i, *order;
2377 GtkTreePath *path = NULL, *tmppath, *pos_path = NULL;
2378 GtkTreeIter parent_iter, dst_a, dst_b;
2380 gboolean handle_b = TRUE;
2382 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
2383 g_return_if_fail (!GTK_TREE_STORE_IS_SORTED (tree_store));
2384 g_return_if_fail (VALID_ITER (iter, tree_store));
2386 g_return_if_fail (VALID_ITER (position, tree_store));
2393 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
2394 pos_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store),
2398 * moving the iter before path or "path + 1" doesn't make sense
2400 * moving the iter before path or "path - 1" doesn't make sense
2402 if (!gtk_tree_path_compare (path, pos_path))
2403 goto free_paths_and_out;
2406 gtk_tree_path_next (path);
2408 gtk_tree_path_prev (path);
2410 if (!gtk_tree_path_compare (path, pos_path))
2411 goto free_paths_and_out;
2414 gtk_tree_path_prev (path);
2416 gtk_tree_path_next (path);
2418 if (gtk_tree_path_get_depth (path) != gtk_tree_path_get_depth (pos_path))
2420 g_warning ("Given children are not in the same level\n");
2422 goto free_paths_and_out;
2425 tmppath = gtk_tree_path_copy (pos_path);
2426 gtk_tree_path_up (path);
2427 gtk_tree_path_up (tmppath);
2429 if (gtk_tree_path_get_depth (path) > 0 &&
2430 gtk_tree_path_compare (path, tmppath))
2432 g_warning ("Given children are not in the same level\n");
2434 gtk_tree_path_free (tmppath);
2435 goto free_paths_and_out;
2438 gtk_tree_path_free (tmppath);
2443 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
2444 gtk_tree_path_up (path);
2447 depth = gtk_tree_path_get_depth (path);
2451 gtk_tree_store_get_iter (GTK_TREE_MODEL (tree_store),
2452 &parent_iter, path);
2454 parent = G_NODE (parent_iter.user_data);
2457 parent = G_NODE (tree_store->root);
2459 /* yes, I know that this can be done shorter, but I'm doing it this way
2460 * so the code is also maintainable
2463 if (before && position)
2465 b = G_NODE (position->user_data);
2467 if (gtk_tree_path_get_indices (pos_path)[gtk_tree_path_get_depth (pos_path) - 1] > 0)
2469 gtk_tree_path_prev (pos_path);
2470 if (gtk_tree_store_get_iter (GTK_TREE_MODEL (tree_store),
2472 a = G_NODE (dst_a.user_data);
2475 gtk_tree_path_next (pos_path);
2478 /* if b is NULL, a is NULL too -- we are at the beginning of the list
2479 * yes and we leak memory here ...
2481 g_return_if_fail (b);
2483 else if (before && !position)
2485 /* move before without position is appending */
2492 a = G_NODE (position->user_data);
2498 gtk_tree_path_next (pos_path);
2499 if (gtk_tree_store_get_iter (GTK_TREE_MODEL (tree_store), &dst_b, pos_path))
2500 b = G_NODE (dst_b.user_data);
2503 gtk_tree_path_prev (pos_path);
2507 /* move after without position is prepending */
2509 gtk_tree_store_iter_children (GTK_TREE_MODEL (tree_store), &dst_b,
2512 gtk_tree_store_iter_children (GTK_TREE_MODEL (tree_store), &dst_b,
2515 b = G_NODE (dst_b.user_data);
2518 /* if a is NULL, b is NULL too -- we are at the end of the list
2519 * yes and we leak memory here ...
2522 g_return_if_fail (a);
2525 /* counting nodes */
2526 tmp = parent->children;
2528 length = old_pos = 0;
2531 if (tmp == iter->user_data)
2538 /* remove node from list */
2539 node = G_NODE (iter->user_data);
2544 tmp_a->next = tmp_b;
2546 parent->children = tmp_b;
2549 tmp_b->prev = tmp_a;
2551 /* and reinsert the node */
2560 else if (!a && !before)
2562 tmp = parent->children;
2565 parent->children = node;
2573 else if (!a && before)
2577 node->parent = NULL;
2578 node->next = node->prev = NULL;
2580 /* before with sibling = NULL appends */
2581 g_node_insert_before (parent, NULL, node);
2585 node->parent = NULL;
2586 node->next = node->prev = NULL;
2588 /* after with sibling = NULL prepends */
2589 g_node_insert_after (parent, NULL, node);
2605 else if (!(!a && before)) /* !a && before is completely handled above */
2611 new_pos = gtk_tree_path_get_indices (pos_path)[gtk_tree_path_get_depth (pos_path)-1];
2615 new_pos = gtk_tree_store_iter_n_children (GTK_TREE_MODEL (tree_store),
2618 new_pos = gtk_tree_store_iter_n_children (GTK_TREE_MODEL (tree_store),
2624 if (new_pos > old_pos)
2626 if (before && position)
2631 if (!before && position)
2635 order = g_new (gint, length);
2636 if (new_pos > old_pos)
2638 for (i = 0; i < length; i++)
2641 else if (i >= old_pos && i < new_pos)
2643 else if (i == new_pos)
2650 for (i = 0; i < length; i++)
2653 else if (i > new_pos && i <= old_pos)
2661 tmppath = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store),
2663 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
2664 tmppath, &parent_iter, order);
2668 tmppath = gtk_tree_path_new ();
2669 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
2670 tmppath, NULL, order);
2673 gtk_tree_path_free (tmppath);
2674 gtk_tree_path_free (path);
2676 gtk_tree_path_free (pos_path);
2682 gtk_tree_path_free (path);
2683 gtk_tree_path_free (pos_path);
2687 * gtk_tree_store_move_before:
2688 * @tree_store: A #GtkTreeStore.
2689 * @iter: A #GtkTreeIter.
2690 * @position: A #GtkTreeIter or %NULL.
2692 * Moves @iter in @tree_store to the position before @position. @iter and
2693 * @position should be in the same level. Note that this function only
2694 * works with unsorted stores. If @position is %NULL, @iter will be
2695 * moved to the end of the level.
2700 gtk_tree_store_move_before (GtkTreeStore *tree_store,
2702 GtkTreeIter *position)
2704 gtk_tree_store_move (tree_store, iter, position, TRUE);
2708 * gtk_tree_store_move_after:
2709 * @tree_store: A #GtkTreeStore.
2710 * @iter: A #GtkTreeIter.
2711 * @position: A #GtkTreeIter.
2713 * Moves @iter in @tree_store to the position after @position. @iter and
2714 * @position should be in the same level. Note that this function only
2715 * works with unsorted stores. If @position is %NULL, @iter will be moved
2716 * to the start of the level.
2721 gtk_tree_store_move_after (GtkTreeStore *tree_store,
2723 GtkTreeIter *position)
2725 gtk_tree_store_move (tree_store, iter, position, FALSE);
2730 gtk_tree_store_compare_func (gconstpointer a,
2734 GtkTreeStore *tree_store = user_data;
2737 GtkTreeIterCompareFunc func;
2744 if (tree_store->sort_column_id != -1)
2746 GtkTreeDataSortHeader *header;
2748 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
2749 tree_store->sort_column_id);
2750 g_return_val_if_fail (header != NULL, 0);
2751 g_return_val_if_fail (header->func != NULL, 0);
2753 func = header->func;
2754 data = header->data;
2758 g_return_val_if_fail (tree_store->default_sort_func != NULL, 0);
2759 func = tree_store->default_sort_func;
2760 data = tree_store->default_sort_data;
2763 node_a = ((SortTuple *) a)->node;
2764 node_b = ((SortTuple *) b)->node;
2766 iter_a.stamp = tree_store->stamp;
2767 iter_a.user_data = node_a;
2768 iter_b.stamp = tree_store->stamp;
2769 iter_b.user_data = node_b;
2771 retval = (* func) (GTK_TREE_MODEL (user_data), &iter_a, &iter_b, data);
2773 if (tree_store->order == GTK_SORT_DESCENDING)
2777 else if (retval < 0)
2784 gtk_tree_store_sort_helper (GtkTreeStore *tree_store,
2797 node = parent->children;
2798 if (node == NULL || node->next == NULL)
2800 if (recurse && node && node->children)
2801 gtk_tree_store_sort_helper (tree_store, node, TRUE);
2807 for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
2810 sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), list_length);
2813 for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
2818 tuple.node = tmp_node;
2819 g_array_append_val (sort_array, tuple);
2823 /* Sort the array */
2824 g_array_sort_with_data (sort_array, gtk_tree_store_compare_func, tree_store);
2826 for (i = 0; i < list_length - 1; i++)
2828 g_array_index (sort_array, SortTuple, i).node->next =
2829 g_array_index (sort_array, SortTuple, i + 1).node;
2830 g_array_index (sort_array, SortTuple, i + 1).node->prev =
2831 g_array_index (sort_array, SortTuple, i).node;
2833 g_array_index (sort_array, SortTuple, list_length - 1).node->next = NULL;
2834 g_array_index (sort_array, SortTuple, 0).node->prev = NULL;
2835 parent->children = g_array_index (sort_array, SortTuple, 0).node;
2837 /* Let the world know about our new order */
2838 new_order = g_new (gint, list_length);
2839 for (i = 0; i < list_length; i++)
2840 new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
2842 iter.stamp = tree_store->stamp;
2843 iter.user_data = parent;
2844 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &iter);
2845 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
2846 path, &iter, new_order);
2847 gtk_tree_path_free (path);
2849 g_array_free (sort_array, TRUE);
2853 for (tmp_node = parent->children; tmp_node; tmp_node = tmp_node->next)
2855 if (tmp_node->children)
2856 gtk_tree_store_sort_helper (tree_store, tmp_node, TRUE);
2862 gtk_tree_store_sort (GtkTreeStore *tree_store)
2864 if (!GTK_TREE_STORE_IS_SORTED (tree_store))
2867 if (tree_store->sort_column_id != -1)
2869 GtkTreeDataSortHeader *header = NULL;
2871 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
2872 tree_store->sort_column_id);
2874 /* We want to make sure that we have a function */
2875 g_return_if_fail (header != NULL);
2876 g_return_if_fail (header->func != NULL);
2880 g_return_if_fail (tree_store->default_sort_func != NULL);
2883 gtk_tree_store_sort_helper (tree_store, G_NODE (tree_store->root), TRUE);
2887 gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
2890 gboolean emit_signal)
2895 GtkTreePath *tmp_path;
2896 GtkTreeIter tmp_iter;
2904 GtkTreeIterCompareFunc func;
2907 g_return_if_fail (G_NODE (iter->user_data)->parent != NULL);
2909 tmp_iter.stamp = tree_store->stamp;
2910 if (tree_store->sort_column_id != -1)
2912 GtkTreeDataSortHeader *header;
2913 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
2914 tree_store->sort_column_id);
2915 g_return_if_fail (header != NULL);
2916 g_return_if_fail (header->func != NULL);
2917 func = header->func;
2918 data = header->data;
2922 g_return_if_fail (tree_store->default_sort_func != NULL);
2923 func = tree_store->default_sort_func;
2924 data = tree_store->default_sort_data;
2927 /* If it's the built in function, we don't sort. */
2928 if (func == _gtk_tree_data_list_compare_func &&
2929 tree_store->sort_column_id != column)
2933 node = G_NODE (iter->user_data)->parent->children;
2934 /* First we find the iter, its prev, and its next */
2937 if (node == G_NODE (iter->user_data))
2942 g_assert (node != NULL);
2947 /* Check the common case, where we don't need to sort it moved. */
2950 tmp_iter.user_data = prev;
2951 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
2956 tmp_iter.user_data = next;
2957 cmp_b = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
2960 if (tree_store->order == GTK_SORT_DESCENDING)
2973 if (prev == NULL && cmp_b <= 0)
2975 else if (next == NULL && cmp_a <= 0)
2977 else if (prev != NULL && next != NULL &&
2978 cmp_a <= 0 && cmp_b <= 0)
2981 /* We actually need to sort it */
2982 /* First, remove the old link. */
2987 node->parent->children = next;
2995 /* FIXME: as an optimization, we can potentially start at next */
2997 node = node->parent->children;
2999 tmp_iter.user_data = node;
3000 if (tree_store->order == GTK_SORT_DESCENDING)
3001 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
3003 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
3005 while ((node->next) && (cmp_a > 0))
3010 tmp_iter.user_data = node;
3011 if (tree_store->order == GTK_SORT_DESCENDING)
3012 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
3014 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
3017 if ((!node->next) && (cmp_a > 0))
3020 node->next = G_NODE (iter->user_data);
3021 node->next->prev = node;
3025 prev->next = G_NODE (iter->user_data);
3026 prev->next->prev = prev;
3027 G_NODE (iter->user_data)->next = node;
3028 G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
3032 G_NODE (iter->user_data)->next = G_NODE (iter->user_data)->parent->children;
3033 G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
3034 G_NODE (iter->user_data)->parent->children = G_NODE (iter->user_data);
3040 /* Emit the reordered signal. */
3041 length = g_node_n_children (node->parent);
3042 new_order = g_new (int, length);
3043 if (old_location < new_location)
3044 for (i = 0; i < length; i++)
3046 if (i < old_location ||
3049 else if (i >= old_location &&
3051 new_order[i] = i + 1;
3052 else if (i == new_location)
3053 new_order[i] = old_location;
3056 for (i = 0; i < length; i++)
3058 if (i < new_location ||
3061 else if (i > new_location &&
3063 new_order[i] = i - 1;
3064 else if (i == new_location)
3065 new_order[i] = old_location;
3068 tmp_iter.user_data = node->parent;
3069 tmp_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &tmp_iter);
3071 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
3072 tmp_path, &tmp_iter,
3075 gtk_tree_path_free (tmp_path);
3081 gtk_tree_store_get_sort_column_id (GtkTreeSortable *sortable,
3082 gint *sort_column_id,
3085 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3088 * sort_column_id = tree_store->sort_column_id;
3090 * order = tree_store->order;
3092 if (tree_store->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
3093 tree_store->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
3100 gtk_tree_store_set_sort_column_id (GtkTreeSortable *sortable,
3101 gint sort_column_id,
3104 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3107 if ((tree_store->sort_column_id == sort_column_id) &&
3108 (tree_store->order == order))
3111 if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
3113 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
3115 GtkTreeDataSortHeader *header = NULL;
3117 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
3120 /* We want to make sure that we have a function */
3121 g_return_if_fail (header != NULL);
3122 g_return_if_fail (header->func != NULL);
3126 g_return_if_fail (tree_store->default_sort_func != NULL);
3130 tree_store->sort_column_id = sort_column_id;
3131 tree_store->order = order;
3133 gtk_tree_sortable_sort_column_changed (sortable);
3135 gtk_tree_store_sort (tree_store);
3139 gtk_tree_store_set_sort_func (GtkTreeSortable *sortable,
3140 gint sort_column_id,
3141 GtkTreeIterCompareFunc func,
3143 GDestroyNotify destroy)
3145 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3147 tree_store->sort_list = _gtk_tree_data_list_set_header (tree_store->sort_list,
3149 func, data, destroy);
3151 if (tree_store->sort_column_id == sort_column_id)
3152 gtk_tree_store_sort (tree_store);
3156 gtk_tree_store_set_default_sort_func (GtkTreeSortable *sortable,
3157 GtkTreeIterCompareFunc func,
3159 GDestroyNotify destroy)
3161 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3163 if (tree_store->default_sort_destroy)
3165 GDestroyNotify d = tree_store->default_sort_destroy;
3167 tree_store->default_sort_destroy = NULL;
3168 d (tree_store->default_sort_data);
3171 tree_store->default_sort_func = func;
3172 tree_store->default_sort_data = data;
3173 tree_store->default_sort_destroy = destroy;
3175 if (tree_store->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
3176 gtk_tree_store_sort (tree_store);
3180 gtk_tree_store_has_default_sort_func (GtkTreeSortable *sortable)
3182 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3184 return (tree_store->default_sort_func != NULL);
3188 validate_gnode (GNode* node)
3192 iter = node->children;
3193 while (iter != NULL)
3195 g_assert (iter->parent == node);
3197 g_assert (iter->prev->next == iter);
3198 validate_gnode (iter);
3203 /* GtkBuildable custom tag implementation
3206 * <column type="..."/>
3207 * <column type="..."/>
3211 GtkBuilder *builder;
3214 } GSListSubParserData;
3217 tree_model_start_element (GMarkupParseContext *context,
3218 const gchar *element_name,
3219 const gchar **names,
3220 const gchar **values,
3225 GSListSubParserData *data = (GSListSubParserData*)user_data;
3227 for (i = 0; names[i]; i++)
3229 if (strcmp (names[i], "type") == 0)
3230 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
3235 tree_model_end_element (GMarkupParseContext *context,
3236 const gchar *element_name,
3240 GSListSubParserData *data = (GSListSubParserData*)user_data;
3242 g_assert(data->builder);
3244 if (strcmp (element_name, "columns") == 0)
3251 data = (GSListSubParserData*)user_data;
3252 data->items = g_slist_reverse (data->items);
3253 types = g_new0 (GType, g_slist_length (data->items));
3255 for (l = data->items, i = 0; l; l = l->next, i++)
3257 type = gtk_builder_get_type_from_name (data->builder, l->data);
3258 if (type == G_TYPE_INVALID)
3260 g_warning ("Unknown type %s specified in treemodel %s",
3261 (const gchar*)l->data,
3262 gtk_buildable_get_name (GTK_BUILDABLE (data->object)));
3270 gtk_tree_store_set_column_types (GTK_TREE_STORE (data->object), i, types);
3274 else if (strcmp (element_name, "column") == 0)
3278 static const GMarkupParser tree_model_parser =
3280 tree_model_start_element,
3281 tree_model_end_element
3286 gtk_tree_store_buildable_custom_tag_start (GtkBuildable *buildable,
3287 GtkBuilder *builder,
3289 const gchar *tagname,
3290 GMarkupParser *parser,
3293 GSListSubParserData *parser_data;
3298 if (strcmp (tagname, "columns") == 0)
3300 parser_data = g_slice_new0 (GSListSubParserData);
3301 parser_data->builder = builder;
3302 parser_data->items = NULL;
3303 parser_data->object = G_OBJECT (buildable);
3305 *parser = tree_model_parser;
3306 *data = parser_data;
3314 gtk_tree_store_buildable_custom_finished (GtkBuildable *buildable,
3315 GtkBuilder *builder,
3317 const gchar *tagname,
3320 GSListSubParserData *data;
3322 if (strcmp (tagname, "columns"))
3325 data = (GSListSubParserData*)user_data;
3327 g_slist_free (data->items);
3328 g_slice_free (GSListSubParserData, data);
3331 #define __GTK_TREE_STORE_C__
3332 #include "gtkaliasdef.c"