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 = GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID;
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);
282 gtk_tree_store_set_column_type (retval, i, type);
289 * gtk_tree_store_newv:
290 * @n_columns: number of columns in the tree store
291 * @types: an array of #GType types for the columns, from first to last
293 * Non vararg creation function. Used primarily by language bindings.
295 * Return value: a new #GtkTreeStore
298 gtk_tree_store_newv (gint n_columns,
301 GtkTreeStore *retval;
304 g_return_val_if_fail (n_columns > 0, NULL);
306 retval = g_object_new (GTK_TYPE_TREE_STORE, NULL);
307 gtk_tree_store_set_n_columns (retval, n_columns);
309 for (i = 0; i < n_columns; i++)
311 if (! _gtk_tree_data_list_check_type (types[i]))
313 g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (types[i]));
314 g_object_unref (retval);
317 gtk_tree_store_set_column_type (retval, i, types[i]);
325 * gtk_tree_store_set_column_types:
326 * @tree_store: A #GtkTreeStore
327 * @n_columns: Number of columns for the tree store
328 * @types: An array of #GType types, one for each column
330 * This function is meant primarily for #GObjects that inherit from
331 * #GtkTreeStore, and should only be used when constructing a new
332 * #GtkTreeStore. It will not function after a row has been added,
333 * or a method on the #GtkTreeModel interface is called.
336 gtk_tree_store_set_column_types (GtkTreeStore *tree_store,
342 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
343 g_return_if_fail (tree_store->columns_dirty == 0);
345 gtk_tree_store_set_n_columns (tree_store, n_columns);
346 for (i = 0; i < n_columns; i++)
348 if (! _gtk_tree_data_list_check_type (types[i]))
350 g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (types[i]));
353 gtk_tree_store_set_column_type (tree_store, i, types[i]);
358 gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
363 if (tree_store->n_columns == n_columns)
366 tree_store->column_headers = g_renew (GType, tree_store->column_headers, n_columns);
367 for (i = tree_store->n_columns; i < n_columns; i++)
368 tree_store->column_headers[i] = G_TYPE_INVALID;
369 tree_store->n_columns = n_columns;
371 if (tree_store->sort_list)
372 _gtk_tree_data_list_header_free (tree_store->sort_list);
374 tree_store->sort_list = _gtk_tree_data_list_header_new (n_columns, tree_store->column_headers);
378 * gtk_tree_store_set_column_type:
379 * @tree_store: a #GtkTreeStore
380 * @column: column number
381 * @type: type of the data to be stored in @column
383 * Supported types include: %G_TYPE_UINT, %G_TYPE_INT, %G_TYPE_UCHAR,
384 * %G_TYPE_CHAR, %G_TYPE_BOOLEAN, %G_TYPE_POINTER, %G_TYPE_FLOAT,
385 * %G_TYPE_DOUBLE, %G_TYPE_STRING, %G_TYPE_OBJECT, and %G_TYPE_BOXED, along with
386 * subclasses of those types such as %GDK_TYPE_PIXBUF.
390 gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
394 if (!_gtk_tree_data_list_check_type (type))
396 g_warning ("%s: Invalid type %s\n", G_STRLOC, g_type_name (type));
399 tree_store->column_headers[column] = type;
403 node_free (GNode *node, gpointer data)
406 _gtk_tree_data_list_free (node->data, (GType*)data);
413 gtk_tree_store_finalize (GObject *object)
415 GtkTreeStore *tree_store = GTK_TREE_STORE (object);
417 g_node_traverse (tree_store->root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
418 node_free, tree_store->column_headers);
419 g_node_destroy (tree_store->root);
420 _gtk_tree_data_list_header_free (tree_store->sort_list);
421 g_free (tree_store->column_headers);
423 if (tree_store->default_sort_destroy)
425 GDestroyNotify d = tree_store->default_sort_destroy;
427 tree_store->default_sort_destroy = NULL;
428 d (tree_store->default_sort_data);
429 tree_store->default_sort_data = NULL;
433 G_OBJECT_CLASS (gtk_tree_store_parent_class)->finalize (object);
436 /* fulfill the GtkTreeModel requirements */
437 /* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node. However,
438 * it is not visible to the tree or to the user., and the path "0" refers to the
439 * first child of GtkTreeStore::root.
443 static GtkTreeModelFlags
444 gtk_tree_store_get_flags (GtkTreeModel *tree_model)
446 return GTK_TREE_MODEL_ITERS_PERSIST;
450 gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
452 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
454 tree_store->columns_dirty = TRUE;
456 return tree_store->n_columns;
460 gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
463 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
465 g_return_val_if_fail (index < tree_store->n_columns, G_TYPE_INVALID);
467 tree_store->columns_dirty = TRUE;
469 return tree_store->column_headers[index];
473 gtk_tree_store_get_iter (GtkTreeModel *tree_model,
477 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
482 tree_store->columns_dirty = TRUE;
484 indices = gtk_tree_path_get_indices (path);
485 depth = gtk_tree_path_get_depth (path);
487 g_return_val_if_fail (depth > 0, FALSE);
489 parent.stamp = tree_store->stamp;
490 parent.user_data = tree_store->root;
492 if (!gtk_tree_store_iter_nth_child (tree_model, iter, &parent, indices[0]))
495 for (i = 1; i < depth; i++)
498 if (!gtk_tree_store_iter_nth_child (tree_model, iter, &parent, indices[i]))
506 gtk_tree_store_get_path (GtkTreeModel *tree_model,
509 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
514 g_return_val_if_fail (iter->user_data != NULL, NULL);
515 g_return_val_if_fail (iter->stamp == tree_store->stamp, NULL);
517 validate_tree (tree_store);
519 if (G_NODE (iter->user_data)->parent == NULL &&
520 G_NODE (iter->user_data) == tree_store->root)
521 return gtk_tree_path_new ();
522 g_assert (G_NODE (iter->user_data)->parent != NULL);
524 if (G_NODE (iter->user_data)->parent == G_NODE (tree_store->root))
526 retval = gtk_tree_path_new ();
527 tmp_node = G_NODE (tree_store->root)->children;
531 GtkTreeIter tmp_iter = *iter;
533 tmp_iter.user_data = G_NODE (iter->user_data)->parent;
535 retval = gtk_tree_store_get_path (tree_model, &tmp_iter);
536 tmp_node = G_NODE (iter->user_data)->parent->children;
542 if (tmp_node == NULL)
544 gtk_tree_path_free (retval);
548 for (; tmp_node; tmp_node = tmp_node->next)
550 if (tmp_node == G_NODE (iter->user_data))
555 if (tmp_node == NULL)
557 /* We couldn't find node, meaning it's prolly not ours */
558 /* Perhaps I should do a g_return_if_fail here. */
559 gtk_tree_path_free (retval);
563 gtk_tree_path_append_index (retval, i);
570 gtk_tree_store_get_value (GtkTreeModel *tree_model,
575 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
576 GtkTreeDataList *list;
577 gint tmp_column = column;
579 g_return_if_fail (column < tree_store->n_columns);
580 g_return_if_fail (VALID_ITER (iter, tree_store));
582 list = G_NODE (iter->user_data)->data;
584 while (tmp_column-- > 0 && list)
589 _gtk_tree_data_list_node_to_value (list,
590 tree_store->column_headers[column],
595 /* We want to return an initialized but empty (default) value */
596 g_value_init (value, tree_store->column_headers[column]);
601 gtk_tree_store_iter_next (GtkTreeModel *tree_model,
604 g_return_val_if_fail (iter->user_data != NULL, FALSE);
605 g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, FALSE);
607 if (G_NODE (iter->user_data)->next)
609 iter->user_data = G_NODE (iter->user_data)->next;
620 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
624 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
628 g_return_val_if_fail (VALID_ITER (parent, tree_store), FALSE);
631 children = G_NODE (parent->user_data)->children;
633 children = G_NODE (tree_store->root)->children;
637 iter->stamp = tree_store->stamp;
638 iter->user_data = children;
649 gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
652 g_return_val_if_fail (iter->user_data != NULL, FALSE);
653 g_return_val_if_fail (VALID_ITER (iter, tree_model), FALSE);
655 return G_NODE (iter->user_data)->children != NULL;
659 gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
665 g_return_val_if_fail (iter == NULL || iter->user_data != NULL, 0);
668 node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
670 node = G_NODE (iter->user_data)->children;
682 gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
687 GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
691 g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
694 parent_node = tree_store->root;
696 parent_node = parent->user_data;
698 child = g_node_nth_child (parent_node, n);
702 iter->user_data = child;
703 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;
742 /* Does not emit a signal */
744 gtk_tree_store_real_set_value (GtkTreeStore *tree_store,
750 GtkTreeDataList *list;
751 GtkTreeDataList *prev;
752 gint old_column = column;
753 GValue real_value = {0, };
754 gboolean converted = FALSE;
755 gboolean retval = FALSE;
757 if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column]))
759 if (! (g_value_type_compatible (G_VALUE_TYPE (value), tree_store->column_headers[column]) &&
760 g_value_type_compatible (tree_store->column_headers[column], G_VALUE_TYPE (value))))
762 g_warning ("%s: Unable to convert from %s to %s\n",
764 g_type_name (G_VALUE_TYPE (value)),
765 g_type_name (tree_store->column_headers[column]));
768 if (!g_value_transform (value, &real_value))
770 g_warning ("%s: Unable to make conversion from %s to %s\n",
772 g_type_name (G_VALUE_TYPE (value)),
773 g_type_name (tree_store->column_headers[column]));
774 g_value_unset (&real_value);
780 prev = list = G_NODE (iter->user_data)->data;
787 _gtk_tree_data_list_value_to_node (list, &real_value);
789 _gtk_tree_data_list_value_to_node (list, value);
792 g_value_unset (&real_value);
793 if (sort && GTK_TREE_STORE_IS_SORTED (tree_store))
794 gtk_tree_store_sort_iter_changed (tree_store, iter, old_column, TRUE);
803 if (G_NODE (iter->user_data)->data == NULL)
805 G_NODE (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
810 list = prev->next = _gtk_tree_data_list_alloc ();
816 list->next = _gtk_tree_data_list_alloc ();
823 _gtk_tree_data_list_value_to_node (list, &real_value);
825 _gtk_tree_data_list_value_to_node (list, value);
829 g_value_unset (&real_value);
831 if (sort && GTK_TREE_STORE_IS_SORTED (tree_store))
832 gtk_tree_store_sort_iter_changed (tree_store, iter, old_column, TRUE);
838 * gtk_tree_store_set_value:
839 * @tree_store: a #GtkTreeStore
840 * @iter: A valid #GtkTreeIter for the row being modified
841 * @column: column number to modify
842 * @value: new value for the cell
844 * Sets the data in the cell specified by @iter and @column.
845 * The type of @value must be convertible to the type of the
850 gtk_tree_store_set_value (GtkTreeStore *tree_store,
855 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
856 g_return_if_fail (VALID_ITER (iter, tree_store));
857 g_return_if_fail (column >= 0 && column < tree_store->n_columns);
858 g_return_if_fail (G_IS_VALUE (value));
860 if (gtk_tree_store_real_set_value (tree_store, iter, column, value, TRUE))
864 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
865 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
866 gtk_tree_path_free (path);
870 static GtkTreeIterCompareFunc
871 gtk_tree_store_get_compare_func (GtkTreeStore *tree_store)
873 GtkTreeIterCompareFunc func = NULL;
875 if (GTK_TREE_STORE_IS_SORTED (tree_store))
877 if (tree_store->sort_column_id != -1)
879 GtkTreeDataSortHeader *header;
880 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
881 tree_store->sort_column_id);
882 g_return_val_if_fail (header != NULL, NULL);
883 g_return_val_if_fail (header->func != NULL, NULL);
888 func = tree_store->default_sort_func;
896 gtk_tree_store_set_vector_internal (GtkTreeStore *tree_store,
898 gboolean *emit_signal,
899 gboolean *maybe_need_sort,
905 GtkTreeIterCompareFunc func = NULL;
907 func = gtk_tree_store_get_compare_func (tree_store);
908 if (func != _gtk_tree_data_list_compare_func)
909 *maybe_need_sort = TRUE;
911 for (i = 0; i < n_values; i++)
913 *emit_signal = gtk_tree_store_real_set_value (tree_store, iter,
914 columns[i], &values[i],
915 FALSE) || *emit_signal;
917 if (func == _gtk_tree_data_list_compare_func &&
918 columns[i] == tree_store->sort_column_id)
919 *maybe_need_sort = TRUE;
924 gtk_tree_store_set_valist_internal (GtkTreeStore *tree_store,
926 gboolean *emit_signal,
927 gboolean *maybe_need_sort,
931 GtkTreeIterCompareFunc func = NULL;
933 column = va_arg (var_args, gint);
935 func = gtk_tree_store_get_compare_func (tree_store);
936 if (func != _gtk_tree_data_list_compare_func)
937 *maybe_need_sort = TRUE;
941 GValue value = { 0, };
944 if (column < 0 || column >= tree_store->n_columns)
946 g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
949 g_value_init (&value, tree_store->column_headers[column]);
951 G_VALUE_COLLECT (&value, var_args, 0, &error);
954 g_warning ("%s: %s", G_STRLOC, error);
957 /* we purposely leak the value here, it might not be
958 * in a sane state if an error condition occoured
963 *emit_signal = gtk_tree_store_real_set_value (tree_store,
967 FALSE) || *emit_signal;
969 if (func == _gtk_tree_data_list_compare_func &&
970 column == tree_store->sort_column_id)
971 *maybe_need_sort = TRUE;
973 g_value_unset (&value);
975 column = va_arg (var_args, gint);
980 * gtk_tree_store_set_valuesv:
981 * @tree_store: A #GtkTreeStore
982 * @iter: A valid #GtkTreeIter for the row being modified
983 * @columns: an array of column numbers
984 * @values: an array of GValues
985 * @n_values: the length of the @columns and @values arrays
987 * A variant of gtk_tree_store_set_valist() which takes
988 * the columns and values as two arrays, instead of varargs. This
989 * function is mainly intended for language bindings or in case
990 * the number of columns to change is not known until run-time.
995 gtk_tree_store_set_valuesv (GtkTreeStore *tree_store,
1001 gboolean emit_signal = FALSE;
1002 gboolean maybe_need_sort = FALSE;
1004 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1005 g_return_if_fail (VALID_ITER (iter, tree_store));
1007 gtk_tree_store_set_vector_internal (tree_store, iter,
1010 columns, values, n_values);
1012 if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store))
1013 gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, TRUE);
1019 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1020 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
1021 gtk_tree_path_free (path);
1026 * gtk_tree_store_set_valist:
1027 * @tree_store: A #GtkTreeStore
1028 * @iter: A valid #GtkTreeIter for the row being modified
1029 * @var_args: <type>va_list</type> of column/value pairs
1031 * See gtk_tree_store_set(); this version takes a <type>va_list</type> for
1032 * use by language bindings.
1036 gtk_tree_store_set_valist (GtkTreeStore *tree_store,
1040 gboolean emit_signal = FALSE;
1041 gboolean maybe_need_sort = FALSE;
1043 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1044 g_return_if_fail (VALID_ITER (iter, tree_store));
1046 gtk_tree_store_set_valist_internal (tree_store, iter,
1051 if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store))
1052 gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, TRUE);
1058 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1059 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, iter);
1060 gtk_tree_path_free (path);
1065 * gtk_tree_store_set:
1066 * @tree_store: A #GtkTreeStore
1067 * @iter: A valid #GtkTreeIter for the row being modified
1068 * @Varargs: pairs of column number and value, terminated with -1
1070 * Sets the value of one or more cells in the row referenced by @iter.
1071 * The variable argument list should contain integer column numbers,
1072 * each column number followed by the value to be set.
1073 * The list is terminated by a -1. For example, to set column 0 with type
1074 * %G_TYPE_STRING to "Foo", you would write
1075 * <literal>gtk_tree_store_set (store, iter, 0, "Foo", -1)</literal>.
1076 * The value will be copied or referenced by the store if appropriate.
1079 gtk_tree_store_set (GtkTreeStore *tree_store,
1085 va_start (var_args, iter);
1086 gtk_tree_store_set_valist (tree_store, iter, var_args);
1091 * gtk_tree_store_remove:
1092 * @tree_store: A #GtkTreeStore
1093 * @iter: A valid #GtkTreeIter
1095 * Removes @iter from @tree_store. After being removed, @iter is set to the
1096 * next valid row at that level, or invalidated if it previously pointed to the
1099 * Return value: %TRUE if @iter is still valid, %FALSE if not.
1102 gtk_tree_store_remove (GtkTreeStore *tree_store,
1106 GtkTreeIter new_iter = {0,};
1110 g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1111 g_return_val_if_fail (VALID_ITER (iter, tree_store), FALSE);
1113 parent = G_NODE (iter->user_data)->parent;
1115 g_assert (parent != NULL);
1116 next_node = G_NODE (iter->user_data)->next;
1118 if (G_NODE (iter->user_data)->data)
1119 g_node_traverse (G_NODE (iter->user_data), G_POST_ORDER, G_TRAVERSE_ALL,
1120 -1, node_free, tree_store->column_headers);
1122 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1123 g_node_destroy (G_NODE (iter->user_data));
1125 gtk_tree_model_row_deleted (GTK_TREE_MODEL (tree_store), path);
1127 if (parent != G_NODE (tree_store->root))
1130 if (parent->children == NULL)
1132 gtk_tree_path_up (path);
1134 new_iter.stamp = tree_store->stamp;
1135 new_iter.user_data = parent;
1136 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &new_iter);
1139 gtk_tree_path_free (path);
1141 /* revalidate iter */
1142 if (next_node != NULL)
1144 iter->stamp = tree_store->stamp;
1145 iter->user_data = next_node;
1151 iter->user_data = NULL;
1158 * gtk_tree_store_insert:
1159 * @tree_store: A #GtkTreeStore
1160 * @iter: An unset #GtkTreeIter to set to the new row
1161 * @parent: A valid #GtkTreeIter, or %NULL
1162 * @position: position to insert the new row
1164 * Creates a new row at @position. If parent is non-%NULL, then the row will be
1165 * made a child of @parent. Otherwise, the row will be created at the toplevel.
1166 * If @position is larger than the number of rows at that level, then the new
1167 * row will be inserted to the end of the list. @iter will be changed to point
1168 * to this new row. The row will be empty after this function is called. To
1169 * fill in values, you need to call gtk_tree_store_set() or
1170 * gtk_tree_store_set_value().
1174 gtk_tree_store_insert (GtkTreeStore *tree_store,
1176 GtkTreeIter *parent,
1183 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1184 g_return_if_fail (iter != NULL);
1186 g_return_if_fail (VALID_ITER (parent, tree_store));
1189 parent_node = parent->user_data;
1191 parent_node = tree_store->root;
1193 tree_store->columns_dirty = TRUE;
1195 new_node = g_node_new (NULL);
1197 iter->stamp = tree_store->stamp;
1198 iter->user_data = new_node;
1199 g_node_insert (parent_node, position, new_node);
1201 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1202 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1204 if (parent_node != tree_store->root)
1206 if (new_node->prev == NULL && new_node->next == NULL)
1208 gtk_tree_path_up (path);
1209 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1213 gtk_tree_path_free (path);
1215 validate_tree ((GtkTreeStore*)tree_store);
1219 * gtk_tree_store_insert_before:
1220 * @tree_store: A #GtkTreeStore
1221 * @iter: An unset #GtkTreeIter to set to the new row
1222 * @parent: A valid #GtkTreeIter, or %NULL
1223 * @sibling: A valid #GtkTreeIter, or %NULL
1225 * Inserts a new row before @sibling. If @sibling is %NULL, then the row will
1226 * be appended to @parent 's children. If @parent and @sibling are %NULL, then
1227 * the row will be appended to the toplevel. If both @sibling and @parent are
1228 * set, then @parent must be the parent of @sibling. When @sibling is set,
1229 * @parent is optional.
1231 * @iter will be changed to point to this new row. The row will be empty after
1232 * this function is called. To fill in values, you need to call
1233 * gtk_tree_store_set() or gtk_tree_store_set_value().
1237 gtk_tree_store_insert_before (GtkTreeStore *tree_store,
1239 GtkTreeIter *parent,
1240 GtkTreeIter *sibling)
1243 GNode *parent_node = NULL;
1246 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1247 g_return_if_fail (iter != NULL);
1249 g_return_if_fail (VALID_ITER (parent, tree_store));
1250 if (sibling != NULL)
1251 g_return_if_fail (VALID_ITER (sibling, tree_store));
1253 if (parent == NULL && sibling == NULL)
1254 parent_node = tree_store->root;
1255 else if (parent == NULL)
1256 parent_node = G_NODE (sibling->user_data)->parent;
1257 else if (sibling == NULL)
1258 parent_node = G_NODE (parent->user_data);
1261 g_return_if_fail (G_NODE (sibling->user_data)->parent == G_NODE (parent->user_data));
1262 parent_node = G_NODE (parent->user_data);
1265 tree_store->columns_dirty = TRUE;
1267 new_node = g_node_new (NULL);
1269 g_node_insert_before (parent_node,
1270 sibling ? G_NODE (sibling->user_data) : NULL,
1273 iter->stamp = tree_store->stamp;
1274 iter->user_data = new_node;
1276 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1277 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1279 if (parent_node != tree_store->root)
1281 if (new_node->prev == NULL && new_node->next == NULL)
1283 GtkTreeIter parent_iter;
1285 parent_iter.stamp = tree_store->stamp;
1286 parent_iter.user_data = parent_node;
1288 gtk_tree_path_up (path);
1289 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &parent_iter);
1293 gtk_tree_path_free (path);
1295 validate_tree (tree_store);
1299 * gtk_tree_store_insert_after:
1300 * @tree_store: A #GtkTreeStore
1301 * @iter: An unset #GtkTreeIter to set to the new row
1302 * @parent: A valid #GtkTreeIter, or %NULL
1303 * @sibling: A valid #GtkTreeIter, or %NULL
1305 * Inserts a new row after @sibling. If @sibling is %NULL, then the row will be
1306 * prepended to @parent 's children. If @parent and @sibling are %NULL, then
1307 * the row will be prepended to the toplevel. If both @sibling and @parent are
1308 * set, then @parent must be the parent of @sibling. When @sibling is set,
1309 * @parent is optional.
1311 * @iter will be changed to point to this new row. The row will be empty after
1312 * this function is called. To fill in values, you need to call
1313 * gtk_tree_store_set() or gtk_tree_store_set_value().
1317 gtk_tree_store_insert_after (GtkTreeStore *tree_store,
1319 GtkTreeIter *parent,
1320 GtkTreeIter *sibling)
1326 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1327 g_return_if_fail (iter != NULL);
1329 g_return_if_fail (VALID_ITER (parent, tree_store));
1330 if (sibling != NULL)
1331 g_return_if_fail (VALID_ITER (sibling, tree_store));
1333 if (parent == NULL && sibling == NULL)
1334 parent_node = tree_store->root;
1335 else if (parent == NULL)
1336 parent_node = G_NODE (sibling->user_data)->parent;
1337 else if (sibling == NULL)
1338 parent_node = G_NODE (parent->user_data);
1341 g_return_if_fail (G_NODE (sibling->user_data)->parent ==
1342 G_NODE (parent->user_data));
1343 parent_node = G_NODE (parent->user_data);
1346 tree_store->columns_dirty = TRUE;
1348 new_node = g_node_new (NULL);
1350 g_node_insert_after (parent_node,
1351 sibling ? G_NODE (sibling->user_data) : NULL,
1354 iter->stamp = tree_store->stamp;
1355 iter->user_data = new_node;
1357 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1358 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1360 if (parent_node != tree_store->root)
1362 if (new_node->prev == NULL && new_node->next == NULL)
1364 GtkTreeIter parent_iter;
1366 parent_iter.stamp = tree_store->stamp;
1367 parent_iter.user_data = parent_node;
1369 gtk_tree_path_up (path);
1370 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, &parent_iter);
1374 gtk_tree_path_free (path);
1376 validate_tree (tree_store);
1380 * gtk_tree_store_insert_with_values:
1381 * @tree_store: A #GtkTreeStore
1382 * @iter: An unset #GtkTreeIter to set the new row, or %NULL.
1383 * @parent: A valid #GtkTreeIter, or %NULL
1384 * @position: position to insert the new row
1385 * @Varargs: pairs of column number and value, terminated with -1
1387 * Creates a new row at @position. @iter will be changed to point to this
1388 * new row. If @position is larger than the number of rows on the list, then
1389 * the new row will be appended to the list. The row will be filled with
1390 * the values given to this function.
1393 * <literal>gtk_tree_store_insert_with_values (tree_store, iter, position, ...)</literal>
1394 * has the same effect as calling
1396 * gtk_tree_store_insert (tree_store, iter, position);
1397 * gtk_tree_store_set (tree_store, iter, ...);
1399 * with the different that the former will only emit a row_inserted signal,
1400 * while the latter will emit row_inserted, row_changed and if the tree store
1401 * is sorted, rows_reordered. Since emitting the rows_reordered signal
1402 * repeatedly can affect the performance of the program,
1403 * gtk_tree_store_insert_with_values() should generally be preferred when
1404 * inserting rows in a sorted tree store.
1409 gtk_tree_store_insert_with_values (GtkTreeStore *tree_store,
1411 GtkTreeIter *parent,
1418 GtkTreeIter tmp_iter;
1420 gboolean changed = FALSE;
1421 gboolean maybe_need_sort = FALSE;
1423 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1429 g_return_if_fail (VALID_ITER (parent, tree_store));
1432 parent_node = parent->user_data;
1434 parent_node = tree_store->root;
1436 tree_store->columns_dirty = TRUE;
1438 new_node = g_node_new (NULL);
1440 iter->stamp = tree_store->stamp;
1441 iter->user_data = new_node;
1442 g_node_insert (parent_node, position, new_node);
1444 va_start (var_args, position);
1445 gtk_tree_store_set_valist_internal (tree_store, iter,
1446 &changed, &maybe_need_sort,
1450 if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store))
1451 gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, FALSE);
1453 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1454 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1456 if (parent_node != tree_store->root)
1458 if (new_node->prev == NULL && new_node->next == NULL)
1460 gtk_tree_path_up (path);
1461 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1465 gtk_tree_path_free (path);
1467 validate_tree ((GtkTreeStore *)tree_store);
1471 * gtk_tree_store_insert_with_valuesv:
1472 * @tree_store: A #GtkTreeStore
1473 * @iter: An unset #GtkTreeIter to set the new row, or %NULL.
1474 * @parent: A valid #GtkTreeIter, or %NULL
1475 * @position: position to insert the new row
1476 * @columns: an array of column numbers
1477 * @values: an array of GValues
1478 * @n_values: the length of the @columns and @values arrays
1480 * A variant of gtk_tree_store_insert_with_values() which takes
1481 * the columns and values as two arrays, instead of varargs. This
1482 * function is mainly intended for language bindings.
1487 gtk_tree_store_insert_with_valuesv (GtkTreeStore *tree_store,
1489 GtkTreeIter *parent,
1498 GtkTreeIter tmp_iter;
1499 gboolean changed = FALSE;
1500 gboolean maybe_need_sort = FALSE;
1502 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1508 g_return_if_fail (VALID_ITER (parent, tree_store));
1511 parent_node = parent->user_data;
1513 parent_node = tree_store->root;
1515 tree_store->columns_dirty = TRUE;
1517 new_node = g_node_new (NULL);
1519 iter->stamp = tree_store->stamp;
1520 iter->user_data = new_node;
1521 g_node_insert (parent_node, position, new_node);
1523 gtk_tree_store_set_vector_internal (tree_store, iter,
1524 &changed, &maybe_need_sort,
1525 columns, values, n_values);
1527 if (maybe_need_sort && GTK_TREE_STORE_IS_SORTED (tree_store))
1528 gtk_tree_store_sort_iter_changed (tree_store, iter, tree_store->sort_column_id, FALSE);
1530 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1531 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1533 if (parent_node != tree_store->root)
1535 if (new_node->prev == NULL && new_node->next == NULL)
1537 gtk_tree_path_up (path);
1538 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1542 gtk_tree_path_free (path);
1544 validate_tree ((GtkTreeStore *)tree_store);
1548 * gtk_tree_store_prepend:
1549 * @tree_store: A #GtkTreeStore
1550 * @iter: An unset #GtkTreeIter to set to the prepended row
1551 * @parent: A valid #GtkTreeIter, or %NULL
1553 * Prepends a new row to @tree_store. If @parent is non-%NULL, then it will prepend
1554 * the new row before the first child of @parent, otherwise it will prepend a row
1555 * to the top level. @iter will be changed to point to this new row. The row
1556 * will be empty after this function is called. To fill in values, you need to
1557 * call gtk_tree_store_set() or gtk_tree_store_set_value().
1560 gtk_tree_store_prepend (GtkTreeStore *tree_store,
1562 GtkTreeIter *parent)
1566 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1567 g_return_if_fail (iter != NULL);
1569 g_return_if_fail (VALID_ITER (parent, tree_store));
1571 tree_store->columns_dirty = TRUE;
1574 parent_node = tree_store->root;
1576 parent_node = parent->user_data;
1578 if (parent_node->children == NULL)
1582 iter->stamp = tree_store->stamp;
1583 iter->user_data = g_node_new (NULL);
1585 g_node_prepend (parent_node, G_NODE (iter->user_data));
1587 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1588 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1590 if (parent_node != tree_store->root)
1592 gtk_tree_path_up (path);
1593 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1595 gtk_tree_path_free (path);
1599 gtk_tree_store_insert_after (tree_store, iter, parent, NULL);
1602 validate_tree (tree_store);
1606 * gtk_tree_store_append:
1607 * @tree_store: A #GtkTreeStore
1608 * @iter: An unset #GtkTreeIter to set to the appended row
1609 * @parent: A valid #GtkTreeIter, or %NULL
1611 * Appends a new row to @tree_store. If @parent is non-%NULL, then it will append the
1612 * new row after the last child of @parent, otherwise it will append a row to
1613 * the top level. @iter will be changed to point to this new row. The row will
1614 * be empty after this function is called. To fill in values, you need to call
1615 * gtk_tree_store_set() or gtk_tree_store_set_value().
1618 gtk_tree_store_append (GtkTreeStore *tree_store,
1620 GtkTreeIter *parent)
1624 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1625 g_return_if_fail (iter != NULL);
1627 g_return_if_fail (VALID_ITER (parent, tree_store));
1630 parent_node = tree_store->root;
1632 parent_node = parent->user_data;
1634 tree_store->columns_dirty = TRUE;
1636 if (parent_node->children == NULL)
1640 iter->stamp = tree_store->stamp;
1641 iter->user_data = g_node_new (NULL);
1643 g_node_append (parent_node, G_NODE (iter->user_data));
1645 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
1646 gtk_tree_model_row_inserted (GTK_TREE_MODEL (tree_store), path, iter);
1648 if (parent_node != tree_store->root)
1650 gtk_tree_path_up (path);
1651 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (tree_store), path, parent);
1653 gtk_tree_path_free (path);
1657 gtk_tree_store_insert_before (tree_store, iter, parent, NULL);
1660 validate_tree (tree_store);
1664 * gtk_tree_store_is_ancestor:
1665 * @tree_store: A #GtkTreeStore
1666 * @iter: A valid #GtkTreeIter
1667 * @descendant: A valid #GtkTreeIter
1669 * Returns %TRUE if @iter is an ancestor of @descendant. That is, @iter is the
1670 * parent (or grandparent or great-grandparent) of @descendant.
1672 * Return value: %TRUE, if @iter is an ancestor of @descendant
1675 gtk_tree_store_is_ancestor (GtkTreeStore *tree_store,
1677 GtkTreeIter *descendant)
1679 g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1680 g_return_val_if_fail (VALID_ITER (iter, tree_store), FALSE);
1681 g_return_val_if_fail (VALID_ITER (descendant, tree_store), FALSE);
1683 return g_node_is_ancestor (G_NODE (iter->user_data),
1684 G_NODE (descendant->user_data));
1689 * gtk_tree_store_iter_depth:
1690 * @tree_store: A #GtkTreeStore
1691 * @iter: A valid #GtkTreeIter
1693 * Returns the depth of @iter. This will be 0 for anything on the root level, 1
1694 * for anything down a level, etc.
1696 * Return value: The depth of @iter
1699 gtk_tree_store_iter_depth (GtkTreeStore *tree_store,
1702 g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), 0);
1703 g_return_val_if_fail (VALID_ITER (iter, tree_store), 0);
1705 return g_node_depth (G_NODE (iter->user_data)) - 2;
1708 /* simple ripoff from g_node_traverse_post_order */
1710 gtk_tree_store_clear_traverse (GNode *node,
1711 GtkTreeStore *store)
1719 child = node->children;
1722 register GNode *current;
1725 child = current->next;
1726 if (gtk_tree_store_clear_traverse (current, store))
1732 iter.stamp = store->stamp;
1733 iter.user_data = node;
1735 gtk_tree_store_remove (store, &iter);
1738 else if (node->parent)
1740 iter.stamp = store->stamp;
1741 iter.user_data = node;
1743 gtk_tree_store_remove (store, &iter);
1750 gtk_tree_store_increment_stamp (GtkTreeStore *tree_store)
1754 tree_store->stamp++;
1756 while (tree_store->stamp == 0);
1760 * gtk_tree_store_clear:
1761 * @tree_store: a #GtkTreeStore
1763 * Removes all rows from @tree_store
1766 gtk_tree_store_clear (GtkTreeStore *tree_store)
1768 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1770 gtk_tree_store_clear_traverse (tree_store->root, tree_store);
1771 gtk_tree_store_increment_stamp (tree_store);
1775 gtk_tree_store_iter_is_valid_helper (GtkTreeIter *iter,
1784 if (node == iter->user_data)
1788 if (gtk_tree_store_iter_is_valid_helper (iter, node->children))
1799 * gtk_tree_store_iter_is_valid:
1800 * @tree_store: A #GtkTreeStore.
1801 * @iter: A #GtkTreeIter.
1803 * WARNING: This function is slow. Only use it for debugging and/or testing
1806 * Checks if the given iter is a valid iter for this #GtkTreeStore.
1808 * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
1813 gtk_tree_store_iter_is_valid (GtkTreeStore *tree_store,
1816 g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
1817 g_return_val_if_fail (iter != NULL, FALSE);
1819 if (!VALID_ITER (iter, tree_store))
1822 return gtk_tree_store_iter_is_valid_helper (iter, tree_store->root);
1828 static gboolean real_gtk_tree_store_row_draggable (GtkTreeDragSource *drag_source,
1835 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1840 if (gtk_tree_store_get_iter (GTK_TREE_MODEL (drag_source),
1844 gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1855 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1857 GtkSelectionData *selection_data)
1859 /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1860 * target, because the default handler does it for us, but
1861 * we do anyway for the convenience of someone maybe overriding the
1865 if (gtk_tree_set_row_drag_data (selection_data,
1866 GTK_TREE_MODEL (drag_source),
1873 /* FIXME handle text targets at least. */
1880 copy_node_data (GtkTreeStore *tree_store,
1881 GtkTreeIter *src_iter,
1882 GtkTreeIter *dest_iter)
1884 GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1885 GtkTreeDataList *copy_head = NULL;
1886 GtkTreeDataList *copy_prev = NULL;
1887 GtkTreeDataList *copy_iter = NULL;
1894 copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1896 if (copy_head == NULL)
1897 copy_head = copy_iter;
1900 copy_prev->next = copy_iter;
1902 copy_prev = copy_iter;
1908 G_NODE (dest_iter->user_data)->data = copy_head;
1910 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1911 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_store), path, dest_iter);
1912 gtk_tree_path_free (path);
1916 recursive_node_copy (GtkTreeStore *tree_store,
1917 GtkTreeIter *src_iter,
1918 GtkTreeIter *dest_iter)
1921 GtkTreeModel *model;
1923 model = GTK_TREE_MODEL (tree_store);
1925 copy_node_data (tree_store, src_iter, dest_iter);
1927 if (gtk_tree_store_iter_children (model,
1931 /* Need to create children and recurse. Note our
1932 * dependence on persistent iterators here.
1938 /* Gee, a really slow algorithm... ;-) FIXME */
1939 gtk_tree_store_append (tree_store,
1943 recursive_node_copy (tree_store, &child, ©);
1945 while (gtk_tree_store_iter_next (model, &child));
1950 gtk_tree_store_drag_data_received (GtkTreeDragDest *drag_dest,
1952 GtkSelectionData *selection_data)
1954 GtkTreeModel *tree_model;
1955 GtkTreeStore *tree_store;
1956 GtkTreeModel *src_model = NULL;
1957 GtkTreePath *src_path = NULL;
1958 gboolean retval = FALSE;
1960 tree_model = GTK_TREE_MODEL (drag_dest);
1961 tree_store = GTK_TREE_STORE (drag_dest);
1963 validate_tree (tree_store);
1965 if (gtk_tree_get_row_drag_data (selection_data,
1968 src_model == tree_model)
1970 /* Copy the given row to a new position */
1971 GtkTreeIter src_iter;
1972 GtkTreeIter dest_iter;
1975 if (!gtk_tree_store_get_iter (src_model,
1982 /* Get the path to insert _after_ (dest is the path to insert _before_) */
1983 prev = gtk_tree_path_copy (dest);
1985 if (!gtk_tree_path_prev (prev))
1987 GtkTreeIter dest_parent;
1988 GtkTreePath *parent;
1989 GtkTreeIter *dest_parent_p;
1991 /* dest was the first spot at the current depth; which means
1992 * we are supposed to prepend.
1995 /* Get the parent, NULL if parent is the root */
1996 dest_parent_p = NULL;
1997 parent = gtk_tree_path_copy (dest);
1998 if (gtk_tree_path_up (parent) &&
1999 gtk_tree_path_get_depth (parent) > 0)
2001 gtk_tree_store_get_iter (tree_model,
2004 dest_parent_p = &dest_parent;
2006 gtk_tree_path_free (parent);
2009 gtk_tree_store_prepend (tree_store,
2017 if (gtk_tree_store_get_iter (tree_model, &dest_iter, prev))
2019 GtkTreeIter tmp_iter = dest_iter;
2021 gtk_tree_store_insert_after (tree_store, &dest_iter, NULL,
2028 gtk_tree_path_free (prev);
2030 /* If we succeeded in creating dest_iter, walk src_iter tree branch,
2031 * duplicating it below dest_iter.
2036 recursive_node_copy (tree_store,
2043 /* FIXME maybe add some data targets eventually, or handle text
2044 * targets in the simple case.
2052 gtk_tree_path_free (src_path);
2058 gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
2059 GtkTreePath *dest_path,
2060 GtkSelectionData *selection_data)
2062 GtkTreeModel *src_model = NULL;
2063 GtkTreePath *src_path = NULL;
2064 GtkTreePath *tmp = NULL;
2065 gboolean retval = FALSE;
2067 /* don't accept drops if the tree has been sorted */
2068 if (GTK_TREE_STORE_IS_SORTED (drag_dest))
2071 if (!gtk_tree_get_row_drag_data (selection_data,
2076 /* can only drag to ourselves */
2077 if (src_model != GTK_TREE_MODEL (drag_dest))
2080 /* Can't drop into ourself. */
2081 if (gtk_tree_path_is_ancestor (src_path,
2085 /* Can't drop if dest_path's parent doesn't exist */
2089 if (gtk_tree_path_get_depth (dest_path) > 1)
2091 tmp = gtk_tree_path_copy (dest_path);
2092 gtk_tree_path_up (tmp);
2094 if (!gtk_tree_store_get_iter (GTK_TREE_MODEL (drag_dest),
2100 /* Can otherwise drop anywhere. */
2106 gtk_tree_path_free (src_path);
2108 gtk_tree_path_free (tmp);
2113 /* Sorting and reordering */
2114 typedef struct _SortTuple
2122 gtk_tree_store_reorder_func (gconstpointer a,
2126 SortTuple *a_reorder;
2127 SortTuple *b_reorder;
2129 a_reorder = (SortTuple *)a;
2130 b_reorder = (SortTuple *)b;
2132 if (a_reorder->offset < b_reorder->offset)
2134 if (a_reorder->offset > b_reorder->offset)
2141 * gtk_tree_store_reorder:
2142 * @tree_store: A #GtkTreeStore.
2143 * @parent: A #GtkTreeIter.
2144 * @new_order: an array of integers mapping the new position of each child
2145 * to its old position before the re-ordering,
2146 * i.e. @new_order<literal>[newpos] = oldpos</literal>.
2148 * Reorders the children of @parent in @tree_store to follow the order
2149 * indicated by @new_order. Note that this function only works with
2155 gtk_tree_store_reorder (GtkTreeStore *tree_store,
2156 GtkTreeIter *parent,
2160 GNode *level, *node;
2162 SortTuple *sort_array;
2164 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
2165 g_return_if_fail (!GTK_TREE_STORE_IS_SORTED (tree_store));
2166 g_return_if_fail (parent == NULL || VALID_ITER (parent, tree_store));
2167 g_return_if_fail (new_order != NULL);
2170 level = G_NODE (tree_store->root)->children;
2172 level = G_NODE (parent->user_data)->children;
2182 /* set up sortarray */
2183 sort_array = g_new (SortTuple, length);
2186 for (i = 0; i < length; i++)
2188 sort_array[new_order[i]].offset = i;
2189 sort_array[i].node = node;
2194 g_qsort_with_data (sort_array,
2197 gtk_tree_store_reorder_func,
2201 for (i = 0; i < length - 1; i++)
2203 sort_array[i].node->next = sort_array[i+1].node;
2204 sort_array[i+1].node->prev = sort_array[i].node;
2207 sort_array[length-1].node->next = NULL;
2208 sort_array[0].node->prev = NULL;
2210 G_NODE (parent->user_data)->children = sort_array[0].node;
2212 G_NODE (tree_store->root)->children = sort_array[0].node;
2216 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), parent);
2218 path = gtk_tree_path_new ();
2219 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store), path,
2221 gtk_tree_path_free (path);
2222 g_free (sort_array);
2226 * gtk_tree_store_swap:
2227 * @tree_store: A #GtkTreeStore.
2228 * @a: A #GtkTreeIter.
2229 * @b: Another #GtkTreeIter.
2231 * Swaps @a and @b in the same level of @tree_store. Note that this function
2232 * only works with unsorted stores.
2237 gtk_tree_store_swap (GtkTreeStore *tree_store,
2241 GNode *tmp, *node_a, *node_b, *parent_node;
2242 GNode *a_prev, *a_next, *b_prev, *b_next;
2243 gint i, a_count, b_count, length, *order;
2244 GtkTreePath *path_a, *path_b;
2247 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
2248 g_return_if_fail (VALID_ITER (a, tree_store));
2249 g_return_if_fail (VALID_ITER (b, tree_store));
2251 node_a = G_NODE (a->user_data);
2252 node_b = G_NODE (b->user_data);
2254 /* basic sanity checking */
2255 if (node_a == node_b)
2258 path_a = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), a);
2259 path_b = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), b);
2261 g_return_if_fail (path_a && path_b);
2263 gtk_tree_path_up (path_a);
2264 gtk_tree_path_up (path_b);
2266 if (gtk_tree_path_get_depth (path_a) == 0
2267 || gtk_tree_path_get_depth (path_b) == 0)
2269 if (gtk_tree_path_get_depth (path_a) != gtk_tree_path_get_depth (path_b))
2271 gtk_tree_path_free (path_a);
2272 gtk_tree_path_free (path_b);
2274 g_warning ("Given children are not in the same level\n");
2277 parent_node = G_NODE (tree_store->root);
2281 if (gtk_tree_path_compare (path_a, path_b))
2283 gtk_tree_path_free (path_a);
2284 gtk_tree_path_free (path_b);
2286 g_warning ("Given children don't have a common parent\n");
2289 gtk_tree_store_get_iter (GTK_TREE_MODEL (tree_store), &parent,
2291 parent_node = G_NODE (parent.user_data);
2293 gtk_tree_path_free (path_b);
2295 /* old links which we have to keep around */
2296 a_prev = node_a->prev;
2297 a_next = node_a->next;
2299 b_prev = node_b->prev;
2300 b_next = node_b->next;
2302 /* fix up links if the nodes are next to eachother */
2303 if (a_prev == node_b)
2305 if (a_next == node_b)
2308 if (b_prev == node_a)
2310 if (b_next == node_a)
2313 /* counting nodes */
2314 tmp = parent_node->children;
2315 i = a_count = b_count = 0;
2328 /* hacking the tree */
2330 parent_node->children = node_b;
2332 a_prev->next = node_b;
2335 a_next->prev = node_b;
2338 parent_node->children = node_a;
2340 b_prev->next = node_a;
2343 b_next->prev = node_a;
2345 node_a->prev = b_prev;
2346 node_a->next = b_next;
2348 node_b->prev = a_prev;
2349 node_b->next = a_next;
2352 order = g_new (gint, length);
2353 for (i = 0; i < length; i++)
2356 else if (i == b_count)
2361 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store), path_a,
2362 parent_node == tree_store->root
2363 ? NULL : &parent, order);
2364 gtk_tree_path_free (path_a);
2368 /* WARNING: this function is *incredibly* fragile. Please smashtest after
2369 * making changes here.
2373 gtk_tree_store_move (GtkTreeStore *tree_store,
2375 GtkTreeIter *position,
2378 GNode *parent, *node, *a, *b, *tmp, *tmp_a, *tmp_b;
2379 gint old_pos, new_pos, length, i, *order;
2380 GtkTreePath *path = NULL, *tmppath, *pos_path = NULL;
2381 GtkTreeIter parent_iter, dst_a, dst_b;
2383 gboolean handle_b = TRUE;
2385 g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
2386 g_return_if_fail (!GTK_TREE_STORE_IS_SORTED (tree_store));
2387 g_return_if_fail (VALID_ITER (iter, tree_store));
2389 g_return_if_fail (VALID_ITER (position, tree_store));
2396 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
2397 pos_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store),
2401 * moving the iter before path or "path + 1" doesn't make sense
2403 * moving the iter before path or "path - 1" doesn't make sense
2405 if (!gtk_tree_path_compare (path, pos_path))
2406 goto free_paths_and_out;
2409 gtk_tree_path_next (path);
2411 gtk_tree_path_prev (path);
2413 if (!gtk_tree_path_compare (path, pos_path))
2414 goto free_paths_and_out;
2417 gtk_tree_path_prev (path);
2419 gtk_tree_path_next (path);
2421 if (gtk_tree_path_get_depth (path) != gtk_tree_path_get_depth (pos_path))
2423 g_warning ("Given children are not in the same level\n");
2425 goto free_paths_and_out;
2428 tmppath = gtk_tree_path_copy (pos_path);
2429 gtk_tree_path_up (path);
2430 gtk_tree_path_up (tmppath);
2432 if (gtk_tree_path_get_depth (path) > 0 &&
2433 gtk_tree_path_compare (path, tmppath))
2435 g_warning ("Given children are not in the same level\n");
2437 gtk_tree_path_free (tmppath);
2438 goto free_paths_and_out;
2441 gtk_tree_path_free (tmppath);
2446 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
2447 gtk_tree_path_up (path);
2450 depth = gtk_tree_path_get_depth (path);
2454 gtk_tree_store_get_iter (GTK_TREE_MODEL (tree_store),
2455 &parent_iter, path);
2457 parent = G_NODE (parent_iter.user_data);
2460 parent = G_NODE (tree_store->root);
2462 /* yes, I know that this can be done shorter, but I'm doing it this way
2463 * so the code is also maintainable
2466 if (before && position)
2468 b = G_NODE (position->user_data);
2470 if (gtk_tree_path_get_indices (pos_path)[gtk_tree_path_get_depth (pos_path) - 1] > 0)
2472 gtk_tree_path_prev (pos_path);
2473 if (gtk_tree_store_get_iter (GTK_TREE_MODEL (tree_store),
2475 a = G_NODE (dst_a.user_data);
2478 gtk_tree_path_next (pos_path);
2481 /* if b is NULL, a is NULL too -- we are at the beginning of the list
2482 * yes and we leak memory here ...
2484 g_return_if_fail (b);
2486 else if (before && !position)
2488 /* move before without position is appending */
2495 a = G_NODE (position->user_data);
2501 gtk_tree_path_next (pos_path);
2502 if (gtk_tree_store_get_iter (GTK_TREE_MODEL (tree_store), &dst_b, pos_path))
2503 b = G_NODE (dst_b.user_data);
2506 gtk_tree_path_prev (pos_path);
2510 /* move after without position is prepending */
2512 gtk_tree_store_iter_children (GTK_TREE_MODEL (tree_store), &dst_b,
2515 gtk_tree_store_iter_children (GTK_TREE_MODEL (tree_store), &dst_b,
2518 b = G_NODE (dst_b.user_data);
2521 /* if a is NULL, b is NULL too -- we are at the end of the list
2522 * yes and we leak memory here ...
2525 g_return_if_fail (a);
2528 /* counting nodes */
2529 tmp = parent->children;
2531 length = old_pos = 0;
2534 if (tmp == iter->user_data)
2541 /* remove node from list */
2542 node = G_NODE (iter->user_data);
2547 tmp_a->next = tmp_b;
2549 parent->children = tmp_b;
2552 tmp_b->prev = tmp_a;
2554 /* and reinsert the node */
2563 else if (!a && !before)
2565 tmp = parent->children;
2568 parent->children = node;
2576 else if (!a && before)
2580 node->parent = NULL;
2581 node->next = node->prev = NULL;
2583 /* before with sibling = NULL appends */
2584 g_node_insert_before (parent, NULL, node);
2588 node->parent = NULL;
2589 node->next = node->prev = NULL;
2591 /* after with sibling = NULL prepends */
2592 g_node_insert_after (parent, NULL, node);
2608 else if (!(!a && before)) /* !a && before is completely handled above */
2614 new_pos = gtk_tree_path_get_indices (pos_path)[gtk_tree_path_get_depth (pos_path)-1];
2618 new_pos = gtk_tree_store_iter_n_children (GTK_TREE_MODEL (tree_store),
2621 new_pos = gtk_tree_store_iter_n_children (GTK_TREE_MODEL (tree_store),
2627 if (new_pos > old_pos)
2629 if (before && position)
2634 if (!before && position)
2638 order = g_new (gint, length);
2639 if (new_pos > old_pos)
2641 for (i = 0; i < length; i++)
2644 else if (i >= old_pos && i < new_pos)
2646 else if (i == new_pos)
2653 for (i = 0; i < length; i++)
2656 else if (i > new_pos && i <= old_pos)
2664 tmppath = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store),
2666 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
2667 tmppath, &parent_iter, order);
2671 tmppath = gtk_tree_path_new ();
2672 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
2673 tmppath, NULL, order);
2676 gtk_tree_path_free (tmppath);
2677 gtk_tree_path_free (path);
2679 gtk_tree_path_free (pos_path);
2685 gtk_tree_path_free (path);
2686 gtk_tree_path_free (pos_path);
2690 * gtk_tree_store_move_before:
2691 * @tree_store: A #GtkTreeStore.
2692 * @iter: A #GtkTreeIter.
2693 * @position: (allow-none): A #GtkTreeIter or %NULL.
2695 * Moves @iter in @tree_store to the position before @position. @iter and
2696 * @position should be in the same level. Note that this function only
2697 * works with unsorted stores. If @position is %NULL, @iter will be
2698 * moved to the end of the level.
2703 gtk_tree_store_move_before (GtkTreeStore *tree_store,
2705 GtkTreeIter *position)
2707 gtk_tree_store_move (tree_store, iter, position, TRUE);
2711 * gtk_tree_store_move_after:
2712 * @tree_store: A #GtkTreeStore.
2713 * @iter: A #GtkTreeIter.
2714 * @position: (allow-none): A #GtkTreeIter.
2716 * Moves @iter in @tree_store to the position after @position. @iter and
2717 * @position should be in the same level. Note that this function only
2718 * works with unsorted stores. If @position is %NULL, @iter will be moved
2719 * to the start of the level.
2724 gtk_tree_store_move_after (GtkTreeStore *tree_store,
2726 GtkTreeIter *position)
2728 gtk_tree_store_move (tree_store, iter, position, FALSE);
2733 gtk_tree_store_compare_func (gconstpointer a,
2737 GtkTreeStore *tree_store = user_data;
2740 GtkTreeIterCompareFunc func;
2747 if (tree_store->sort_column_id != -1)
2749 GtkTreeDataSortHeader *header;
2751 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
2752 tree_store->sort_column_id);
2753 g_return_val_if_fail (header != NULL, 0);
2754 g_return_val_if_fail (header->func != NULL, 0);
2756 func = header->func;
2757 data = header->data;
2761 g_return_val_if_fail (tree_store->default_sort_func != NULL, 0);
2762 func = tree_store->default_sort_func;
2763 data = tree_store->default_sort_data;
2766 node_a = ((SortTuple *) a)->node;
2767 node_b = ((SortTuple *) b)->node;
2769 iter_a.stamp = tree_store->stamp;
2770 iter_a.user_data = node_a;
2771 iter_b.stamp = tree_store->stamp;
2772 iter_b.user_data = node_b;
2774 retval = (* func) (GTK_TREE_MODEL (user_data), &iter_a, &iter_b, data);
2776 if (tree_store->order == GTK_SORT_DESCENDING)
2780 else if (retval < 0)
2787 gtk_tree_store_sort_helper (GtkTreeStore *tree_store,
2800 node = parent->children;
2801 if (node == NULL || node->next == NULL)
2803 if (recurse && node && node->children)
2804 gtk_tree_store_sort_helper (tree_store, node, TRUE);
2810 for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
2813 sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), list_length);
2816 for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
2821 tuple.node = tmp_node;
2822 g_array_append_val (sort_array, tuple);
2826 /* Sort the array */
2827 g_array_sort_with_data (sort_array, gtk_tree_store_compare_func, tree_store);
2829 for (i = 0; i < list_length - 1; i++)
2831 g_array_index (sort_array, SortTuple, i).node->next =
2832 g_array_index (sort_array, SortTuple, i + 1).node;
2833 g_array_index (sort_array, SortTuple, i + 1).node->prev =
2834 g_array_index (sort_array, SortTuple, i).node;
2836 g_array_index (sort_array, SortTuple, list_length - 1).node->next = NULL;
2837 g_array_index (sort_array, SortTuple, 0).node->prev = NULL;
2838 parent->children = g_array_index (sort_array, SortTuple, 0).node;
2840 /* Let the world know about our new order */
2841 new_order = g_new (gint, list_length);
2842 for (i = 0; i < list_length; i++)
2843 new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
2845 iter.stamp = tree_store->stamp;
2846 iter.user_data = parent;
2847 path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &iter);
2848 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
2849 path, &iter, new_order);
2850 gtk_tree_path_free (path);
2852 g_array_free (sort_array, TRUE);
2856 for (tmp_node = parent->children; tmp_node; tmp_node = tmp_node->next)
2858 if (tmp_node->children)
2859 gtk_tree_store_sort_helper (tree_store, tmp_node, TRUE);
2865 gtk_tree_store_sort (GtkTreeStore *tree_store)
2867 if (!GTK_TREE_STORE_IS_SORTED (tree_store))
2870 if (tree_store->sort_column_id != -1)
2872 GtkTreeDataSortHeader *header = NULL;
2874 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
2875 tree_store->sort_column_id);
2877 /* We want to make sure that we have a function */
2878 g_return_if_fail (header != NULL);
2879 g_return_if_fail (header->func != NULL);
2883 g_return_if_fail (tree_store->default_sort_func != NULL);
2886 gtk_tree_store_sort_helper (tree_store, G_NODE (tree_store->root), TRUE);
2890 gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
2893 gboolean emit_signal)
2898 GtkTreePath *tmp_path;
2899 GtkTreeIter tmp_iter;
2907 GtkTreeIterCompareFunc func;
2910 g_return_if_fail (G_NODE (iter->user_data)->parent != NULL);
2912 tmp_iter.stamp = tree_store->stamp;
2913 if (tree_store->sort_column_id != -1)
2915 GtkTreeDataSortHeader *header;
2916 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
2917 tree_store->sort_column_id);
2918 g_return_if_fail (header != NULL);
2919 g_return_if_fail (header->func != NULL);
2920 func = header->func;
2921 data = header->data;
2925 g_return_if_fail (tree_store->default_sort_func != NULL);
2926 func = tree_store->default_sort_func;
2927 data = tree_store->default_sort_data;
2930 /* If it's the built in function, we don't sort. */
2931 if (func == _gtk_tree_data_list_compare_func &&
2932 tree_store->sort_column_id != column)
2936 node = G_NODE (iter->user_data)->parent->children;
2937 /* First we find the iter, its prev, and its next */
2940 if (node == G_NODE (iter->user_data))
2945 g_assert (node != NULL);
2950 /* Check the common case, where we don't need to sort it moved. */
2953 tmp_iter.user_data = prev;
2954 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
2959 tmp_iter.user_data = next;
2960 cmp_b = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
2963 if (tree_store->order == GTK_SORT_DESCENDING)
2976 if (prev == NULL && cmp_b <= 0)
2978 else if (next == NULL && cmp_a <= 0)
2980 else if (prev != NULL && next != NULL &&
2981 cmp_a <= 0 && cmp_b <= 0)
2984 /* We actually need to sort it */
2985 /* First, remove the old link. */
2990 node->parent->children = next;
2998 /* FIXME: as an optimization, we can potentially start at next */
3000 node = node->parent->children;
3002 tmp_iter.user_data = node;
3003 if (tree_store->order == GTK_SORT_DESCENDING)
3004 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
3006 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
3008 while ((node->next) && (cmp_a > 0))
3013 tmp_iter.user_data = node;
3014 if (tree_store->order == GTK_SORT_DESCENDING)
3015 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), &tmp_iter, iter, data);
3017 cmp_a = (* func) (GTK_TREE_MODEL (tree_store), iter, &tmp_iter, data);
3020 if ((!node->next) && (cmp_a > 0))
3023 node->next = G_NODE (iter->user_data);
3024 node->next->prev = node;
3028 prev->next = G_NODE (iter->user_data);
3029 prev->next->prev = prev;
3030 G_NODE (iter->user_data)->next = node;
3031 G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
3035 G_NODE (iter->user_data)->next = G_NODE (iter->user_data)->parent->children;
3036 G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
3037 G_NODE (iter->user_data)->parent->children = G_NODE (iter->user_data);
3043 /* Emit the reordered signal. */
3044 length = g_node_n_children (node->parent);
3045 new_order = g_new (int, length);
3046 if (old_location < new_location)
3047 for (i = 0; i < length; i++)
3049 if (i < old_location ||
3052 else if (i >= old_location &&
3054 new_order[i] = i + 1;
3055 else if (i == new_location)
3056 new_order[i] = old_location;
3059 for (i = 0; i < length; i++)
3061 if (i < new_location ||
3064 else if (i > new_location &&
3066 new_order[i] = i - 1;
3067 else if (i == new_location)
3068 new_order[i] = old_location;
3071 tmp_iter.user_data = node->parent;
3072 tmp_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &tmp_iter);
3074 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_store),
3075 tmp_path, &tmp_iter,
3078 gtk_tree_path_free (tmp_path);
3084 gtk_tree_store_get_sort_column_id (GtkTreeSortable *sortable,
3085 gint *sort_column_id,
3088 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3091 * sort_column_id = tree_store->sort_column_id;
3093 * order = tree_store->order;
3095 if (tree_store->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
3096 tree_store->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
3103 gtk_tree_store_set_sort_column_id (GtkTreeSortable *sortable,
3104 gint sort_column_id,
3107 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3110 if ((tree_store->sort_column_id == sort_column_id) &&
3111 (tree_store->order == order))
3114 if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
3116 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
3118 GtkTreeDataSortHeader *header = NULL;
3120 header = _gtk_tree_data_list_get_header (tree_store->sort_list,
3123 /* We want to make sure that we have a function */
3124 g_return_if_fail (header != NULL);
3125 g_return_if_fail (header->func != NULL);
3129 g_return_if_fail (tree_store->default_sort_func != NULL);
3133 tree_store->sort_column_id = sort_column_id;
3134 tree_store->order = order;
3136 gtk_tree_sortable_sort_column_changed (sortable);
3138 gtk_tree_store_sort (tree_store);
3142 gtk_tree_store_set_sort_func (GtkTreeSortable *sortable,
3143 gint sort_column_id,
3144 GtkTreeIterCompareFunc func,
3146 GDestroyNotify destroy)
3148 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3150 tree_store->sort_list = _gtk_tree_data_list_set_header (tree_store->sort_list,
3152 func, data, destroy);
3154 if (tree_store->sort_column_id == sort_column_id)
3155 gtk_tree_store_sort (tree_store);
3159 gtk_tree_store_set_default_sort_func (GtkTreeSortable *sortable,
3160 GtkTreeIterCompareFunc func,
3162 GDestroyNotify destroy)
3164 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3166 if (tree_store->default_sort_destroy)
3168 GDestroyNotify d = tree_store->default_sort_destroy;
3170 tree_store->default_sort_destroy = NULL;
3171 d (tree_store->default_sort_data);
3174 tree_store->default_sort_func = func;
3175 tree_store->default_sort_data = data;
3176 tree_store->default_sort_destroy = destroy;
3178 if (tree_store->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
3179 gtk_tree_store_sort (tree_store);
3183 gtk_tree_store_has_default_sort_func (GtkTreeSortable *sortable)
3185 GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
3187 return (tree_store->default_sort_func != NULL);
3191 validate_gnode (GNode* node)
3195 iter = node->children;
3196 while (iter != NULL)
3198 g_assert (iter->parent == node);
3200 g_assert (iter->prev->next == iter);
3201 validate_gnode (iter);
3206 /* GtkBuildable custom tag implementation
3209 * <column type="..."/>
3210 * <column type="..."/>
3214 GtkBuilder *builder;
3217 } GSListSubParserData;
3220 tree_model_start_element (GMarkupParseContext *context,
3221 const gchar *element_name,
3222 const gchar **names,
3223 const gchar **values,
3228 GSListSubParserData *data = (GSListSubParserData*)user_data;
3230 for (i = 0; names[i]; i++)
3232 if (strcmp (names[i], "type") == 0)
3233 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
3238 tree_model_end_element (GMarkupParseContext *context,
3239 const gchar *element_name,
3243 GSListSubParserData *data = (GSListSubParserData*)user_data;
3245 g_assert(data->builder);
3247 if (strcmp (element_name, "columns") == 0)
3254 data = (GSListSubParserData*)user_data;
3255 data->items = g_slist_reverse (data->items);
3256 types = g_new0 (GType, g_slist_length (data->items));
3258 for (l = data->items, i = 0; l; l = l->next, i++)
3260 type = gtk_builder_get_type_from_name (data->builder, l->data);
3261 if (type == G_TYPE_INVALID)
3263 g_warning ("Unknown type %s specified in treemodel %s",
3264 (const gchar*)l->data,
3265 gtk_buildable_get_name (GTK_BUILDABLE (data->object)));
3273 gtk_tree_store_set_column_types (GTK_TREE_STORE (data->object), i, types);
3279 static const GMarkupParser tree_model_parser =
3281 tree_model_start_element,
3282 tree_model_end_element
3287 gtk_tree_store_buildable_custom_tag_start (GtkBuildable *buildable,
3288 GtkBuilder *builder,
3290 const gchar *tagname,
3291 GMarkupParser *parser,
3294 GSListSubParserData *parser_data;
3299 if (strcmp (tagname, "columns") == 0)
3301 parser_data = g_slice_new0 (GSListSubParserData);
3302 parser_data->builder = builder;
3303 parser_data->items = NULL;
3304 parser_data->object = G_OBJECT (buildable);
3306 *parser = tree_model_parser;
3307 *data = parser_data;
3315 gtk_tree_store_buildable_custom_finished (GtkBuildable *buildable,
3316 GtkBuilder *builder,
3318 const gchar *tagname,
3321 GSListSubParserData *data;
3323 if (strcmp (tagname, "columns"))
3326 data = (GSListSubParserData*)user_data;
3328 g_slist_free (data->items);
3329 g_slice_free (GSListSubParserData, data);
3332 #define __GTK_TREE_STORE_C__
3333 #include "gtkaliasdef.c"