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 * This should be called by models after a row has been removed.
405 * The location pointed to by @path should be the location that
406 * the row previously was at. It may not be a valid location anymore.
408 closure = g_closure_new_simple (sizeof (GClosure), NULL);
409 g_closure_set_marshal (closure, row_deleted_marshal);
410 tree_model_signals[ROW_DELETED] =
411 g_signal_newv (I_("row-deleted"),
416 _gtk_marshal_VOID__BOXED,
421 * GtkTreeModel::rows-reordered: (skip)
422 * @tree_model: the #GtkTreeModel on which the signal is emitted
423 * @path: a #GtkTreePath identifying the tree node whose children
424 * have been reordered
425 * @iter: a valid #GtkTreeIter pointing to the node whose
426 * @new_order: an array of integers mapping the current position
427 * of each child to its old position before the re-ordering,
428 * i.e. @new_order<literal>[newpos] = oldpos</literal>
430 * This signal is emitted when the children of a node in the
431 * #GtkTreeModel have been reordered.
433 * Note that this signal is <emphasis>not</emphasis> emitted
434 * when rows are reordered by DND, since this is implemented
435 * by removing and then reinserting the row.
437 closure = g_closure_new_simple (sizeof (GClosure), NULL);
438 g_closure_set_marshal (closure, rows_reordered_marshal);
439 tree_model_signals[ROWS_REORDERED] =
440 g_signal_newv (I_("rows-reordered"),
445 _gtk_marshal_VOID__BOXED_BOXED_POINTER,
447 rows_reordered_params);
453 row_inserted_marshal (GClosure *closure,
454 GValue /* out */ *return_value,
455 guint n_param_values,
456 const GValue *param_values,
457 gpointer invocation_hint,
458 gpointer marshal_data)
460 GtkTreeModelIface *iface;
462 void (* row_inserted_callback) (GtkTreeModel *tree_model,
464 GtkTreeIter *iter) = NULL;
466 GObject *model = g_value_get_object (param_values + 0);
467 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
468 GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
470 /* first, we need to update internal row references */
471 gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
474 /* fetch the interface ->row_inserted implementation */
475 iface = GTK_TREE_MODEL_GET_IFACE (model);
476 row_inserted_callback = G_STRUCT_MEMBER (gpointer, iface,
477 G_STRUCT_OFFSET (GtkTreeModelIface,
480 /* Call that default signal handler, it if has been set */
481 if (row_inserted_callback)
482 row_inserted_callback (GTK_TREE_MODEL (model), path, iter);
486 row_deleted_marshal (GClosure *closure,
487 GValue /* out */ *return_value,
488 guint n_param_values,
489 const GValue *param_values,
490 gpointer invocation_hint,
491 gpointer marshal_data)
493 GtkTreeModelIface *iface;
494 void (* row_deleted_callback) (GtkTreeModel *tree_model,
495 GtkTreePath *path) = NULL;
496 GObject *model = g_value_get_object (param_values + 0);
497 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
499 /* first, we need to update internal row references */
500 gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
503 /* fetch the interface ->row_deleted implementation */
504 iface = GTK_TREE_MODEL_GET_IFACE (model);
505 row_deleted_callback = G_STRUCT_MEMBER (gpointer, iface,
506 G_STRUCT_OFFSET (GtkTreeModelIface,
509 /* Call that default signal handler, it if has been set */
510 if (row_deleted_callback)
511 row_deleted_callback (GTK_TREE_MODEL (model), path);
515 rows_reordered_marshal (GClosure *closure,
516 GValue /* out */ *return_value,
517 guint n_param_values,
518 const GValue *param_values,
519 gpointer invocation_hint,
520 gpointer marshal_data)
522 GtkTreeModelIface *iface;
523 void (* rows_reordered_callback) (GtkTreeModel *tree_model,
528 GObject *model = g_value_get_object (param_values + 0);
529 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
530 GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
531 gint *new_order = (gint *)g_value_get_pointer (param_values + 3);
533 /* first, we need to update internal row references */
534 gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
535 path, iter, new_order);
537 /* fetch the interface ->rows_reordered implementation */
538 iface = GTK_TREE_MODEL_GET_IFACE (model);
539 rows_reordered_callback = G_STRUCT_MEMBER (gpointer, iface,
540 G_STRUCT_OFFSET (GtkTreeModelIface,
543 /* Call that default signal handler, it if has been set */
544 if (rows_reordered_callback)
545 rows_reordered_callback (GTK_TREE_MODEL (model), path, iter, new_order);
551 * Creates a new #GtkTreePath.
552 * This structure refers to a row.
554 * Return value: A newly created #GtkTreePath.
557 gtk_tree_path_new (void)
560 retval = g_slice_new (GtkTreePath);
562 retval->indices = NULL;
568 * gtk_tree_path_new_from_string:
569 * @path: The string representation of a path
571 * Creates a new #GtkTreePath initialized to @path.
573 * @path is expected to be a colon separated list of numbers.
574 * For example, the string "10:4:0" would create a path of depth
575 * 3 pointing to the 11th child of the root node, the 5th
576 * child of that 11th child, and the 1st child of that 5th child.
577 * If an invalid path string is passed in, %NULL is returned.
579 * Return value: A newly-created #GtkTreePath, or %NULL
582 gtk_tree_path_new_from_string (const gchar *path)
585 const gchar *orig_path = path;
589 g_return_val_if_fail (path != NULL, NULL);
590 g_return_val_if_fail (*path != '\000', NULL);
592 retval = gtk_tree_path_new ();
596 i = strtol (path, &ptr, 10);
599 g_warning (G_STRLOC ": Negative numbers in path %s passed to gtk_tree_path_new_from_string", orig_path);
600 gtk_tree_path_free (retval);
604 gtk_tree_path_append_index (retval, i);
608 if (ptr == path || *ptr != ':')
610 g_warning (G_STRLOC ": Invalid path %s passed to gtk_tree_path_new_from_string", orig_path);
611 gtk_tree_path_free (retval);
621 * gtk_tree_path_new_from_indices:
622 * @first_index: first integer
623 * @varargs: list of integers terminated by -1
625 * Creates a new path with @first_index and @varargs as indices.
627 * Return value: A newly created #GtkTreePath
632 gtk_tree_path_new_from_indices (gint first_index,
639 path = gtk_tree_path_new ();
641 va_start (args, first_index);
646 gtk_tree_path_append_index (path, arg);
647 arg = va_arg (args, gint);
656 * gtk_tree_path_to_string:
657 * @path: A #GtkTreePath
659 * Generates a string representation of the path.
661 * This string is a ':' separated list of numbers.
662 * For example, "4:10:0:3" would be an acceptable
663 * return value for this string.
665 * Return value: A newly-allocated string.
666 * Must be freed with g_free().
669 gtk_tree_path_to_string (GtkTreePath *path)
671 gchar *retval, *ptr, *end;
674 g_return_val_if_fail (path != NULL, NULL);
676 if (path->depth == 0)
679 n = path->depth * 12;
680 ptr = retval = g_new0 (gchar, n);
682 g_snprintf (retval, end - ptr, "%d", path->indices[0]);
683 while (*ptr != '\000')
686 for (i = 1; i < path->depth; i++)
688 g_snprintf (ptr, end - ptr, ":%d", path->indices[i]);
689 while (*ptr != '\000')
697 * gtk_tree_path_new_first:
699 * Creates a new #GtkTreePath.
701 * The string representation of this path is "0".
703 * Return value: A new #GtkTreePath
706 gtk_tree_path_new_first (void)
710 retval = gtk_tree_path_new ();
711 gtk_tree_path_append_index (retval, 0);
717 * gtk_tree_path_append_index:
718 * @path: a #GtkTreePath
721 * Appends a new index to a path.
723 * As a result, the depth of the path is increased.
726 gtk_tree_path_append_index (GtkTreePath *path,
729 g_return_if_fail (path != NULL);
730 g_return_if_fail (index >= 0);
733 path->indices = g_realloc (path->indices, path->depth * sizeof(gint));
734 path->indices[path->depth - 1] = index;
738 * gtk_tree_path_prepend_index:
739 * @path: a #GtkTreePath
742 * Prepends a new index to a path.
744 * As a result, the depth of the path is increased.
747 gtk_tree_path_prepend_index (GtkTreePath *path,
753 new_indices = g_new (gint, path->depth);
755 if (path->indices == NULL)
757 path->indices = new_indices;
758 path->indices[0] = index;
761 memcpy (new_indices + 1, path->indices, (path->depth - 1)*sizeof (gint));
762 g_free (path->indices);
763 path->indices = new_indices;
764 path->indices[0] = index;
768 * gtk_tree_path_get_depth:
769 * @path: a #GtkTreePath
771 * Returns the current depth of @path.
773 * Return value: The depth of @path
776 gtk_tree_path_get_depth (GtkTreePath *path)
778 g_return_val_if_fail (path != NULL, 0);
784 * gtk_tree_path_get_indices: (skip)
785 * @path: a #GtkTreePath
787 * Returns the current indices of @path.
789 * This is an array of integers, each representing a node in a tree.
790 * This value should not be freed.
792 * Return value: The current indices, or %NULL
795 gtk_tree_path_get_indices (GtkTreePath *path)
797 g_return_val_if_fail (path != NULL, NULL);
799 return path->indices;
803 * gtk_tree_path_get_indices_with_depth:
804 * @path: a #GtkTreePath
805 * @depth: (allow-none): return location for number of elements
806 * returned in the integer array, or %NULL
808 * Returns the current indices of @path.
810 * This is an array of integers, each representing a node in a tree.
811 * It also returns the number of elements in the array.
812 * The array should not be freed.
814 * Return value: (array length=depth) (transfer none): The current
819 * Rename to: gtk_tree_path_get_indices
822 gtk_tree_path_get_indices_with_depth (GtkTreePath *path,
825 g_return_val_if_fail (path != NULL, NULL);
828 *depth = path->depth;
830 return path->indices;
834 * gtk_tree_path_free:
835 * @path: a #GtkTreePath
840 gtk_tree_path_free (GtkTreePath *path)
845 g_free (path->indices);
846 g_slice_free (GtkTreePath, path);
850 * gtk_tree_path_copy:
851 * @path: a #GtkTreePath
853 * Creates a new #GtkTreePath as a copy of @path.
855 * Return value: a new #GtkTreePath
858 gtk_tree_path_copy (const GtkTreePath *path)
862 g_return_val_if_fail (path != NULL, NULL);
864 retval = g_slice_new (GtkTreePath);
865 retval->depth = path->depth;
866 retval->indices = g_new (gint, path->depth);
867 memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
871 G_DEFINE_BOXED_TYPE (GtkTreePath, gtk_tree_path,
876 * gtk_tree_path_compare:
878 * @b: a #GtkTreePath to compare with
880 * Compares two paths.
882 * If @a appears before @b in a tree, then -1 is returned.
883 * If @b appears before @a, then 1 is returned.
884 * If the two nodes are equal, then 0 is returned.
886 * Return value: the relative positions of @a and @b
889 gtk_tree_path_compare (const GtkTreePath *a,
890 const GtkTreePath *b)
894 g_return_val_if_fail (a != NULL, 0);
895 g_return_val_if_fail (b != NULL, 0);
896 g_return_val_if_fail (a->depth > 0, 0);
897 g_return_val_if_fail (b->depth > 0, 0);
901 if (a->indices[p] == b->indices[q])
903 return (a->indices[p] < b->indices[q]?-1:1);
905 while (++p < a->depth && ++q < b->depth);
906 if (a->depth == b->depth)
908 return (a->depth < b->depth?-1:1);
912 * gtk_tree_path_is_ancestor:
913 * @path: a #GtkTreePath
914 * @descendant: another #GtkTreePath
916 * Returns %TRUE if @descendant is a descendant of @path.
918 * Return value: %TRUE if @descendant is contained inside @path
921 gtk_tree_path_is_ancestor (GtkTreePath *path,
922 GtkTreePath *descendant)
926 g_return_val_if_fail (path != NULL, FALSE);
927 g_return_val_if_fail (descendant != NULL, FALSE);
929 /* can't be an ancestor if we're deeper */
930 if (path->depth >= descendant->depth)
934 while (i < path->depth)
936 if (path->indices[i] != descendant->indices[i])
945 * gtk_tree_path_is_descendant:
946 * @path: a #GtkTreePath
947 * @ancestor: another #GtkTreePath
949 * Returns %TRUE if @path is a descendant of @ancestor.
951 * Return value: %TRUE if @ancestor contains @path somewhere below it
954 gtk_tree_path_is_descendant (GtkTreePath *path,
955 GtkTreePath *ancestor)
959 g_return_val_if_fail (path != NULL, FALSE);
960 g_return_val_if_fail (ancestor != NULL, FALSE);
962 /* can't be a descendant if we're shallower in the tree */
963 if (path->depth <= ancestor->depth)
967 while (i < ancestor->depth)
969 if (path->indices[i] != ancestor->indices[i])
979 * gtk_tree_path_next:
980 * @path: a #GtkTreePath
982 * Moves the @path to point to the next node at the current depth.
985 gtk_tree_path_next (GtkTreePath *path)
987 g_return_if_fail (path != NULL);
988 g_return_if_fail (path->depth > 0);
990 path->indices[path->depth - 1] ++;
994 * gtk_tree_path_prev:
995 * @path: a #GtkTreePath
997 * Moves the @path to point to the previous node at the
998 * current depth, if it exists.
1000 * Return value: %TRUE if @path has a previous node, and
1004 gtk_tree_path_prev (GtkTreePath *path)
1006 g_return_val_if_fail (path != NULL, FALSE);
1008 if (path->depth == 0)
1011 if (path->indices[path->depth - 1] == 0)
1014 path->indices[path->depth - 1] -= 1;
1021 * @path: a #GtkTreePath
1023 * Moves the @path to point to its parent node, if it has a parent.
1025 * Return value: %TRUE if @path has a parent, and the move was made
1028 gtk_tree_path_up (GtkTreePath *path)
1030 g_return_val_if_fail (path != NULL, FALSE);
1032 if (path->depth == 0)
1041 * gtk_tree_path_down:
1042 * @path: a #GtkTreePath
1044 * Moves @path to point to the first child of the current path.
1047 gtk_tree_path_down (GtkTreePath *path)
1049 g_return_if_fail (path != NULL);
1051 gtk_tree_path_append_index (path, 0);
1055 * gtk_tree_iter_copy:
1056 * @iter: a #GtkTreeIter
1058 * Creates a dynamically allocated tree iterator as a copy of @iter.
1060 * This function is not intended for use in applications,
1061 * because you can just copy the structs by value
1062 * (<literal>GtkTreeIter new_iter = iter;</literal>).
1063 * You must free this iter with gtk_tree_iter_free().
1065 * Return value: a newly-allocated copy of @iter
1068 gtk_tree_iter_copy (GtkTreeIter *iter)
1070 GtkTreeIter *retval;
1072 g_return_val_if_fail (iter != NULL, NULL);
1074 retval = g_slice_new (GtkTreeIter);
1081 * gtk_tree_iter_free:
1082 * @iter: a dynamically allocated tree iterator
1084 * Frees an iterator that has been allocated by gtk_tree_iter_copy().
1086 * This function is mainly used for language bindings.
1089 gtk_tree_iter_free (GtkTreeIter *iter)
1091 g_return_if_fail (iter != NULL);
1093 g_slice_free (GtkTreeIter, iter);
1096 G_DEFINE_BOXED_TYPE (GtkTreeIter, gtk_tree_iter,
1101 * gtk_tree_model_get_flags:
1102 * @tree_model: a #GtkTreeModel
1104 * Returns a set of flags supported by this interface.
1106 * The flags are a bitwise combination of #GtkTreeModelFlags.
1107 * The flags supported should not change during the lifetime
1108 * of the @tree_model.
1110 * Return value: the flags supported by this interface
1113 gtk_tree_model_get_flags (GtkTreeModel *tree_model)
1115 GtkTreeModelIface *iface;
1117 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1119 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1120 if (iface->get_flags)
1121 return (* iface->get_flags) (tree_model);
1127 * gtk_tree_model_get_n_columns:
1128 * @tree_model: a #GtkTreeModel
1130 * Returns the number of columns supported by @tree_model.
1132 * Return value: the number of columns
1135 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
1137 GtkTreeModelIface *iface;
1138 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1140 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1141 g_return_val_if_fail (iface->get_n_columns != NULL, 0);
1143 return (* iface->get_n_columns) (tree_model);
1147 * gtk_tree_model_get_column_type:
1148 * @tree_model: a #GtkTreeModel
1149 * @index_: the column index
1151 * Returns the type of the column.
1153 * Return value: (transfer none): the type of the column
1156 gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
1159 GtkTreeModelIface *iface;
1161 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
1163 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1164 g_return_val_if_fail (iface->get_column_type != NULL, G_TYPE_INVALID);
1165 g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
1167 return (* iface->get_column_type) (tree_model, index);
1171 * gtk_tree_model_get_iter:
1172 * @tree_model: a #GtkTreeModel
1173 * @iter: (out): the uninitialized #GtkTreeIter
1174 * @path: the #GtkTreePath
1176 * Sets @iter to a valid iterator pointing to @path.
1178 * Return value: %TRUE, if @iter was set
1181 gtk_tree_model_get_iter (GtkTreeModel *tree_model,
1185 GtkTreeModelIface *iface;
1187 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1188 g_return_val_if_fail (iter != NULL, FALSE);
1189 g_return_val_if_fail (path != NULL, FALSE);
1191 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1192 g_return_val_if_fail (iface->get_iter != NULL, FALSE);
1193 g_return_val_if_fail (path->depth > 0, FALSE);
1195 INITIALIZE_TREE_ITER (iter);
1197 return (* iface->get_iter) (tree_model, iter, path);
1201 * gtk_tree_model_get_iter_from_string:
1202 * @tree_model: a #GtkTreeModel
1203 * @iter: (out): an uninitialized #GtkTreeIter
1204 * @path_string: a string representation of a #GtkTreePath
1206 * Sets @iter to a valid iterator pointing to @path_string, if it
1207 * exists. Otherwise, @iter is left invalid and %FALSE is returned.
1209 * Return value: %TRUE, if @iter was set
1212 gtk_tree_model_get_iter_from_string (GtkTreeModel *tree_model,
1214 const gchar *path_string)
1219 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1220 g_return_val_if_fail (iter != NULL, FALSE);
1221 g_return_val_if_fail (path_string != NULL, FALSE);
1223 path = gtk_tree_path_new_from_string (path_string);
1225 g_return_val_if_fail (path != NULL, FALSE);
1227 retval = gtk_tree_model_get_iter (tree_model, iter, path);
1228 gtk_tree_path_free (path);
1234 * gtk_tree_model_get_string_from_iter:
1235 * @tree_model: a #GtkTreeModel
1236 * @iter: a #GtkTreeIter
1238 * Generates a string representation of the iter.
1240 * This string is a ':' separated list of numbers.
1241 * For example, "4:10:0:3" would be an acceptable
1242 * return value for this string.
1244 * Return value: a newly-allocated string.
1245 * Must be freed with g_free().
1250 gtk_tree_model_get_string_from_iter (GtkTreeModel *tree_model,
1256 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1257 g_return_val_if_fail (iter != NULL, NULL);
1259 path = gtk_tree_model_get_path (tree_model, iter);
1261 g_return_val_if_fail (path != NULL, NULL);
1263 ret = gtk_tree_path_to_string (path);
1264 gtk_tree_path_free (path);
1270 * gtk_tree_model_get_iter_first:
1271 * @tree_model: a #GtkTreeModel
1272 * @iter: (out): the uninitialized #GtkTreeIter
1274 * Initializes @iter with the first iterator in the tree
1275 * (the one at the path "0") and returns %TRUE. Returns
1276 * %FALSE if the tree is empty.
1278 * Return value: %TRUE, if @iter was set
1281 gtk_tree_model_get_iter_first (GtkTreeModel *tree_model,
1287 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1288 g_return_val_if_fail (iter != NULL, FALSE);
1290 path = gtk_tree_path_new_first ();
1291 retval = gtk_tree_model_get_iter (tree_model, iter, path);
1292 gtk_tree_path_free (path);
1298 * gtk_tree_model_get_path:
1299 * @tree_model: a #GtkTreeModel
1300 * @iter: the #GtkTreeIter
1302 * Returns a newly-created #GtkTreePath referenced by @iter.
1304 * This path should be freed with gtk_tree_path_free().
1306 * Return value: a newly-created #GtkTreePath
1309 gtk_tree_model_get_path (GtkTreeModel *tree_model,
1312 GtkTreeModelIface *iface;
1314 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1315 g_return_val_if_fail (iter != NULL, NULL);
1317 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1318 g_return_val_if_fail (iface->get_path != NULL, NULL);
1320 return (* iface->get_path) (tree_model, iter);
1324 * gtk_tree_model_get_value:
1325 * @tree_model: a #GtkTreeModel
1326 * @iter: the #GtkTreeIter
1327 * @column: the column to lookup the value at
1328 * @value: (out) (transfer none): an empty #GValue to set
1330 * Initializes and sets @value to that at @column.
1332 * When done with @value, g_value_unset() needs to be called
1333 * to free any allocated memory.
1336 gtk_tree_model_get_value (GtkTreeModel *tree_model,
1341 GtkTreeModelIface *iface;
1343 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1344 g_return_if_fail (iter != NULL);
1345 g_return_if_fail (value != NULL);
1347 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1348 g_return_if_fail (iface->get_value != NULL);
1350 (* iface->get_value) (tree_model, iter, column, value);
1354 * gtk_tree_model_iter_next:
1355 * @tree_model: a #GtkTreeModel
1356 * @iter: (in): the #GtkTreeIter
1358 * Sets @iter to point to the node following it at the current level.
1360 * If there is no next @iter, %FALSE is returned and @iter is set
1363 * Return value: %TRUE if @iter has been changed to the next node
1366 gtk_tree_model_iter_next (GtkTreeModel *tree_model,
1369 GtkTreeModelIface *iface;
1371 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1372 g_return_val_if_fail (iter != NULL, FALSE);
1374 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1375 g_return_val_if_fail (iface->iter_next != NULL, FALSE);
1377 return (* iface->iter_next) (tree_model, iter);
1381 gtk_tree_model_iter_previous_default (GtkTreeModel *tree_model,
1387 path = gtk_tree_model_get_path (tree_model, iter);
1391 retval = gtk_tree_path_prev (path) &&
1392 gtk_tree_model_get_iter (tree_model, iter, path);
1393 if (retval == FALSE)
1396 gtk_tree_path_free (path);
1402 * gtk_tree_model_iter_previous:
1403 * @tree_model: a #GtkTreeModel
1404 * @iter: (in): the #GtkTreeIter
1406 * Sets @iter to point to the previous node at the current level.
1408 * If there is no previous @iter, %FALSE is returned and @iter is
1409 * set to be invalid.
1411 * Return value: %TRUE if @iter has been changed to the previous node
1416 gtk_tree_model_iter_previous (GtkTreeModel *tree_model,
1420 GtkTreeModelIface *iface;
1422 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1423 g_return_val_if_fail (iter != NULL, FALSE);
1425 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1427 if (iface->iter_previous)
1428 retval = (* iface->iter_previous) (tree_model, iter);
1430 retval = gtk_tree_model_iter_previous_default (tree_model, iter);
1436 * gtk_tree_model_iter_children:
1437 * @tree_model: a #GtkTreeModel
1438 * @iter: (out): the new #GtkTreeIter to be set to the child
1439 * @parent: (allow-none): the #GtkTreeIter, or %NULL
1441 * Sets @iter to point to the first child of @parent.
1443 * If @parent has no children, %FALSE is returned and @iter is
1444 * set to be invalid. @parent will remain a valid node after this
1445 * function has been called.
1447 * If @parent is %NULL returns the first node, equivalent to
1448 * <literal>gtk_tree_model_get_iter_first (tree_model, iter);</literal>
1450 * Return value: %TRUE, if @child has been set to the first child
1453 gtk_tree_model_iter_children (GtkTreeModel *tree_model,
1455 GtkTreeIter *parent)
1457 GtkTreeModelIface *iface;
1459 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1460 g_return_val_if_fail (iter != NULL, FALSE);
1462 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1463 g_return_val_if_fail (iface->iter_children != NULL, FALSE);
1465 INITIALIZE_TREE_ITER (iter);
1467 return (* iface->iter_children) (tree_model, iter, parent);
1471 * gtk_tree_model_iter_has_child:
1472 * @tree_model: a #GtkTreeModel
1473 * @iter: the #GtkTreeIter to test for children
1475 * Returns %TRUE if @iter has children, %FALSE otherwise.
1477 * Return value: %TRUE if @iter has children
1480 gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
1483 GtkTreeModelIface *iface;
1485 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1486 g_return_val_if_fail (iter != NULL, FALSE);
1488 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1489 g_return_val_if_fail (iface->iter_has_child != NULL, FALSE);
1491 return (* iface->iter_has_child) (tree_model, iter);
1495 * gtk_tree_model_iter_n_children:
1496 * @tree_model: a #GtkTreeModel
1497 * @iter: (allow-none): the #GtkTreeIter, or %NULL
1499 * Returns the number of children that @iter has.
1501 * As a special case, if @iter is %NULL, then the number
1502 * of toplevel nodes is returned.
1504 * Return value: the number of children of @iter
1507 gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
1510 GtkTreeModelIface *iface;
1512 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1514 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1515 g_return_val_if_fail (iface->iter_n_children != NULL, 0);
1517 return (* iface->iter_n_children) (tree_model, iter);
1521 * gtk_tree_model_iter_nth_child:
1522 * @tree_model: a #GtkTreeModel
1523 * @iter: (out): the #GtkTreeIter to set to the nth child
1524 * @parent: (allow-none): the #GtkTreeIter to get the child from, or %NULL.
1525 * @n: the index of the desired child
1527 * Sets @iter to be the child of @parent, using the given index.
1529 * The first index is 0. If @n is too big, or @parent has no children,
1530 * @iter is set to an invalid iterator and %FALSE is returned. @parent
1531 * will remain a valid node after this function has been called. As a
1532 * special case, if @parent is %NULL, then the @n<!-- -->th root node
1535 * Return value: %TRUE, if @parent has an @n<!-- -->th child
1538 gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
1540 GtkTreeIter *parent,
1543 GtkTreeModelIface *iface;
1545 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1546 g_return_val_if_fail (iter != NULL, FALSE);
1547 g_return_val_if_fail (n >= 0, FALSE);
1549 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1550 g_return_val_if_fail (iface->iter_nth_child != NULL, FALSE);
1552 INITIALIZE_TREE_ITER (iter);
1554 return (* iface->iter_nth_child) (tree_model, iter, parent, n);
1558 * gtk_tree_model_iter_parent:
1559 * @tree_model: a #GtkTreeModel
1560 * @iter: (out): the new #GtkTreeIter to set to the parent
1561 * @child: the #GtkTreeIter
1563 * Sets @iter to be the parent of @child.
1565 * If @child is at the toplevel, and doesn't have a parent, then
1566 * @iter is set to an invalid iterator and %FALSE is returned.
1567 * @child will remain a valid node after this function has been
1570 * Return value: %TRUE, if @iter is set to the parent of @child
1573 gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
1577 GtkTreeModelIface *iface;
1579 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1580 g_return_val_if_fail (iter != NULL, FALSE);
1581 g_return_val_if_fail (child != NULL, FALSE);
1583 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1584 g_return_val_if_fail (iface->iter_parent != NULL, FALSE);
1586 INITIALIZE_TREE_ITER (iter);
1588 return (* iface->iter_parent) (tree_model, iter, child);
1592 * gtk_tree_model_ref_node:
1593 * @tree_model: a #GtkTreeModel
1594 * @iter: the #GtkTreeIter
1596 * Lets the tree ref the node.
1598 * This is an optional method for models to implement.
1599 * To be more specific, models may ignore this call as it exists
1600 * primarily for performance reasons.
1602 * This function is primarily meant as a way for views to let
1603 * caching models know when nodes are being displayed (and hence,
1604 * whether or not to cache that node). For example, a file-system
1605 * based model would not want to keep the entire file-hierarchy in
1606 * memory, just the sections that are currently being displayed by
1607 * every current view.
1609 * A model should be expected to be able to get an iter independent
1610 * of its reffed state.
1613 gtk_tree_model_ref_node (GtkTreeModel *tree_model,
1616 GtkTreeModelIface *iface;
1618 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1620 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1621 if (iface->ref_node)
1622 (* iface->ref_node) (tree_model, iter);
1626 * gtk_tree_model_unref_node:
1627 * @tree_model: a #GtkTreeModel
1628 * @iter: the #GtkTreeIter
1630 * Lets the tree unref the node.
1632 * This is an optional method for models to implement.
1633 * To be more specific, models may ignore this call as it exists
1634 * primarily for performance reasons. For more information on what
1635 * this means, see gtk_tree_model_ref_node().
1637 * Please note that nodes that are deleted are not unreffed.
1640 gtk_tree_model_unref_node (GtkTreeModel *tree_model,
1643 GtkTreeModelIface *iface;
1645 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1646 g_return_if_fail (iter != NULL);
1648 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1649 if (iface->unref_node)
1650 (* iface->unref_node) (tree_model, iter);
1654 * gtk_tree_model_get:
1655 * @tree_model: a #GtkTreeModel
1656 * @iter: a row in @tree_model
1657 * @Varargs: pairs of column number and value return locations,
1660 * Gets the value of one or more cells in the row referenced by @iter.
1661 * The variable argument list should contain integer column numbers,
1662 * each column number followed by a place to store the value being
1663 * retrieved. The list is terminated by a -1. For example, to get a
1664 * value from column 0 with type %G_TYPE_STRING, you would
1665 * write: <literal>gtk_tree_model_get (model, iter, 0, &place_string_here, -1)</literal>,
1666 * where <literal>place_string_here</literal> is a <type>gchar*</type>
1667 * to be filled with the string.
1669 * Returned values with type %G_TYPE_OBJECT have to be unreferenced,
1670 * values with type %G_TYPE_STRING or %G_TYPE_BOXED have to be freed.
1671 * Other values are passed by value.
1674 gtk_tree_model_get (GtkTreeModel *tree_model,
1680 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1681 g_return_if_fail (iter != NULL);
1683 va_start (var_args, iter);
1684 gtk_tree_model_get_valist (tree_model, iter, var_args);
1689 * gtk_tree_model_get_valist:
1690 * @tree_model: a #GtkTreeModel
1691 * @iter: a row in @tree_model
1692 * @var_args: <type>va_list</type> of column/return location pairs
1694 * See gtk_tree_model_get(), this version takes a <type>va_list</type>
1695 * for language bindings to use.
1698 gtk_tree_model_get_valist (GtkTreeModel *tree_model,
1704 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1705 g_return_if_fail (iter != NULL);
1707 column = va_arg (var_args, gint);
1709 while (column != -1)
1711 GValue value = { 0, };
1712 gchar *error = NULL;
1714 if (column >= gtk_tree_model_get_n_columns (tree_model))
1716 g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
1720 gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, column, &value);
1722 G_VALUE_LCOPY (&value, var_args, 0, &error);
1725 g_warning ("%s: %s", G_STRLOC, error);
1728 /* we purposely leak the value here, it might not be
1729 * in a sane state if an error condition occurred
1734 g_value_unset (&value);
1736 column = va_arg (var_args, gint);
1741 * gtk_tree_model_row_changed:
1742 * @tree_model: a #GtkTreeModel
1743 * @path: a #GtkTreePath pointing to the changed row
1744 * @iter: a valid #GtkTreeIter pointing to the changed row
1746 * Emits the #GtkTreeModel::row-changed signal on @tree_model.
1749 gtk_tree_model_row_changed (GtkTreeModel *tree_model,
1753 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1754 g_return_if_fail (path != NULL);
1755 g_return_if_fail (iter != NULL);
1757 g_signal_emit (tree_model, tree_model_signals[ROW_CHANGED], 0, path, iter);
1761 * gtk_tree_model_row_inserted:
1762 * @tree_model: a #GtkTreeModel
1763 * @path: a #GtkTreePath pointing to the inserted row
1764 * @iter: a valid #GtkTreeIter pointing to the inserted row
1766 * Emits the #GtkTreeModel::row-inserted signal on @tree_model.
1769 gtk_tree_model_row_inserted (GtkTreeModel *tree_model,
1773 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1774 g_return_if_fail (path != NULL);
1775 g_return_if_fail (iter != NULL);
1777 g_signal_emit (tree_model, tree_model_signals[ROW_INSERTED], 0, path, iter);
1781 * gtk_tree_model_row_has_child_toggled:
1782 * @tree_model: a #GtkTreeModel
1783 * @path: a #GtkTreePath pointing to the changed row
1784 * @iter: a valid #GtkTreeIter pointing to the changed row
1786 * Emits the #GtkTreeModel::row-has-child-toggled signal on
1787 * @tree_model. This should be called by models after the child
1788 * state of a node changes.
1791 gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model,
1795 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1796 g_return_if_fail (path != NULL);
1797 g_return_if_fail (iter != NULL);
1799 g_signal_emit (tree_model, tree_model_signals[ROW_HAS_CHILD_TOGGLED], 0, path, iter);
1803 * gtk_tree_model_row_deleted:
1804 * @tree_model: a #GtkTreeModel
1805 * @path: a #GtkTreePath pointing to the previous location of
1808 * Emits the #GtkTreeModel::row-deleted signal on @tree_model.
1810 * This should be called by models after a row has been removed.
1811 * The location pointed to by @path should be the location that
1812 * the row previously was at. It may not be a valid location anymore.
1815 gtk_tree_model_row_deleted (GtkTreeModel *tree_model,
1818 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1819 g_return_if_fail (path != NULL);
1821 g_signal_emit (tree_model, tree_model_signals[ROW_DELETED], 0, path);
1825 * gtk_tree_model_rows_reordered: (skip)
1826 * @tree_model: a #GtkTreeModel
1827 * @path: a #GtkTreePath pointing to the tree node whose children
1828 * have been reordered
1829 * @iter: a valid #GtkTreeIter pointing to the node whose children
1830 * have been reordered, or %NULL if the depth of @path is 0
1831 * @new_order: an array of integers mapping the current position of
1832 * each child to its old position before the re-ordering,
1833 * i.e. @new_order<literal>[newpos] = oldpos</literal>
1835 * Emits the #GtkTreeModel::rows-reordered signal on @tree_model.
1837 * This should be called by models when their rows have been
1841 gtk_tree_model_rows_reordered (GtkTreeModel *tree_model,
1846 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1847 g_return_if_fail (new_order != NULL);
1849 g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1854 gtk_tree_model_foreach_helper (GtkTreeModel *model,
1857 GtkTreeModelForeachFunc func,
1864 if ((* func) (model, path, iter, user_data))
1867 if (gtk_tree_model_iter_children (model, &child, iter))
1869 gtk_tree_path_down (path);
1870 if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
1872 gtk_tree_path_up (path);
1875 gtk_tree_path_next (path);
1877 while (gtk_tree_model_iter_next (model, iter));
1883 * gtk_tree_model_foreach:
1884 * @model: a #GtkTreeModel
1885 * @func: (scope call): a function to be called on each row
1886 * @user_data: user data to passed to @func
1888 * Calls func on each node in model in a depth-first fashion.
1890 * If @func returns %TRUE, then the tree ceases to be walked,
1891 * and gtk_tree_model_foreach() returns.
1894 gtk_tree_model_foreach (GtkTreeModel *model,
1895 GtkTreeModelForeachFunc func,
1901 g_return_if_fail (GTK_IS_TREE_MODEL (model));
1902 g_return_if_fail (func != NULL);
1904 path = gtk_tree_path_new_first ();
1905 if (gtk_tree_model_get_iter (model, &iter, path) == FALSE)
1907 gtk_tree_path_free (path);
1911 gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
1912 gtk_tree_path_free (path);
1917 * GtkTreeRowReference
1920 static void gtk_tree_row_reference_unref_path (GtkTreePath *path,
1921 GtkTreeModel *model,
1925 G_DEFINE_BOXED_TYPE (GtkTreeRowReference, gtk_tree_row_reference,
1926 gtk_tree_row_reference_copy,
1927 gtk_tree_row_reference_free)
1929 struct _GtkTreeRowReference
1932 GtkTreeModel *model;
1938 release_row_references (gpointer data)
1940 RowRefList *refs = data;
1941 GSList *tmp_list = NULL;
1943 tmp_list = refs->list;
1944 while (tmp_list != NULL)
1946 GtkTreeRowReference *reference = tmp_list->data;
1948 if (reference->proxy == (GObject *)reference->model)
1949 reference->model = NULL;
1950 reference->proxy = NULL;
1952 /* we don't free the reference, users are responsible for that. */
1954 tmp_list = g_slist_next (tmp_list);
1957 g_slist_free (refs->list);
1962 gtk_tree_row_ref_inserted (RowRefList *refs,
1971 /* This function corrects the path stored in the reference to
1972 * account for an insertion. Note that it's called _after_ the
1973 * insertion with the path to the newly-inserted row. Which means
1974 * that the inserted path is in a different "coordinate system" than
1975 * the old path (e.g. if the inserted path was just before the old
1976 * path, then inserted path and old path will be the same, and old
1977 * path must be moved down one).
1980 tmp_list = refs->list;
1982 while (tmp_list != NULL)
1984 GtkTreeRowReference *reference = tmp_list->data;
1986 if (reference->path == NULL)
1989 if (reference->path->depth >= path->depth)
1992 gboolean ancestor = TRUE;
1994 for (i = 0; i < path->depth - 1; i ++)
1996 if (path->indices[i] != reference->path->indices[i])
2002 if (ancestor == FALSE)
2005 if (path->indices[path->depth-1] <= reference->path->indices[path->depth-1])
2006 reference->path->indices[path->depth-1] += 1;
2009 tmp_list = g_slist_next (tmp_list);
2014 gtk_tree_row_ref_deleted (RowRefList *refs,
2022 /* This function corrects the path stored in the reference to
2023 * account for an deletion. Note that it's called _after_ the
2024 * deletion with the old path of the just-deleted row. Which means
2025 * that the deleted path is the same now-defunct "coordinate system"
2026 * as the path saved in the reference, which is what we want to fix.
2029 tmp_list = refs->list;
2031 while (tmp_list != NULL)
2033 GtkTreeRowReference *reference = tmp_list->data;
2035 if (reference->path)
2039 if (path->depth > reference->path->depth)
2041 for (i = 0; i < path->depth - 1; i++)
2043 if (path->indices[i] != reference->path->indices[i])
2047 /* We know it affects us. */
2048 if (path->indices[i] == reference->path->indices[i])
2050 if (reference->path->depth > path->depth)
2051 /* some parent was deleted, trying to unref any node
2052 * between the deleted parent and the node the reference
2053 * is pointing to is bad, as those nodes are already gone.
2055 gtk_tree_row_reference_unref_path (reference->path, reference->model, path->depth - 1);
2057 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth - 1);
2058 gtk_tree_path_free (reference->path);
2059 reference->path = NULL;
2061 else if (path->indices[i] < reference->path->indices[i])
2063 reference->path->indices[path->depth-1]-=1;
2068 tmp_list = g_slist_next (tmp_list);
2073 gtk_tree_row_ref_reordered (RowRefList *refs,
2084 tmp_list = refs->list;
2086 while (tmp_list != NULL)
2088 GtkTreeRowReference *reference = tmp_list->data;
2090 length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (reference->model), iter);
2095 if ((reference->path) &&
2096 (gtk_tree_path_is_ancestor (path, reference->path)))
2098 gint ref_depth = gtk_tree_path_get_depth (reference->path);
2099 gint depth = gtk_tree_path_get_depth (path);
2101 if (ref_depth > depth)
2104 gint *indices = gtk_tree_path_get_indices (reference->path);
2106 for (i = 0; i < length; i++)
2108 if (new_order[i] == indices[depth])
2117 tmp_list = g_slist_next (tmp_list);
2121 /* We do this recursively so that we can unref children nodes
2122 * before their parent
2125 gtk_tree_row_reference_unref_path_helper (GtkTreePath *path,
2126 GtkTreeModel *model,
2127 GtkTreeIter *parent_iter,
2133 if (depth == current_depth)
2136 gtk_tree_model_iter_nth_child (model, &iter, parent_iter, path->indices[current_depth]);
2137 gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, current_depth + 1);
2138 gtk_tree_model_unref_node (model, &iter);
2142 gtk_tree_row_reference_unref_path (GtkTreePath *path,
2143 GtkTreeModel *model,
2151 gtk_tree_model_iter_nth_child (model, &iter, NULL, path->indices[0]);
2152 gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, 1);
2153 gtk_tree_model_unref_node (model, &iter);
2157 * gtk_tree_row_reference_new:
2158 * @model: a #GtkTreeModel
2159 * @path: a valid #GtkTreePath to monitor
2161 * Creates a row reference based on @path.
2163 * This reference will keep pointing to the node pointed to
2164 * by @path, so long as it exists. It listens to all signals
2165 * emitted by @model, and updates its path appropriately. If
2166 * @path isn't a valid path in @model, then %NULL is returned.
2168 * Return value: a newly allocated #GtkTreeRowReference, or %NULL
2170 GtkTreeRowReference *
2171 gtk_tree_row_reference_new (GtkTreeModel *model,
2174 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2175 g_return_val_if_fail (path != NULL, NULL);
2177 /* We use the model itself as the proxy object; and call
2178 * gtk_tree_row_reference_inserted(), etc, in the
2179 * class closure (default handler) marshalers for the signal.
2181 return gtk_tree_row_reference_new_proxy (G_OBJECT (model), model, path);
2185 * gtk_tree_row_reference_new_proxy:
2186 * @proxy: a proxy #GObject
2187 * @model: a #GtkTreeModel
2188 * @path: a valid #GtkTreePath to monitor
2190 * You do not need to use this function.
2192 * Creates a row reference based on @path.
2194 * This reference will keep pointing to the node pointed to
2195 * by @path, so long as it exists. If @path isn't a valid
2196 * path in @model, then %NULL is returned. However, unlike
2197 * references created with gtk_tree_row_reference_new(), it
2198 * does not listen to the model for changes. The creator of
2199 * the row reference must do this explicitly using
2200 * gtk_tree_row_reference_inserted(), gtk_tree_row_reference_deleted(),
2201 * gtk_tree_row_reference_reordered().
2203 * These functions must be called exactly once per proxy when the
2204 * corresponding signal on the model is emitted. This single call
2205 * updates all row references for that proxy. Since built-in GTK+
2206 * objects like #GtkTreeView already use this mechanism internally,
2207 * using them as the proxy object will produce unpredictable results.
2208 * Further more, passing the same object as @model and @proxy
2209 * doesn't work for reasons of internal implementation.
2211 * This type of row reference is primarily meant by structures that
2212 * need to carefully monitor exactly when a row reference updates
2213 * itself, and is not generally needed by most applications.
2215 * Return value: a newly allocated #GtkTreeRowReference, or %NULL
2217 GtkTreeRowReference *
2218 gtk_tree_row_reference_new_proxy (GObject *proxy,
2219 GtkTreeModel *model,
2222 GtkTreeRowReference *reference;
2224 GtkTreeIter parent_iter;
2227 g_return_val_if_fail (G_IS_OBJECT (proxy), NULL);
2228 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2229 g_return_val_if_fail (path != NULL, NULL);
2230 g_return_val_if_fail (path->depth > 0, NULL);
2232 /* check that the path is valid */
2233 if (gtk_tree_model_get_iter (model, &parent_iter, path) == FALSE)
2236 /* Now we want to ref every node */
2237 gtk_tree_model_iter_nth_child (model, &parent_iter, NULL, path->indices[0]);
2238 gtk_tree_model_ref_node (model, &parent_iter);
2240 for (i = 1; i < path->depth; i++)
2243 gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, path->indices[i]);
2244 gtk_tree_model_ref_node (model, &iter);
2248 /* Make the row reference */
2249 reference = g_new (GtkTreeRowReference, 1);
2251 g_object_ref (proxy);
2252 g_object_ref (model);
2253 reference->proxy = proxy;
2254 reference->model = model;
2255 reference->path = gtk_tree_path_copy (path);
2257 refs = g_object_get_data (G_OBJECT (proxy), ROW_REF_DATA_STRING);
2261 refs = g_new (RowRefList, 1);
2264 g_object_set_data_full (G_OBJECT (proxy),
2265 I_(ROW_REF_DATA_STRING),
2266 refs, release_row_references);
2269 refs->list = g_slist_prepend (refs->list, reference);
2275 * gtk_tree_row_reference_get_path:
2276 * @reference: a #GtkTreeRowReference
2278 * Returns a path that the row reference currently points to,
2279 * or %NULL if the path pointed to is no longer valid.
2281 * Return value: a current path, or %NULL
2284 gtk_tree_row_reference_get_path (GtkTreeRowReference *reference)
2286 g_return_val_if_fail (reference != NULL, NULL);
2288 if (reference->proxy == NULL)
2291 if (reference->path == NULL)
2294 return gtk_tree_path_copy (reference->path);
2298 * gtk_tree_row_reference_get_model:
2299 * @reference: a #GtkTreeRowReference
2301 * Returns the model that the row reference is monitoring.
2303 * Return value: (transfer none): the model
2308 gtk_tree_row_reference_get_model (GtkTreeRowReference *reference)
2310 g_return_val_if_fail (reference != NULL, NULL);
2312 return reference->model;
2316 * gtk_tree_row_reference_valid:
2317 * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2319 * Returns %TRUE if the @reference is non-%NULL and refers to
2320 * a current valid path.
2322 * Return value: %TRUE if @reference points to a valid path
2325 gtk_tree_row_reference_valid (GtkTreeRowReference *reference)
2327 if (reference == NULL || reference->path == NULL)
2335 * gtk_tree_row_reference_copy:
2336 * @reference: a #GtkTreeRowReference
2338 * Copies a #GtkTreeRowReference.
2340 * Return value: a copy of @reference
2344 GtkTreeRowReference *
2345 gtk_tree_row_reference_copy (GtkTreeRowReference *reference)
2347 return gtk_tree_row_reference_new_proxy (reference->proxy,
2353 * gtk_tree_row_reference_free:
2354 * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2356 * Free's @reference. @reference may be %NULL
2359 gtk_tree_row_reference_free (GtkTreeRowReference *reference)
2363 if (reference == NULL)
2366 refs = g_object_get_data (G_OBJECT (reference->proxy), ROW_REF_DATA_STRING);
2370 g_warning (G_STRLOC": bad row reference, proxy has no outstanding row references");
2374 refs->list = g_slist_remove (refs->list, reference);
2376 if (refs->list == NULL)
2378 g_object_set_data (G_OBJECT (reference->proxy),
2379 I_(ROW_REF_DATA_STRING),
2383 if (reference->path)
2385 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth);
2386 gtk_tree_path_free (reference->path);
2389 g_object_unref (reference->proxy);
2390 g_object_unref (reference->model);
2395 * gtk_tree_row_reference_inserted:
2396 * @proxy: a #GObject
2397 * @path: the row position that was inserted
2399 * Lets a set of row reference created by
2400 * gtk_tree_row_reference_new_proxy() know that the
2401 * model emitted the #GtkTreeModel::row-inserted signal.
2404 gtk_tree_row_reference_inserted (GObject *proxy,
2407 g_return_if_fail (G_IS_OBJECT (proxy));
2409 gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, NULL);
2413 * gtk_tree_row_reference_deleted:
2414 * @proxy: a #GObject
2415 * @path: the path position that was deleted
2417 * Lets a set of row reference created by
2418 * gtk_tree_row_reference_new_proxy() know that the
2419 * model emitted the #GtkTreeModel::row-deleted signal.
2422 gtk_tree_row_reference_deleted (GObject *proxy,
2425 g_return_if_fail (G_IS_OBJECT (proxy));
2427 gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path);
2431 * gtk_tree_row_reference_reordered: (skip)
2432 * @proxy: a #GObject
2433 * @path: the parent path of the reordered signal
2434 * @iter: the iter pointing to the parent of the reordered
2435 * @new_order: the new order of rows
2437 * Lets a set of row reference created by
2438 * gtk_tree_row_reference_new_proxy() know that the
2439 * model emitted the #GtkTreeModel::rows-reordered signal.
2442 gtk_tree_row_reference_reordered (GObject *proxy,
2447 g_return_if_fail (G_IS_OBJECT (proxy));
2449 gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, iter, new_order);