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.
24 #include <glib/gprintf.h>
25 #include <gobject/gvaluecollector.h>
26 #include "gtktreemodel.h"
27 #include "gtktreeview.h"
28 #include "gtktreeprivate.h"
29 #include "gtkmarshalers.h"
33 * SECTION:gtktreemodel
34 * @Title: GtkTreeModel
35 * @Short_description: The tree interface used by GtkTreeView
36 * @See_also: #GtkTreeView, #GtkTreeStore, #GtkListStore,
37 * <link linkend="gtk-GtkTreeView-drag-and-drop">GtkTreeDnd</link>,
40 * The #GtkTreeModel interface defines a generic tree interface for
41 * use by the #GtkTreeView widget. It is an abstract interface, and
42 * is designed to be usable with any appropriate data structure. The
43 * programmer just has to implement this interface on their own data
44 * type for it to be viewable by a #GtkTreeView widget.
46 * The model is represented as a hierarchical tree of strongly-typed,
47 * columned data. In other words, the model can be seen as a tree where
48 * every node has different values depending on which column is being
49 * queried. The type of data found in a column is determined by using
50 * the GType system (ie. #G_TYPE_INT, #GTK_TYPE_BUTTON, #G_TYPE_POINTER,
51 * etc). The types are homogeneous per column across all nodes. It is
52 * important to note that this interface only provides a way of examining
53 * a model and observing changes. The implementation of each individual
54 * model decides how and if changes are made.
56 * In order to make life simpler for programmers who do not need to
57 * write their own specialized model, two generic models are provided
58 * — the #GtkTreeStore and the #GtkListStore. To use these, the
59 * developer simply pushes data into these models as necessary. These
60 * models provide the data structure as well as all appropriate tree
61 * interfaces. As a result, implementing drag and drop, sorting, and
62 * storing data is trivial. For the vast majority of trees and lists,
63 * these two models are sufficient.
65 * Models are accessed on a node/column level of granularity. One can
66 * query for the value of a model at a certain node and a certain
67 * column on that node. There are two structures used to reference
68 * a particular node in a model. They are the #GtkTreePath and the
69 * #GtkTreeIter<footnote><para>Here, <abbrev>iter</abbrev> is short
70 * for <quote>iterator</quote></para></footnote>. Most of the interface
71 * consists of operations on a #GtkTreeIter.
73 * A path is essentially a potential node. It is a location on a model
74 * that may or may not actually correspond to a node on a specific
75 * model. The #GtkTreePath struct can be converted into either an
76 * array of unsigned integers or a string. The string form is a list
77 * of numbers separated by a colon. Each number refers to the offset
78 * at that level. Thus, the path <quote>0</quote> refers to the root
79 * node and the path <quote>2:4</quote> refers to the fifth child of
82 * By contrast, a #GtkTreeIter is a reference to a specific node on
83 * a specific model. It is a generic struct with an integer and three
84 * generic pointers. These are filled in by the model in a model-specific
85 * way. One can convert a path to an iterator by calling
86 * gtk_tree_model_get_iter(). These iterators are the primary way
87 * of accessing a model and are similar to the iterators used by
88 * #GtkTextBuffer. They are generally statically allocated on the
89 * stack and only used for a short time. The model interface defines
90 * a set of operations using them for navigating the model.
92 * It is expected that models fill in the iterator with private data.
93 * For example, the #GtkListStore model, which is internally a simple
94 * linked list, stores a list node in one of the pointers. The
95 * #GtkTreeModelSort stores an array and an offset in two of the
96 * pointers. Additionally, there is an integer field. This field is
97 * generally filled with a unique stamp per model. This stamp is for
98 * catching errors resulting from using invalid iterators with a model.
100 * The lifecycle of an iterator can be a little confusing at first.
101 * Iterators are expected to always be valid for as long as the model
102 * is unchanged (and doesn't emit a signal). The model is considered
103 * to own all outstanding iterators and nothing needs to be done to
104 * free them from the user's point of view. Additionally, some models
105 * guarantee that an iterator is valid for as long as the node it refers
106 * to is valid (most notably the #GtkTreeStore and #GtkListStore).
107 * Although generally uninteresting, as one always has to allow for
108 * the case where iterators do not persist beyond a signal, some very
109 * important performance enhancements were made in the sort model.
110 * As a result, the #GTK_TREE_MODEL_ITERS_PERSIST flag was added to
111 * indicate this behavior.
113 * To help show some common operation of a model, some examples are
114 * provided. The first example shows three ways of getting the iter at
115 * the location <quote>3:2:5</quote>. While the first method shown is
116 * easier, the second is much more common, as you often get paths from
120 * <title>Acquiring a <structname>GtkTreeIter</structname></title>
122 * /* Three ways of getting the iter pointing to the location */
125 * GtkTreeIter parent_iter;
127 * /* get the iterator from a string */
128 * gtk_tree_model_get_iter_from_string (model, &iter, "3:2:5");
130 * /* get the iterator from a path */
131 * path = gtk_tree_path_new_from_string ("3:2:5");
132 * gtk_tree_model_get_iter (model, &iter, path);
133 * gtk_tree_path_free (path);
135 * /* walk the tree to find the iterator */
136 * gtk_tree_model_iter_nth_child (model, &iter, NULL, 3);
137 * parent_iter = iter;
138 * gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, 2);
139 * parent_iter = iter;
140 * gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, 5);
144 * This second example shows a quick way of iterating through a list
145 * and getting a string and an integer from each row. The
146 * <function>populate_model</function> function used below is not
147 * shown, as it is specific to the #GtkListStore. For information on
148 * how to write such a function, see the #GtkListStore documentation.
151 * <title>Reading data from a <structname>GtkTreeModel</structname></title>
162 * GtkTreeModel *list_store;
165 * gint row_count = 0;
167 * /* make a new list_store */
168 * list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
170 * /* Fill the list store with data */
171 * populate_model (list_store);
173 * /* Get the first iter in the list */
174 * valid = gtk_tree_model_get_iter_first (list_store, &iter);
178 * /* Walk through the list, reading each row */
182 * /* Make sure you terminate calls to gtk_tree_model_get()
183 * * with a '-1' value
185 * gtk_tree_model_get (list_store, &iter,
186 * STRING_COLUMN, &str_data,
187 * INT_COLUMN, &int_data,
190 * /* Do something with the data */
191 * g_print ("Row %d: (%s,%d)\n", row_count, str_data, int_data);
195 * valid = gtk_tree_model_iter_next (list_store, &iter);
202 #define INITIALIZE_TREE_ITER(Iter) \
205 (Iter)->user_data = NULL; \
206 (Iter)->user_data2 = NULL; \
207 (Iter)->user_data3 = NULL; \
210 #define ROW_REF_DATA_STRING "gtk-tree-row-refs"
215 ROW_HAS_CHILD_TOGGLED,
221 static guint tree_model_signals[LAST_SIGNAL] = { 0 };
234 static void gtk_tree_model_base_init (gpointer g_class);
236 /* custom closures */
237 static void row_inserted_marshal (GClosure *closure,
238 GValue /* out */ *return_value,
240 const GValue *param_values,
241 gpointer invocation_hint,
242 gpointer marshal_data);
243 static void row_deleted_marshal (GClosure *closure,
244 GValue /* out */ *return_value,
246 const GValue *param_values,
247 gpointer invocation_hint,
248 gpointer marshal_data);
249 static void rows_reordered_marshal (GClosure *closure,
250 GValue /* out */ *return_value,
252 const GValue *param_values,
253 gpointer invocation_hint,
254 gpointer marshal_data);
256 static void gtk_tree_row_ref_inserted (RowRefList *refs,
259 static void gtk_tree_row_ref_deleted (RowRefList *refs,
261 static void gtk_tree_row_ref_reordered (RowRefList *refs,
267 gtk_tree_model_get_type (void)
269 static GType tree_model_type = 0;
271 if (! tree_model_type)
273 const GTypeInfo tree_model_info =
275 sizeof (GtkTreeModelIface), /* class_size */
276 gtk_tree_model_base_init, /* base_init */
277 NULL, /* base_finalize */
279 NULL, /* class_finalize */
280 NULL, /* class_data */
287 g_type_register_static (G_TYPE_INTERFACE, I_("GtkTreeModel"),
288 &tree_model_info, 0);
290 g_type_interface_add_prerequisite (tree_model_type, G_TYPE_OBJECT);
293 return tree_model_type;
297 gtk_tree_model_base_init (gpointer g_class)
299 static gboolean initialized = FALSE;
304 GType row_inserted_params[2];
305 GType row_deleted_params[1];
306 GType rows_reordered_params[3];
308 row_inserted_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
309 row_inserted_params[1] = GTK_TYPE_TREE_ITER;
311 row_deleted_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
313 rows_reordered_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
314 rows_reordered_params[1] = GTK_TYPE_TREE_ITER;
315 rows_reordered_params[2] = G_TYPE_POINTER;
318 * GtkTreeModel::row-changed:
319 * @tree_model: the #GtkTreeModel on which the signal is emitted
320 * @path: a #GtkTreePath identifying the changed row
321 * @iter: a valid #GtkTreeIter pointing to the changed row
323 * This signal is emitted when a row in the model has changed.
325 tree_model_signals[ROW_CHANGED] =
326 g_signal_new (I_("row-changed"),
329 G_STRUCT_OFFSET (GtkTreeModelIface, row_changed),
331 _gtk_marshal_VOID__BOXED_BOXED,
333 GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE,
336 /* We need to get notification about structure changes
337 * to update row references., so instead of using the
338 * standard g_signal_new() with an offset into our interface
339 * structure, we use a customs closures for the class
340 * closures (default handlers) that first update row references
341 * and then calls the function from the interface structure.
343 * The reason we don't simply update the row references from
344 * the wrapper functions (gtk_tree_model_row_inserted(), etc.)
345 * is to keep proper ordering with respect to signal handlers
346 * connected normally and after.
350 * GtkTreeModel::row-inserted:
351 * @tree_model: the #GtkTreeModel on which the signal is emitted
352 * @path: a #GtkTreePath identifying the new row
353 * @iter: a valid #GtkTreeIter pointing to the new row
355 * This signal is emitted when a new row has been inserted in
358 * Note that the row may still be empty at this point, since
359 * it is a common pattern to first insert an empty row, and
360 * then fill it with the desired values.
362 closure = g_closure_new_simple (sizeof (GClosure), NULL);
363 g_closure_set_marshal (closure, row_inserted_marshal);
364 tree_model_signals[ROW_INSERTED] =
365 g_signal_newv (I_("row-inserted"),
370 _gtk_marshal_VOID__BOXED_BOXED,
372 row_inserted_params);
375 * GtkTreeModel::row-has-child-toggled:
376 * @tree_model: the #GtkTreeModel on which the signal is emitted
377 * @path: a #GtkTreePath identifying the row
378 * @iter: a valid #GtkTreeIter pointing to the row
380 * This signal is emitted when a row has gotten the first child
381 * row or lost its last child row.
383 tree_model_signals[ROW_HAS_CHILD_TOGGLED] =
384 g_signal_new (I_("row-has-child-toggled"),
387 G_STRUCT_OFFSET (GtkTreeModelIface, row_has_child_toggled),
389 _gtk_marshal_VOID__BOXED_BOXED,
391 GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE,
395 * GtkTreeModel::row-deleted:
396 * @tree_model: the #GtkTreeModel on which the signal is emitted
397 * @path: a #GtkTreePath identifying the row
399 * This signal is emitted when a row has been deleted.
401 * Note that no iterator is passed to the signal handler,
402 * since the row is already deleted.
404 * Implementations of GtkTreeModel must emit ::row-deleted
405 * <emphasis>before</emphasis> removing the node from its
406 * internal data structures. This is because models and
407 * views which access and monitor this model might have
408 * references on the node which need to be released in the
409 * row-deleted handler.
411 closure = g_closure_new_simple (sizeof (GClosure), NULL);
412 g_closure_set_marshal (closure, row_deleted_marshal);
413 tree_model_signals[ROW_DELETED] =
414 g_signal_newv (I_("row-deleted"),
419 _gtk_marshal_VOID__BOXED,
424 * GtkTreeModel::rows-reordered: (skip)
425 * @tree_model: the #GtkTreeModel on which the signal is emitted
426 * @path: a #GtkTreePath identifying the tree node whose children
427 * have been reordered
428 * @iter: a valid #GtkTreeIter pointing to the node whose
429 * @new_order: an array of integers mapping the current position
430 * of each child to its old position before the re-ordering,
431 * i.e. @new_order<literal>[newpos] = oldpos</literal>
433 * This signal is emitted when the children of a node in the
434 * #GtkTreeModel have been reordered.
436 * Note that this signal is <emphasis>not</emphasis> emitted
437 * when rows are reordered by DND, since this is implemented
438 * by removing and then reinserting the row.
440 closure = g_closure_new_simple (sizeof (GClosure), NULL);
441 g_closure_set_marshal (closure, rows_reordered_marshal);
442 tree_model_signals[ROWS_REORDERED] =
443 g_signal_newv (I_("rows-reordered"),
448 _gtk_marshal_VOID__BOXED_BOXED_POINTER,
450 rows_reordered_params);
456 row_inserted_marshal (GClosure *closure,
457 GValue /* out */ *return_value,
458 guint n_param_values,
459 const GValue *param_values,
460 gpointer invocation_hint,
461 gpointer marshal_data)
463 GtkTreeModelIface *iface;
465 void (* row_inserted_callback) (GtkTreeModel *tree_model,
467 GtkTreeIter *iter) = NULL;
469 GObject *model = g_value_get_object (param_values + 0);
470 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
471 GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
473 /* first, we need to update internal row references */
474 gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
477 /* fetch the interface ->row_inserted implementation */
478 iface = GTK_TREE_MODEL_GET_IFACE (model);
479 row_inserted_callback = G_STRUCT_MEMBER (gpointer, iface,
480 G_STRUCT_OFFSET (GtkTreeModelIface,
483 /* Call that default signal handler, it if has been set */
484 if (row_inserted_callback)
485 row_inserted_callback (GTK_TREE_MODEL (model), path, iter);
489 row_deleted_marshal (GClosure *closure,
490 GValue /* out */ *return_value,
491 guint n_param_values,
492 const GValue *param_values,
493 gpointer invocation_hint,
494 gpointer marshal_data)
496 GtkTreeModelIface *iface;
497 void (* row_deleted_callback) (GtkTreeModel *tree_model,
498 GtkTreePath *path) = NULL;
499 GObject *model = g_value_get_object (param_values + 0);
500 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
502 /* first, we need to update internal row references */
503 gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
506 /* fetch the interface ->row_deleted implementation */
507 iface = GTK_TREE_MODEL_GET_IFACE (model);
508 row_deleted_callback = G_STRUCT_MEMBER (gpointer, iface,
509 G_STRUCT_OFFSET (GtkTreeModelIface,
512 /* Call that default signal handler, it if has been set */
513 if (row_deleted_callback)
514 row_deleted_callback (GTK_TREE_MODEL (model), path);
518 rows_reordered_marshal (GClosure *closure,
519 GValue /* out */ *return_value,
520 guint n_param_values,
521 const GValue *param_values,
522 gpointer invocation_hint,
523 gpointer marshal_data)
525 GtkTreeModelIface *iface;
526 void (* rows_reordered_callback) (GtkTreeModel *tree_model,
531 GObject *model = g_value_get_object (param_values + 0);
532 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
533 GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
534 gint *new_order = (gint *)g_value_get_pointer (param_values + 3);
536 /* first, we need to update internal row references */
537 gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
538 path, iter, new_order);
540 /* fetch the interface ->rows_reordered implementation */
541 iface = GTK_TREE_MODEL_GET_IFACE (model);
542 rows_reordered_callback = G_STRUCT_MEMBER (gpointer, iface,
543 G_STRUCT_OFFSET (GtkTreeModelIface,
546 /* Call that default signal handler, it if has been set */
547 if (rows_reordered_callback)
548 rows_reordered_callback (GTK_TREE_MODEL (model), path, iter, new_order);
554 * Creates a new #GtkTreePath.
555 * This structure refers to a row.
557 * Return value: A newly created #GtkTreePath.
560 gtk_tree_path_new (void)
563 retval = g_slice_new (GtkTreePath);
565 retval->indices = NULL;
571 * gtk_tree_path_new_from_string:
572 * @path: The string representation of a path
574 * Creates a new #GtkTreePath initialized to @path.
576 * @path is expected to be a colon separated list of numbers.
577 * For example, the string "10:4:0" would create a path of depth
578 * 3 pointing to the 11th child of the root node, the 5th
579 * child of that 11th child, and the 1st child of that 5th child.
580 * If an invalid path string is passed in, %NULL is returned.
582 * Return value: A newly-created #GtkTreePath, or %NULL
585 gtk_tree_path_new_from_string (const gchar *path)
588 const gchar *orig_path = path;
592 g_return_val_if_fail (path != NULL, NULL);
593 g_return_val_if_fail (*path != '\000', NULL);
595 retval = gtk_tree_path_new ();
599 i = strtol (path, &ptr, 10);
602 g_warning (G_STRLOC ": Negative numbers in path %s passed to gtk_tree_path_new_from_string", orig_path);
603 gtk_tree_path_free (retval);
607 gtk_tree_path_append_index (retval, i);
611 if (ptr == path || *ptr != ':')
613 g_warning (G_STRLOC ": Invalid path %s passed to gtk_tree_path_new_from_string", orig_path);
614 gtk_tree_path_free (retval);
624 * gtk_tree_path_new_from_indices:
625 * @first_index: first integer
626 * @varargs: list of integers terminated by -1
628 * Creates a new path with @first_index and @varargs as indices.
630 * Return value: A newly created #GtkTreePath
635 gtk_tree_path_new_from_indices (gint first_index,
642 path = gtk_tree_path_new ();
644 va_start (args, first_index);
649 gtk_tree_path_append_index (path, arg);
650 arg = va_arg (args, gint);
659 * gtk_tree_path_to_string:
660 * @path: A #GtkTreePath
662 * Generates a string representation of the path.
664 * This string is a ':' separated list of numbers.
665 * For example, "4:10:0:3" would be an acceptable
666 * return value for this string.
668 * Return value: A newly-allocated string.
669 * Must be freed with g_free().
672 gtk_tree_path_to_string (GtkTreePath *path)
674 gchar *retval, *ptr, *end;
677 g_return_val_if_fail (path != NULL, NULL);
679 if (path->depth == 0)
682 n = path->depth * 12;
683 ptr = retval = g_new0 (gchar, n);
685 g_snprintf (retval, end - ptr, "%d", path->indices[0]);
686 while (*ptr != '\000')
689 for (i = 1; i < path->depth; i++)
691 g_snprintf (ptr, end - ptr, ":%d", path->indices[i]);
692 while (*ptr != '\000')
700 * gtk_tree_path_new_first:
702 * Creates a new #GtkTreePath.
704 * The string representation of this path is "0".
706 * Return value: A new #GtkTreePath
709 gtk_tree_path_new_first (void)
713 retval = gtk_tree_path_new ();
714 gtk_tree_path_append_index (retval, 0);
720 * gtk_tree_path_append_index:
721 * @path: a #GtkTreePath
724 * Appends a new index to a path.
726 * As a result, the depth of the path is increased.
729 gtk_tree_path_append_index (GtkTreePath *path,
732 g_return_if_fail (path != NULL);
733 g_return_if_fail (index >= 0);
736 path->indices = g_realloc (path->indices, path->depth * sizeof(gint));
737 path->indices[path->depth - 1] = index;
741 * gtk_tree_path_prepend_index:
742 * @path: a #GtkTreePath
745 * Prepends a new index to a path.
747 * As a result, the depth of the path is increased.
750 gtk_tree_path_prepend_index (GtkTreePath *path,
756 new_indices = g_new (gint, path->depth);
758 if (path->indices == NULL)
760 path->indices = new_indices;
761 path->indices[0] = index;
764 memcpy (new_indices + 1, path->indices, (path->depth - 1)*sizeof (gint));
765 g_free (path->indices);
766 path->indices = new_indices;
767 path->indices[0] = index;
771 * gtk_tree_path_get_depth:
772 * @path: a #GtkTreePath
774 * Returns the current depth of @path.
776 * Return value: The depth of @path
779 gtk_tree_path_get_depth (GtkTreePath *path)
781 g_return_val_if_fail (path != NULL, 0);
787 * gtk_tree_path_get_indices: (skip)
788 * @path: a #GtkTreePath
790 * Returns the current indices of @path.
792 * This is an array of integers, each representing a node in a tree.
793 * This value should not be freed.
795 * Return value: The current indices, or %NULL
798 gtk_tree_path_get_indices (GtkTreePath *path)
800 g_return_val_if_fail (path != NULL, NULL);
802 return path->indices;
806 * gtk_tree_path_get_indices_with_depth:
807 * @path: a #GtkTreePath
808 * @depth: (allow-none): return location for number of elements
809 * returned in the integer array, or %NULL
811 * Returns the current indices of @path.
813 * This is an array of integers, each representing a node in a tree.
814 * It also returns the number of elements in the array.
815 * The array should not be freed.
817 * Return value: (array length=depth) (transfer none): The current
822 * Rename to: gtk_tree_path_get_indices
825 gtk_tree_path_get_indices_with_depth (GtkTreePath *path,
828 g_return_val_if_fail (path != NULL, NULL);
831 *depth = path->depth;
833 return path->indices;
837 * gtk_tree_path_free:
838 * @path: a #GtkTreePath
843 gtk_tree_path_free (GtkTreePath *path)
848 g_free (path->indices);
849 g_slice_free (GtkTreePath, path);
853 * gtk_tree_path_copy:
854 * @path: a #GtkTreePath
856 * Creates a new #GtkTreePath as a copy of @path.
858 * Return value: a new #GtkTreePath
861 gtk_tree_path_copy (const GtkTreePath *path)
865 g_return_val_if_fail (path != NULL, NULL);
867 retval = g_slice_new (GtkTreePath);
868 retval->depth = path->depth;
869 retval->indices = g_new (gint, path->depth);
870 memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
874 G_DEFINE_BOXED_TYPE (GtkTreePath, gtk_tree_path,
879 * gtk_tree_path_compare:
881 * @b: a #GtkTreePath to compare with
883 * Compares two paths.
885 * If @a appears before @b in a tree, then -1 is returned.
886 * If @b appears before @a, then 1 is returned.
887 * If the two nodes are equal, then 0 is returned.
889 * Return value: the relative positions of @a and @b
892 gtk_tree_path_compare (const GtkTreePath *a,
893 const GtkTreePath *b)
897 g_return_val_if_fail (a != NULL, 0);
898 g_return_val_if_fail (b != NULL, 0);
899 g_return_val_if_fail (a->depth > 0, 0);
900 g_return_val_if_fail (b->depth > 0, 0);
904 if (a->indices[p] == b->indices[q])
906 return (a->indices[p] < b->indices[q]?-1:1);
908 while (++p < a->depth && ++q < b->depth);
909 if (a->depth == b->depth)
911 return (a->depth < b->depth?-1:1);
915 * gtk_tree_path_is_ancestor:
916 * @path: a #GtkTreePath
917 * @descendant: another #GtkTreePath
919 * Returns %TRUE if @descendant is a descendant of @path.
921 * Return value: %TRUE if @descendant is contained inside @path
924 gtk_tree_path_is_ancestor (GtkTreePath *path,
925 GtkTreePath *descendant)
929 g_return_val_if_fail (path != NULL, FALSE);
930 g_return_val_if_fail (descendant != NULL, FALSE);
932 /* can't be an ancestor if we're deeper */
933 if (path->depth >= descendant->depth)
937 while (i < path->depth)
939 if (path->indices[i] != descendant->indices[i])
948 * gtk_tree_path_is_descendant:
949 * @path: a #GtkTreePath
950 * @ancestor: another #GtkTreePath
952 * Returns %TRUE if @path is a descendant of @ancestor.
954 * Return value: %TRUE if @ancestor contains @path somewhere below it
957 gtk_tree_path_is_descendant (GtkTreePath *path,
958 GtkTreePath *ancestor)
962 g_return_val_if_fail (path != NULL, FALSE);
963 g_return_val_if_fail (ancestor != NULL, FALSE);
965 /* can't be a descendant if we're shallower in the tree */
966 if (path->depth <= ancestor->depth)
970 while (i < ancestor->depth)
972 if (path->indices[i] != ancestor->indices[i])
982 * gtk_tree_path_next:
983 * @path: a #GtkTreePath
985 * Moves the @path to point to the next node at the current depth.
988 gtk_tree_path_next (GtkTreePath *path)
990 g_return_if_fail (path != NULL);
991 g_return_if_fail (path->depth > 0);
993 path->indices[path->depth - 1] ++;
997 * gtk_tree_path_prev:
998 * @path: a #GtkTreePath
1000 * Moves the @path to point to the previous node at the
1001 * current depth, if it exists.
1003 * Return value: %TRUE if @path has a previous node, and
1007 gtk_tree_path_prev (GtkTreePath *path)
1009 g_return_val_if_fail (path != NULL, FALSE);
1011 if (path->depth == 0)
1014 if (path->indices[path->depth - 1] == 0)
1017 path->indices[path->depth - 1] -= 1;
1024 * @path: a #GtkTreePath
1026 * Moves the @path to point to its parent node, if it has a parent.
1028 * Return value: %TRUE if @path has a parent, and the move was made
1031 gtk_tree_path_up (GtkTreePath *path)
1033 g_return_val_if_fail (path != NULL, FALSE);
1035 if (path->depth == 0)
1044 * gtk_tree_path_down:
1045 * @path: a #GtkTreePath
1047 * Moves @path to point to the first child of the current path.
1050 gtk_tree_path_down (GtkTreePath *path)
1052 g_return_if_fail (path != NULL);
1054 gtk_tree_path_append_index (path, 0);
1058 * gtk_tree_iter_copy:
1059 * @iter: a #GtkTreeIter
1061 * Creates a dynamically allocated tree iterator as a copy of @iter.
1063 * This function is not intended for use in applications,
1064 * because you can just copy the structs by value
1065 * (<literal>GtkTreeIter new_iter = iter;</literal>).
1066 * You must free this iter with gtk_tree_iter_free().
1068 * Return value: a newly-allocated copy of @iter
1071 gtk_tree_iter_copy (GtkTreeIter *iter)
1073 GtkTreeIter *retval;
1075 g_return_val_if_fail (iter != NULL, NULL);
1077 retval = g_slice_new (GtkTreeIter);
1084 * gtk_tree_iter_free:
1085 * @iter: a dynamically allocated tree iterator
1087 * Frees an iterator that has been allocated by gtk_tree_iter_copy().
1089 * This function is mainly used for language bindings.
1092 gtk_tree_iter_free (GtkTreeIter *iter)
1094 g_return_if_fail (iter != NULL);
1096 g_slice_free (GtkTreeIter, iter);
1099 G_DEFINE_BOXED_TYPE (GtkTreeIter, gtk_tree_iter,
1104 * gtk_tree_model_get_flags:
1105 * @tree_model: a #GtkTreeModel
1107 * Returns a set of flags supported by this interface.
1109 * The flags are a bitwise combination of #GtkTreeModelFlags.
1110 * The flags supported should not change during the lifetime
1111 * of the @tree_model.
1113 * Return value: the flags supported by this interface
1116 gtk_tree_model_get_flags (GtkTreeModel *tree_model)
1118 GtkTreeModelIface *iface;
1120 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1122 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1123 if (iface->get_flags)
1124 return (* iface->get_flags) (tree_model);
1130 * gtk_tree_model_get_n_columns:
1131 * @tree_model: a #GtkTreeModel
1133 * Returns the number of columns supported by @tree_model.
1135 * Return value: the number of columns
1138 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
1140 GtkTreeModelIface *iface;
1141 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1143 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1144 g_return_val_if_fail (iface->get_n_columns != NULL, 0);
1146 return (* iface->get_n_columns) (tree_model);
1150 * gtk_tree_model_get_column_type:
1151 * @tree_model: a #GtkTreeModel
1152 * @index_: the column index
1154 * Returns the type of the column.
1156 * Return value: (transfer none): the type of the column
1159 gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
1162 GtkTreeModelIface *iface;
1164 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
1166 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1167 g_return_val_if_fail (iface->get_column_type != NULL, G_TYPE_INVALID);
1168 g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
1170 return (* iface->get_column_type) (tree_model, index);
1174 * gtk_tree_model_get_iter:
1175 * @tree_model: a #GtkTreeModel
1176 * @iter: (out): the uninitialized #GtkTreeIter
1177 * @path: the #GtkTreePath
1179 * Sets @iter to a valid iterator pointing to @path.
1181 * Return value: %TRUE, if @iter was set
1184 gtk_tree_model_get_iter (GtkTreeModel *tree_model,
1188 GtkTreeModelIface *iface;
1190 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1191 g_return_val_if_fail (iter != NULL, FALSE);
1192 g_return_val_if_fail (path != NULL, FALSE);
1194 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1195 g_return_val_if_fail (iface->get_iter != NULL, FALSE);
1196 g_return_val_if_fail (path->depth > 0, FALSE);
1198 INITIALIZE_TREE_ITER (iter);
1200 return (* iface->get_iter) (tree_model, iter, path);
1204 * gtk_tree_model_get_iter_from_string:
1205 * @tree_model: a #GtkTreeModel
1206 * @iter: (out): an uninitialized #GtkTreeIter
1207 * @path_string: a string representation of a #GtkTreePath
1209 * Sets @iter to a valid iterator pointing to @path_string, if it
1210 * exists. Otherwise, @iter is left invalid and %FALSE is returned.
1212 * Return value: %TRUE, if @iter was set
1215 gtk_tree_model_get_iter_from_string (GtkTreeModel *tree_model,
1217 const gchar *path_string)
1222 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1223 g_return_val_if_fail (iter != NULL, FALSE);
1224 g_return_val_if_fail (path_string != NULL, FALSE);
1226 path = gtk_tree_path_new_from_string (path_string);
1228 g_return_val_if_fail (path != NULL, FALSE);
1230 retval = gtk_tree_model_get_iter (tree_model, iter, path);
1231 gtk_tree_path_free (path);
1237 * gtk_tree_model_get_string_from_iter:
1238 * @tree_model: a #GtkTreeModel
1239 * @iter: a #GtkTreeIter
1241 * Generates a string representation of the iter.
1243 * This string is a ':' separated list of numbers.
1244 * For example, "4:10:0:3" would be an acceptable
1245 * return value for this string.
1247 * Return value: a newly-allocated string.
1248 * Must be freed with g_free().
1253 gtk_tree_model_get_string_from_iter (GtkTreeModel *tree_model,
1259 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1260 g_return_val_if_fail (iter != NULL, NULL);
1262 path = gtk_tree_model_get_path (tree_model, iter);
1264 g_return_val_if_fail (path != NULL, NULL);
1266 ret = gtk_tree_path_to_string (path);
1267 gtk_tree_path_free (path);
1273 * gtk_tree_model_get_iter_first:
1274 * @tree_model: a #GtkTreeModel
1275 * @iter: (out): the uninitialized #GtkTreeIter
1277 * Initializes @iter with the first iterator in the tree
1278 * (the one at the path "0") and returns %TRUE. Returns
1279 * %FALSE if the tree is empty.
1281 * Return value: %TRUE, if @iter was set
1284 gtk_tree_model_get_iter_first (GtkTreeModel *tree_model,
1290 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1291 g_return_val_if_fail (iter != NULL, FALSE);
1293 path = gtk_tree_path_new_first ();
1294 retval = gtk_tree_model_get_iter (tree_model, iter, path);
1295 gtk_tree_path_free (path);
1301 * gtk_tree_model_get_path:
1302 * @tree_model: a #GtkTreeModel
1303 * @iter: the #GtkTreeIter
1305 * Returns a newly-created #GtkTreePath referenced by @iter.
1307 * This path should be freed with gtk_tree_path_free().
1309 * Return value: a newly-created #GtkTreePath
1312 gtk_tree_model_get_path (GtkTreeModel *tree_model,
1315 GtkTreeModelIface *iface;
1317 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1318 g_return_val_if_fail (iter != NULL, NULL);
1320 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1321 g_return_val_if_fail (iface->get_path != NULL, NULL);
1323 return (* iface->get_path) (tree_model, iter);
1327 * gtk_tree_model_get_value:
1328 * @tree_model: a #GtkTreeModel
1329 * @iter: the #GtkTreeIter
1330 * @column: the column to lookup the value at
1331 * @value: (out) (transfer none): an empty #GValue to set
1333 * Initializes and sets @value to that at @column.
1335 * When done with @value, g_value_unset() needs to be called
1336 * to free any allocated memory.
1339 gtk_tree_model_get_value (GtkTreeModel *tree_model,
1344 GtkTreeModelIface *iface;
1346 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1347 g_return_if_fail (iter != NULL);
1348 g_return_if_fail (value != NULL);
1350 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1351 g_return_if_fail (iface->get_value != NULL);
1353 (* iface->get_value) (tree_model, iter, column, value);
1357 * gtk_tree_model_iter_next:
1358 * @tree_model: a #GtkTreeModel
1359 * @iter: (in): the #GtkTreeIter
1361 * Sets @iter to point to the node following it at the current level.
1363 * If there is no next @iter, %FALSE is returned and @iter is set
1366 * Return value: %TRUE if @iter has been changed to the next node
1369 gtk_tree_model_iter_next (GtkTreeModel *tree_model,
1372 GtkTreeModelIface *iface;
1374 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1375 g_return_val_if_fail (iter != NULL, FALSE);
1377 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1378 g_return_val_if_fail (iface->iter_next != NULL, FALSE);
1380 return (* iface->iter_next) (tree_model, iter);
1384 gtk_tree_model_iter_previous_default (GtkTreeModel *tree_model,
1390 path = gtk_tree_model_get_path (tree_model, iter);
1394 retval = gtk_tree_path_prev (path) &&
1395 gtk_tree_model_get_iter (tree_model, iter, path);
1396 if (retval == FALSE)
1399 gtk_tree_path_free (path);
1405 * gtk_tree_model_iter_previous:
1406 * @tree_model: a #GtkTreeModel
1407 * @iter: (in): the #GtkTreeIter
1409 * Sets @iter to point to the previous node at the current level.
1411 * If there is no previous @iter, %FALSE is returned and @iter is
1412 * set to be invalid.
1414 * Return value: %TRUE if @iter has been changed to the previous node
1419 gtk_tree_model_iter_previous (GtkTreeModel *tree_model,
1423 GtkTreeModelIface *iface;
1425 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1426 g_return_val_if_fail (iter != NULL, FALSE);
1428 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1430 if (iface->iter_previous)
1431 retval = (* iface->iter_previous) (tree_model, iter);
1433 retval = gtk_tree_model_iter_previous_default (tree_model, iter);
1439 * gtk_tree_model_iter_children:
1440 * @tree_model: a #GtkTreeModel
1441 * @iter: (out): the new #GtkTreeIter to be set to the child
1442 * @parent: (allow-none): the #GtkTreeIter, or %NULL
1444 * Sets @iter to point to the first child of @parent.
1446 * If @parent has no children, %FALSE is returned and @iter is
1447 * set to be invalid. @parent will remain a valid node after this
1448 * function has been called.
1450 * If @parent is %NULL returns the first node, equivalent to
1451 * <literal>gtk_tree_model_get_iter_first (tree_model, iter);</literal>
1453 * Return value: %TRUE, if @child has been set to the first child
1456 gtk_tree_model_iter_children (GtkTreeModel *tree_model,
1458 GtkTreeIter *parent)
1460 GtkTreeModelIface *iface;
1462 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1463 g_return_val_if_fail (iter != NULL, FALSE);
1465 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1466 g_return_val_if_fail (iface->iter_children != NULL, FALSE);
1468 INITIALIZE_TREE_ITER (iter);
1470 return (* iface->iter_children) (tree_model, iter, parent);
1474 * gtk_tree_model_iter_has_child:
1475 * @tree_model: a #GtkTreeModel
1476 * @iter: the #GtkTreeIter to test for children
1478 * Returns %TRUE if @iter has children, %FALSE otherwise.
1480 * Return value: %TRUE if @iter has children
1483 gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
1486 GtkTreeModelIface *iface;
1488 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1489 g_return_val_if_fail (iter != NULL, FALSE);
1491 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1492 g_return_val_if_fail (iface->iter_has_child != NULL, FALSE);
1494 return (* iface->iter_has_child) (tree_model, iter);
1498 * gtk_tree_model_iter_n_children:
1499 * @tree_model: a #GtkTreeModel
1500 * @iter: (allow-none): the #GtkTreeIter, or %NULL
1502 * Returns the number of children that @iter has.
1504 * As a special case, if @iter is %NULL, then the number
1505 * of toplevel nodes is returned.
1507 * Return value: the number of children of @iter
1510 gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
1513 GtkTreeModelIface *iface;
1515 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1517 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1518 g_return_val_if_fail (iface->iter_n_children != NULL, 0);
1520 return (* iface->iter_n_children) (tree_model, iter);
1524 * gtk_tree_model_iter_nth_child:
1525 * @tree_model: a #GtkTreeModel
1526 * @iter: (out): the #GtkTreeIter to set to the nth child
1527 * @parent: (allow-none): the #GtkTreeIter to get the child from, or %NULL.
1528 * @n: the index of the desired child
1530 * Sets @iter to be the child of @parent, using the given index.
1532 * The first index is 0. If @n is too big, or @parent has no children,
1533 * @iter is set to an invalid iterator and %FALSE is returned. @parent
1534 * will remain a valid node after this function has been called. As a
1535 * special case, if @parent is %NULL, then the @n<!-- -->th root node
1538 * Return value: %TRUE, if @parent has an @n<!-- -->th child
1541 gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
1543 GtkTreeIter *parent,
1546 GtkTreeModelIface *iface;
1548 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1549 g_return_val_if_fail (iter != NULL, FALSE);
1550 g_return_val_if_fail (n >= 0, FALSE);
1552 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1553 g_return_val_if_fail (iface->iter_nth_child != NULL, FALSE);
1555 INITIALIZE_TREE_ITER (iter);
1557 return (* iface->iter_nth_child) (tree_model, iter, parent, n);
1561 * gtk_tree_model_iter_parent:
1562 * @tree_model: a #GtkTreeModel
1563 * @iter: (out): the new #GtkTreeIter to set to the parent
1564 * @child: the #GtkTreeIter
1566 * Sets @iter to be the parent of @child.
1568 * If @child is at the toplevel, and doesn't have a parent, then
1569 * @iter is set to an invalid iterator and %FALSE is returned.
1570 * @child will remain a valid node after this function has been
1573 * Return value: %TRUE, if @iter is set to the parent of @child
1576 gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
1580 GtkTreeModelIface *iface;
1582 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1583 g_return_val_if_fail (iter != NULL, FALSE);
1584 g_return_val_if_fail (child != NULL, FALSE);
1586 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1587 g_return_val_if_fail (iface->iter_parent != NULL, FALSE);
1589 INITIALIZE_TREE_ITER (iter);
1591 return (* iface->iter_parent) (tree_model, iter, child);
1595 * gtk_tree_model_ref_node:
1596 * @tree_model: a #GtkTreeModel
1597 * @iter: the #GtkTreeIter
1599 * Lets the tree ref the node.
1601 * This is an optional method for models to implement.
1602 * To be more specific, models may ignore this call as it exists
1603 * primarily for performance reasons.
1605 * This function is primarily meant as a way for views to let
1606 * caching models know when nodes are being displayed (and hence,
1607 * whether or not to cache that node). For example, a file-system
1608 * based model would not want to keep the entire file-hierarchy in
1609 * memory, just the sections that are currently being displayed by
1610 * every current view.
1612 * A model should be expected to be able to get an iter independent
1613 * of its reffed state.
1616 gtk_tree_model_ref_node (GtkTreeModel *tree_model,
1619 GtkTreeModelIface *iface;
1621 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1623 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1624 if (iface->ref_node)
1625 (* iface->ref_node) (tree_model, iter);
1629 * gtk_tree_model_unref_node:
1630 * @tree_model: a #GtkTreeModel
1631 * @iter: the #GtkTreeIter
1633 * Lets the tree unref the node.
1635 * This is an optional method for models to implement.
1636 * To be more specific, models may ignore this call as it exists
1637 * primarily for performance reasons. For more information on what
1638 * this means, see gtk_tree_model_ref_node().
1640 * Please note that nodes that are deleted are not unreffed.
1643 gtk_tree_model_unref_node (GtkTreeModel *tree_model,
1646 GtkTreeModelIface *iface;
1648 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1649 g_return_if_fail (iter != NULL);
1651 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1652 if (iface->unref_node)
1653 (* iface->unref_node) (tree_model, iter);
1657 * gtk_tree_model_get:
1658 * @tree_model: a #GtkTreeModel
1659 * @iter: a row in @tree_model
1660 * @Varargs: pairs of column number and value return locations,
1663 * Gets the value of one or more cells in the row referenced by @iter.
1664 * The variable argument list should contain integer column numbers,
1665 * each column number followed by a place to store the value being
1666 * retrieved. The list is terminated by a -1. For example, to get a
1667 * value from column 0 with type %G_TYPE_STRING, you would
1668 * write: <literal>gtk_tree_model_get (model, iter, 0, &place_string_here, -1)</literal>,
1669 * where <literal>place_string_here</literal> is a <type>gchar*</type>
1670 * to be filled with the string.
1672 * Returned values with type %G_TYPE_OBJECT have to be unreferenced,
1673 * values with type %G_TYPE_STRING or %G_TYPE_BOXED have to be freed.
1674 * Other values are passed by value.
1677 gtk_tree_model_get (GtkTreeModel *tree_model,
1683 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1684 g_return_if_fail (iter != NULL);
1686 va_start (var_args, iter);
1687 gtk_tree_model_get_valist (tree_model, iter, var_args);
1692 * gtk_tree_model_get_valist:
1693 * @tree_model: a #GtkTreeModel
1694 * @iter: a row in @tree_model
1695 * @var_args: <type>va_list</type> of column/return location pairs
1697 * See gtk_tree_model_get(), this version takes a <type>va_list</type>
1698 * for language bindings to use.
1701 gtk_tree_model_get_valist (GtkTreeModel *tree_model,
1707 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1708 g_return_if_fail (iter != NULL);
1710 column = va_arg (var_args, gint);
1712 while (column != -1)
1714 GValue value = { 0, };
1715 gchar *error = NULL;
1717 if (column >= gtk_tree_model_get_n_columns (tree_model))
1719 g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
1723 gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, column, &value);
1725 G_VALUE_LCOPY (&value, var_args, 0, &error);
1728 g_warning ("%s: %s", G_STRLOC, error);
1731 /* we purposely leak the value here, it might not be
1732 * in a sane state if an error condition occurred
1737 g_value_unset (&value);
1739 column = va_arg (var_args, gint);
1744 * gtk_tree_model_row_changed:
1745 * @tree_model: a #GtkTreeModel
1746 * @path: a #GtkTreePath pointing to the changed row
1747 * @iter: a valid #GtkTreeIter pointing to the changed row
1749 * Emits the #GtkTreeModel::row-changed signal on @tree_model.
1752 gtk_tree_model_row_changed (GtkTreeModel *tree_model,
1756 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1757 g_return_if_fail (path != NULL);
1758 g_return_if_fail (iter != NULL);
1760 g_signal_emit (tree_model, tree_model_signals[ROW_CHANGED], 0, path, iter);
1764 * gtk_tree_model_row_inserted:
1765 * @tree_model: a #GtkTreeModel
1766 * @path: a #GtkTreePath pointing to the inserted row
1767 * @iter: a valid #GtkTreeIter pointing to the inserted row
1769 * Emits the #GtkTreeModel::row-inserted signal on @tree_model.
1772 gtk_tree_model_row_inserted (GtkTreeModel *tree_model,
1776 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1777 g_return_if_fail (path != NULL);
1778 g_return_if_fail (iter != NULL);
1780 g_signal_emit (tree_model, tree_model_signals[ROW_INSERTED], 0, path, iter);
1784 * gtk_tree_model_row_has_child_toggled:
1785 * @tree_model: a #GtkTreeModel
1786 * @path: a #GtkTreePath pointing to the changed row
1787 * @iter: a valid #GtkTreeIter pointing to the changed row
1789 * Emits the #GtkTreeModel::row-has-child-toggled signal on
1790 * @tree_model. This should be called by models after the child
1791 * state of a node changes.
1794 gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model,
1798 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1799 g_return_if_fail (path != NULL);
1800 g_return_if_fail (iter != NULL);
1802 g_signal_emit (tree_model, tree_model_signals[ROW_HAS_CHILD_TOGGLED], 0, path, iter);
1806 * gtk_tree_model_row_deleted:
1807 * @tree_model: a #GtkTreeModel
1808 * @path: a #GtkTreePath pointing to the previous location of
1811 * Emits the #GtkTreeModel::row-deleted signal on @tree_model.
1813 * This should be called by models after a row has been removed.
1814 * The location pointed to by @path should be the location that
1815 * the row previously was at. It may not be a valid location anymore.
1818 gtk_tree_model_row_deleted (GtkTreeModel *tree_model,
1821 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1822 g_return_if_fail (path != NULL);
1824 g_signal_emit (tree_model, tree_model_signals[ROW_DELETED], 0, path);
1828 * gtk_tree_model_rows_reordered: (skip)
1829 * @tree_model: a #GtkTreeModel
1830 * @path: a #GtkTreePath pointing to the tree node whose children
1831 * have been reordered
1832 * @iter: a valid #GtkTreeIter pointing to the node whose children
1833 * have been reordered, or %NULL if the depth of @path is 0
1834 * @new_order: an array of integers mapping the current position of
1835 * each child to its old position before the re-ordering,
1836 * i.e. @new_order<literal>[newpos] = oldpos</literal>
1838 * Emits the #GtkTreeModel::rows-reordered signal on @tree_model.
1840 * This should be called by models when their rows have been
1844 gtk_tree_model_rows_reordered (GtkTreeModel *tree_model,
1849 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1850 g_return_if_fail (new_order != NULL);
1852 g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1857 gtk_tree_model_foreach_helper (GtkTreeModel *model,
1860 GtkTreeModelForeachFunc func,
1867 if ((* func) (model, path, iter, user_data))
1870 if (gtk_tree_model_iter_children (model, &child, iter))
1872 gtk_tree_path_down (path);
1873 if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
1875 gtk_tree_path_up (path);
1878 gtk_tree_path_next (path);
1880 while (gtk_tree_model_iter_next (model, iter));
1886 * gtk_tree_model_foreach:
1887 * @model: a #GtkTreeModel
1888 * @func: (scope call): a function to be called on each row
1889 * @user_data: user data to passed to @func
1891 * Calls func on each node in model in a depth-first fashion.
1893 * If @func returns %TRUE, then the tree ceases to be walked,
1894 * and gtk_tree_model_foreach() returns.
1897 gtk_tree_model_foreach (GtkTreeModel *model,
1898 GtkTreeModelForeachFunc func,
1904 g_return_if_fail (GTK_IS_TREE_MODEL (model));
1905 g_return_if_fail (func != NULL);
1907 path = gtk_tree_path_new_first ();
1908 if (gtk_tree_model_get_iter (model, &iter, path) == FALSE)
1910 gtk_tree_path_free (path);
1914 gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
1915 gtk_tree_path_free (path);
1920 * GtkTreeRowReference
1923 static void gtk_tree_row_reference_unref_path (GtkTreePath *path,
1924 GtkTreeModel *model,
1928 G_DEFINE_BOXED_TYPE (GtkTreeRowReference, gtk_tree_row_reference,
1929 gtk_tree_row_reference_copy,
1930 gtk_tree_row_reference_free)
1932 struct _GtkTreeRowReference
1935 GtkTreeModel *model;
1941 release_row_references (gpointer data)
1943 RowRefList *refs = data;
1944 GSList *tmp_list = NULL;
1946 tmp_list = refs->list;
1947 while (tmp_list != NULL)
1949 GtkTreeRowReference *reference = tmp_list->data;
1951 if (reference->proxy == (GObject *)reference->model)
1952 reference->model = NULL;
1953 reference->proxy = NULL;
1955 /* we don't free the reference, users are responsible for that. */
1957 tmp_list = g_slist_next (tmp_list);
1960 g_slist_free (refs->list);
1965 gtk_tree_row_ref_inserted (RowRefList *refs,
1974 /* This function corrects the path stored in the reference to
1975 * account for an insertion. Note that it's called _after_ the
1976 * insertion with the path to the newly-inserted row. Which means
1977 * that the inserted path is in a different "coordinate system" than
1978 * the old path (e.g. if the inserted path was just before the old
1979 * path, then inserted path and old path will be the same, and old
1980 * path must be moved down one).
1983 tmp_list = refs->list;
1985 while (tmp_list != NULL)
1987 GtkTreeRowReference *reference = tmp_list->data;
1989 if (reference->path == NULL)
1992 if (reference->path->depth >= path->depth)
1995 gboolean ancestor = TRUE;
1997 for (i = 0; i < path->depth - 1; i ++)
1999 if (path->indices[i] != reference->path->indices[i])
2005 if (ancestor == FALSE)
2008 if (path->indices[path->depth-1] <= reference->path->indices[path->depth-1])
2009 reference->path->indices[path->depth-1] += 1;
2012 tmp_list = g_slist_next (tmp_list);
2017 gtk_tree_row_ref_deleted (RowRefList *refs,
2025 /* This function corrects the path stored in the reference to
2026 * account for an deletion. Note that it's called _after_ the
2027 * deletion with the old path of the just-deleted row. Which means
2028 * that the deleted path is the same now-defunct "coordinate system"
2029 * as the path saved in the reference, which is what we want to fix.
2032 tmp_list = refs->list;
2034 while (tmp_list != NULL)
2036 GtkTreeRowReference *reference = tmp_list->data;
2038 if (reference->path)
2042 if (path->depth > reference->path->depth)
2044 for (i = 0; i < path->depth - 1; i++)
2046 if (path->indices[i] != reference->path->indices[i])
2050 /* We know it affects us. */
2051 if (path->indices[i] == reference->path->indices[i])
2053 if (reference->path->depth > path->depth)
2054 /* some parent was deleted, trying to unref any node
2055 * between the deleted parent and the node the reference
2056 * is pointing to is bad, as those nodes are already gone.
2058 gtk_tree_row_reference_unref_path (reference->path, reference->model, path->depth - 1);
2060 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth - 1);
2061 gtk_tree_path_free (reference->path);
2062 reference->path = NULL;
2064 else if (path->indices[i] < reference->path->indices[i])
2066 reference->path->indices[path->depth-1]-=1;
2071 tmp_list = g_slist_next (tmp_list);
2076 gtk_tree_row_ref_reordered (RowRefList *refs,
2087 tmp_list = refs->list;
2089 while (tmp_list != NULL)
2091 GtkTreeRowReference *reference = tmp_list->data;
2093 length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (reference->model), iter);
2098 if ((reference->path) &&
2099 (gtk_tree_path_is_ancestor (path, reference->path)))
2101 gint ref_depth = gtk_tree_path_get_depth (reference->path);
2102 gint depth = gtk_tree_path_get_depth (path);
2104 if (ref_depth > depth)
2107 gint *indices = gtk_tree_path_get_indices (reference->path);
2109 for (i = 0; i < length; i++)
2111 if (new_order[i] == indices[depth])
2120 tmp_list = g_slist_next (tmp_list);
2124 /* We do this recursively so that we can unref children nodes
2125 * before their parent
2128 gtk_tree_row_reference_unref_path_helper (GtkTreePath *path,
2129 GtkTreeModel *model,
2130 GtkTreeIter *parent_iter,
2136 if (depth == current_depth)
2139 gtk_tree_model_iter_nth_child (model, &iter, parent_iter, path->indices[current_depth]);
2140 gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, current_depth + 1);
2141 gtk_tree_model_unref_node (model, &iter);
2145 gtk_tree_row_reference_unref_path (GtkTreePath *path,
2146 GtkTreeModel *model,
2154 gtk_tree_model_iter_nth_child (model, &iter, NULL, path->indices[0]);
2155 gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, 1);
2156 gtk_tree_model_unref_node (model, &iter);
2160 * gtk_tree_row_reference_new:
2161 * @model: a #GtkTreeModel
2162 * @path: a valid #GtkTreePath to monitor
2164 * Creates a row reference based on @path.
2166 * This reference will keep pointing to the node pointed to
2167 * by @path, so long as it exists. It listens to all signals
2168 * emitted by @model, and updates its path appropriately. If
2169 * @path isn't a valid path in @model, then %NULL is returned.
2171 * Return value: a newly allocated #GtkTreeRowReference, or %NULL
2173 GtkTreeRowReference *
2174 gtk_tree_row_reference_new (GtkTreeModel *model,
2177 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2178 g_return_val_if_fail (path != NULL, NULL);
2180 /* We use the model itself as the proxy object; and call
2181 * gtk_tree_row_reference_inserted(), etc, in the
2182 * class closure (default handler) marshalers for the signal.
2184 return gtk_tree_row_reference_new_proxy (G_OBJECT (model), model, path);
2188 * gtk_tree_row_reference_new_proxy:
2189 * @proxy: a proxy #GObject
2190 * @model: a #GtkTreeModel
2191 * @path: a valid #GtkTreePath to monitor
2193 * You do not need to use this function.
2195 * Creates a row reference based on @path.
2197 * This reference will keep pointing to the node pointed to
2198 * by @path, so long as it exists. If @path isn't a valid
2199 * path in @model, then %NULL is returned. However, unlike
2200 * references created with gtk_tree_row_reference_new(), it
2201 * does not listen to the model for changes. The creator of
2202 * the row reference must do this explicitly using
2203 * gtk_tree_row_reference_inserted(), gtk_tree_row_reference_deleted(),
2204 * gtk_tree_row_reference_reordered().
2206 * These functions must be called exactly once per proxy when the
2207 * corresponding signal on the model is emitted. This single call
2208 * updates all row references for that proxy. Since built-in GTK+
2209 * objects like #GtkTreeView already use this mechanism internally,
2210 * using them as the proxy object will produce unpredictable results.
2211 * Further more, passing the same object as @model and @proxy
2212 * doesn't work for reasons of internal implementation.
2214 * This type of row reference is primarily meant by structures that
2215 * need to carefully monitor exactly when a row reference updates
2216 * itself, and is not generally needed by most applications.
2218 * Return value: a newly allocated #GtkTreeRowReference, or %NULL
2220 GtkTreeRowReference *
2221 gtk_tree_row_reference_new_proxy (GObject *proxy,
2222 GtkTreeModel *model,
2225 GtkTreeRowReference *reference;
2227 GtkTreeIter parent_iter;
2230 g_return_val_if_fail (G_IS_OBJECT (proxy), NULL);
2231 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2232 g_return_val_if_fail (path != NULL, NULL);
2233 g_return_val_if_fail (path->depth > 0, NULL);
2235 /* check that the path is valid */
2236 if (gtk_tree_model_get_iter (model, &parent_iter, path) == FALSE)
2239 /* Now we want to ref every node */
2240 gtk_tree_model_iter_nth_child (model, &parent_iter, NULL, path->indices[0]);
2241 gtk_tree_model_ref_node (model, &parent_iter);
2243 for (i = 1; i < path->depth; i++)
2246 gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, path->indices[i]);
2247 gtk_tree_model_ref_node (model, &iter);
2251 /* Make the row reference */
2252 reference = g_new (GtkTreeRowReference, 1);
2254 g_object_ref (proxy);
2255 g_object_ref (model);
2256 reference->proxy = proxy;
2257 reference->model = model;
2258 reference->path = gtk_tree_path_copy (path);
2260 refs = g_object_get_data (G_OBJECT (proxy), ROW_REF_DATA_STRING);
2264 refs = g_new (RowRefList, 1);
2267 g_object_set_data_full (G_OBJECT (proxy),
2268 I_(ROW_REF_DATA_STRING),
2269 refs, release_row_references);
2272 refs->list = g_slist_prepend (refs->list, reference);
2278 * gtk_tree_row_reference_get_path:
2279 * @reference: a #GtkTreeRowReference
2281 * Returns a path that the row reference currently points to,
2282 * or %NULL if the path pointed to is no longer valid.
2284 * Return value: a current path, or %NULL
2287 gtk_tree_row_reference_get_path (GtkTreeRowReference *reference)
2289 g_return_val_if_fail (reference != NULL, NULL);
2291 if (reference->proxy == NULL)
2294 if (reference->path == NULL)
2297 return gtk_tree_path_copy (reference->path);
2301 * gtk_tree_row_reference_get_model:
2302 * @reference: a #GtkTreeRowReference
2304 * Returns the model that the row reference is monitoring.
2306 * Return value: (transfer none): the model
2311 gtk_tree_row_reference_get_model (GtkTreeRowReference *reference)
2313 g_return_val_if_fail (reference != NULL, NULL);
2315 return reference->model;
2319 * gtk_tree_row_reference_valid:
2320 * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2322 * Returns %TRUE if the @reference is non-%NULL and refers to
2323 * a current valid path.
2325 * Return value: %TRUE if @reference points to a valid path
2328 gtk_tree_row_reference_valid (GtkTreeRowReference *reference)
2330 if (reference == NULL || reference->path == NULL)
2338 * gtk_tree_row_reference_copy:
2339 * @reference: a #GtkTreeRowReference
2341 * Copies a #GtkTreeRowReference.
2343 * Return value: a copy of @reference
2347 GtkTreeRowReference *
2348 gtk_tree_row_reference_copy (GtkTreeRowReference *reference)
2350 return gtk_tree_row_reference_new_proxy (reference->proxy,
2356 * gtk_tree_row_reference_free:
2357 * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2359 * Free's @reference. @reference may be %NULL
2362 gtk_tree_row_reference_free (GtkTreeRowReference *reference)
2366 if (reference == NULL)
2369 refs = g_object_get_data (G_OBJECT (reference->proxy), ROW_REF_DATA_STRING);
2373 g_warning (G_STRLOC": bad row reference, proxy has no outstanding row references");
2377 refs->list = g_slist_remove (refs->list, reference);
2379 if (refs->list == NULL)
2381 g_object_set_data (G_OBJECT (reference->proxy),
2382 I_(ROW_REF_DATA_STRING),
2386 if (reference->path)
2388 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth);
2389 gtk_tree_path_free (reference->path);
2392 g_object_unref (reference->proxy);
2393 g_object_unref (reference->model);
2398 * gtk_tree_row_reference_inserted:
2399 * @proxy: a #GObject
2400 * @path: the row position that was inserted
2402 * Lets a set of row reference created by
2403 * gtk_tree_row_reference_new_proxy() know that the
2404 * model emitted the #GtkTreeModel::row-inserted signal.
2407 gtk_tree_row_reference_inserted (GObject *proxy,
2410 g_return_if_fail (G_IS_OBJECT (proxy));
2412 gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, NULL);
2416 * gtk_tree_row_reference_deleted:
2417 * @proxy: a #GObject
2418 * @path: the path position that was deleted
2420 * Lets a set of row reference created by
2421 * gtk_tree_row_reference_new_proxy() know that the
2422 * model emitted the #GtkTreeModel::row-deleted signal.
2425 gtk_tree_row_reference_deleted (GObject *proxy,
2428 g_return_if_fail (G_IS_OBJECT (proxy));
2430 gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path);
2434 * gtk_tree_row_reference_reordered: (skip)
2435 * @proxy: a #GObject
2436 * @path: the parent path of the reordered signal
2437 * @iter: the iter pointing to the parent of the reordered
2438 * @new_order: the new order of rows
2440 * Lets a set of row reference created by
2441 * gtk_tree_row_reference_new_proxy() know that the
2442 * model emitted the #GtkTreeModel::rows-reordered signal.
2445 gtk_tree_row_reference_reordered (GObject *proxy,
2450 g_return_if_fail (G_IS_OBJECT (proxy));
2452 gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, iter, new_order);