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 };
225 gint depth; /* Number of elements */
226 gint alloc; /* Number of allocated elements */
235 static void gtk_tree_model_base_init (gpointer g_class);
237 /* custom closures */
238 static void row_inserted_marshal (GClosure *closure,
239 GValue /* out */ *return_value,
241 const GValue *param_values,
242 gpointer invocation_hint,
243 gpointer marshal_data);
244 static void row_deleted_marshal (GClosure *closure,
245 GValue /* out */ *return_value,
247 const GValue *param_values,
248 gpointer invocation_hint,
249 gpointer marshal_data);
250 static void rows_reordered_marshal (GClosure *closure,
251 GValue /* out */ *return_value,
253 const GValue *param_values,
254 gpointer invocation_hint,
255 gpointer marshal_data);
257 static void gtk_tree_row_ref_inserted (RowRefList *refs,
260 static void gtk_tree_row_ref_deleted (RowRefList *refs,
262 static void gtk_tree_row_ref_reordered (RowRefList *refs,
268 gtk_tree_model_get_type (void)
270 static GType tree_model_type = 0;
272 if (! tree_model_type)
274 const GTypeInfo tree_model_info =
276 sizeof (GtkTreeModelIface), /* class_size */
277 gtk_tree_model_base_init, /* base_init */
278 NULL, /* base_finalize */
280 NULL, /* class_finalize */
281 NULL, /* class_data */
288 g_type_register_static (G_TYPE_INTERFACE, I_("GtkTreeModel"),
289 &tree_model_info, 0);
291 g_type_interface_add_prerequisite (tree_model_type, G_TYPE_OBJECT);
294 return tree_model_type;
298 gtk_tree_model_base_init (gpointer g_class)
300 static gboolean initialized = FALSE;
305 GType row_inserted_params[2];
306 GType row_deleted_params[1];
307 GType rows_reordered_params[3];
309 row_inserted_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
310 row_inserted_params[1] = GTK_TYPE_TREE_ITER;
312 row_deleted_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
314 rows_reordered_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
315 rows_reordered_params[1] = GTK_TYPE_TREE_ITER;
316 rows_reordered_params[2] = G_TYPE_POINTER;
319 * GtkTreeModel::row-changed:
320 * @tree_model: the #GtkTreeModel on which the signal is emitted
321 * @path: a #GtkTreePath identifying the changed row
322 * @iter: a valid #GtkTreeIter pointing to the changed row
324 * This signal is emitted when a row in the model has changed.
326 tree_model_signals[ROW_CHANGED] =
327 g_signal_new (I_("row-changed"),
330 G_STRUCT_OFFSET (GtkTreeModelIface, row_changed),
332 _gtk_marshal_VOID__BOXED_BOXED,
334 GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE,
337 /* We need to get notification about structure changes
338 * to update row references., so instead of using the
339 * standard g_signal_new() with an offset into our interface
340 * structure, we use a customs closures for the class
341 * closures (default handlers) that first update row references
342 * and then calls the function from the interface structure.
344 * The reason we don't simply update the row references from
345 * the wrapper functions (gtk_tree_model_row_inserted(), etc.)
346 * is to keep proper ordering with respect to signal handlers
347 * connected normally and after.
351 * GtkTreeModel::row-inserted:
352 * @tree_model: the #GtkTreeModel on which the signal is emitted
353 * @path: a #GtkTreePath identifying the new row
354 * @iter: a valid #GtkTreeIter pointing to the new row
356 * This signal is emitted when a new row has been inserted in
359 * Note that the row may still be empty at this point, since
360 * it is a common pattern to first insert an empty row, and
361 * then fill it with the desired values.
363 closure = g_closure_new_simple (sizeof (GClosure), NULL);
364 g_closure_set_marshal (closure, row_inserted_marshal);
365 tree_model_signals[ROW_INSERTED] =
366 g_signal_newv (I_("row-inserted"),
371 _gtk_marshal_VOID__BOXED_BOXED,
373 row_inserted_params);
376 * GtkTreeModel::row-has-child-toggled:
377 * @tree_model: the #GtkTreeModel on which the signal is emitted
378 * @path: a #GtkTreePath identifying the row
379 * @iter: a valid #GtkTreeIter pointing to the row
381 * This signal is emitted when a row has gotten the first child
382 * row or lost its last child row.
384 tree_model_signals[ROW_HAS_CHILD_TOGGLED] =
385 g_signal_new (I_("row-has-child-toggled"),
388 G_STRUCT_OFFSET (GtkTreeModelIface, row_has_child_toggled),
390 _gtk_marshal_VOID__BOXED_BOXED,
392 GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE,
396 * GtkTreeModel::row-deleted:
397 * @tree_model: the #GtkTreeModel on which the signal is emitted
398 * @path: a #GtkTreePath identifying the row
400 * This signal is emitted when a row has been deleted.
402 * Note that no iterator is passed to the signal handler,
403 * since the row is already deleted.
405 * This should be called by models after a row has been removed.
406 * The location pointed to by @path should be the location that
407 * the row previously was at. It may not be a valid location anymore.
409 closure = g_closure_new_simple (sizeof (GClosure), NULL);
410 g_closure_set_marshal (closure, row_deleted_marshal);
411 tree_model_signals[ROW_DELETED] =
412 g_signal_newv (I_("row-deleted"),
417 _gtk_marshal_VOID__BOXED,
422 * GtkTreeModel::rows-reordered: (skip)
423 * @tree_model: the #GtkTreeModel on which the signal is emitted
424 * @path: a #GtkTreePath identifying the tree node whose children
425 * have been reordered
426 * @iter: a valid #GtkTreeIter pointing to the node whose
427 * @new_order: an array of integers mapping the current position
428 * of each child to its old position before the re-ordering,
429 * i.e. @new_order<literal>[newpos] = oldpos</literal>
431 * This signal is emitted when the children of a node in the
432 * #GtkTreeModel have been reordered.
434 * Note that this signal is <emphasis>not</emphasis> emitted
435 * when rows are reordered by DND, since this is implemented
436 * by removing and then reinserting the row.
438 closure = g_closure_new_simple (sizeof (GClosure), NULL);
439 g_closure_set_marshal (closure, rows_reordered_marshal);
440 tree_model_signals[ROWS_REORDERED] =
441 g_signal_newv (I_("rows-reordered"),
446 _gtk_marshal_VOID__BOXED_BOXED_POINTER,
448 rows_reordered_params);
454 row_inserted_marshal (GClosure *closure,
455 GValue /* out */ *return_value,
456 guint n_param_values,
457 const GValue *param_values,
458 gpointer invocation_hint,
459 gpointer marshal_data)
461 GtkTreeModelIface *iface;
463 void (* row_inserted_callback) (GtkTreeModel *tree_model,
465 GtkTreeIter *iter) = NULL;
467 GObject *model = g_value_get_object (param_values + 0);
468 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
469 GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
471 /* first, we need to update internal row references */
472 gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
475 /* fetch the interface ->row_inserted implementation */
476 iface = GTK_TREE_MODEL_GET_IFACE (model);
477 row_inserted_callback = G_STRUCT_MEMBER (gpointer, iface,
478 G_STRUCT_OFFSET (GtkTreeModelIface,
481 /* Call that default signal handler, it if has been set */
482 if (row_inserted_callback)
483 row_inserted_callback (GTK_TREE_MODEL (model), path, iter);
487 row_deleted_marshal (GClosure *closure,
488 GValue /* out */ *return_value,
489 guint n_param_values,
490 const GValue *param_values,
491 gpointer invocation_hint,
492 gpointer marshal_data)
494 GtkTreeModelIface *iface;
495 void (* row_deleted_callback) (GtkTreeModel *tree_model,
496 GtkTreePath *path) = NULL;
497 GObject *model = g_value_get_object (param_values + 0);
498 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
500 /* first, we need to update internal row references */
501 gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
504 /* fetch the interface ->row_deleted implementation */
505 iface = GTK_TREE_MODEL_GET_IFACE (model);
506 row_deleted_callback = G_STRUCT_MEMBER (gpointer, iface,
507 G_STRUCT_OFFSET (GtkTreeModelIface,
510 /* Call that default signal handler, it if has been set */
511 if (row_deleted_callback)
512 row_deleted_callback (GTK_TREE_MODEL (model), path);
516 rows_reordered_marshal (GClosure *closure,
517 GValue /* out */ *return_value,
518 guint n_param_values,
519 const GValue *param_values,
520 gpointer invocation_hint,
521 gpointer marshal_data)
523 GtkTreeModelIface *iface;
524 void (* rows_reordered_callback) (GtkTreeModel *tree_model,
529 GObject *model = g_value_get_object (param_values + 0);
530 GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
531 GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
532 gint *new_order = (gint *)g_value_get_pointer (param_values + 3);
534 /* first, we need to update internal row references */
535 gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
536 path, iter, new_order);
538 /* fetch the interface ->rows_reordered implementation */
539 iface = GTK_TREE_MODEL_GET_IFACE (model);
540 rows_reordered_callback = G_STRUCT_MEMBER (gpointer, iface,
541 G_STRUCT_OFFSET (GtkTreeModelIface,
544 /* Call that default signal handler, it if has been set */
545 if (rows_reordered_callback)
546 rows_reordered_callback (GTK_TREE_MODEL (model), path, iter, new_order);
552 * Creates a new #GtkTreePath.
553 * This structure refers to a row.
555 * Return value: A newly created #GtkTreePath.
558 gtk_tree_path_new (void)
561 retval = g_slice_new (GtkTreePath);
564 retval->indices = NULL;
570 * gtk_tree_path_new_from_string:
571 * @path: The string representation of a path
573 * Creates a new #GtkTreePath initialized to @path.
575 * @path is expected to be a colon separated list of numbers.
576 * For example, the string "10:4:0" would create a path of depth
577 * 3 pointing to the 11th child of the root node, the 5th
578 * child of that 11th child, and the 1st child of that 5th child.
579 * If an invalid path string is passed in, %NULL is returned.
581 * Return value: A newly-created #GtkTreePath, or %NULL
584 gtk_tree_path_new_from_string (const gchar *path)
587 const gchar *orig_path = path;
591 g_return_val_if_fail (path != NULL, NULL);
592 g_return_val_if_fail (*path != '\000', NULL);
594 retval = gtk_tree_path_new ();
598 i = strtol (path, &ptr, 10);
601 g_warning (G_STRLOC ": Negative numbers in path %s passed to gtk_tree_path_new_from_string", orig_path);
602 gtk_tree_path_free (retval);
606 gtk_tree_path_append_index (retval, i);
610 if (ptr == path || *ptr != ':')
612 g_warning (G_STRLOC ": Invalid path %s passed to gtk_tree_path_new_from_string", orig_path);
613 gtk_tree_path_free (retval);
623 * gtk_tree_path_new_from_indices:
624 * @first_index: first integer
625 * @varargs: list of integers terminated by -1
627 * Creates a new path with @first_index and @varargs as indices.
629 * Return value: A newly created #GtkTreePath
634 gtk_tree_path_new_from_indices (gint first_index,
641 path = gtk_tree_path_new ();
643 va_start (args, first_index);
648 gtk_tree_path_append_index (path, arg);
649 arg = va_arg (args, gint);
658 * gtk_tree_path_to_string:
659 * @path: A #GtkTreePath
661 * Generates a string representation of the path.
663 * This string is a ':' separated list of numbers.
664 * For example, "4:10:0:3" would be an acceptable
665 * return value for this string.
667 * Return value: A newly-allocated string.
668 * Must be freed with g_free().
671 gtk_tree_path_to_string (GtkTreePath *path)
673 gchar *retval, *ptr, *end;
676 g_return_val_if_fail (path != NULL, NULL);
678 if (path->depth == 0)
681 n = path->depth * 12;
682 ptr = retval = g_new0 (gchar, n);
684 g_snprintf (retval, end - ptr, "%d", path->indices[0]);
685 while (*ptr != '\000')
688 for (i = 1; i < path->depth; i++)
690 g_snprintf (ptr, end - ptr, ":%d", path->indices[i]);
691 while (*ptr != '\000')
699 * gtk_tree_path_new_first:
701 * Creates a new #GtkTreePath.
703 * The string representation of this path is "0".
705 * Return value: A new #GtkTreePath
708 gtk_tree_path_new_first (void)
712 retval = gtk_tree_path_new ();
713 gtk_tree_path_append_index (retval, 0);
719 * gtk_tree_path_append_index:
720 * @path: a #GtkTreePath
723 * Appends a new index to a path.
725 * As a result, the depth of the path is increased.
728 gtk_tree_path_append_index (GtkTreePath *path,
731 g_return_if_fail (path != NULL);
732 g_return_if_fail (index_ >= 0);
734 if (path->depth == path->alloc)
737 path->alloc = MAX (path->alloc * 2, 1);
738 indices = g_new (gint, path->alloc);
739 memcpy (indices, path->indices, path->depth * sizeof (gint));
740 g_free (path->indices);
741 path->indices = indices;
745 path->indices[path->depth - 1] = index_;
749 * gtk_tree_path_prepend_index:
750 * @path: a #GtkTreePath
753 * Prepends a new index to a path.
755 * As a result, the depth of the path is increased.
758 gtk_tree_path_prepend_index (GtkTreePath *path,
761 if (path->depth == path->alloc)
764 path->alloc = MAX (path->alloc * 2, 1);
765 indices = g_new (gint, path->alloc);
766 memcpy (indices + 1, path->indices, path->depth * sizeof (gint));
767 g_free (path->indices);
768 path->indices = indices;
770 else if (path->depth > 0)
771 memmove (path->indices + 1, path->indices, path->depth * sizeof (gint));
774 path->indices[0] = index;
778 * gtk_tree_path_get_depth:
779 * @path: a #GtkTreePath
781 * Returns the current depth of @path.
783 * Return value: The depth of @path
786 gtk_tree_path_get_depth (GtkTreePath *path)
788 g_return_val_if_fail (path != NULL, 0);
794 * gtk_tree_path_get_indices: (skip)
795 * @path: a #GtkTreePath
797 * Returns the current indices of @path.
799 * This is an array of integers, each representing a node in a tree.
800 * This value should not be freed.
802 * The length of the array can be obtained with gtk_tree_path_get_depth().
804 * Return value: The current indices, or %NULL
807 gtk_tree_path_get_indices (GtkTreePath *path)
809 g_return_val_if_fail (path != NULL, NULL);
811 return path->indices;
815 * gtk_tree_path_get_indices_with_depth:
816 * @path: a #GtkTreePath
817 * @depth: (allow-none): return location for number of elements
818 * returned in the integer array, or %NULL
820 * Returns the current indices of @path.
822 * This is an array of integers, each representing a node in a tree.
823 * It also returns the number of elements in the array.
824 * The array should not be freed.
826 * Return value: (array length=depth) (transfer none): The current
831 * Rename to: gtk_tree_path_get_indices
834 gtk_tree_path_get_indices_with_depth (GtkTreePath *path,
837 g_return_val_if_fail (path != NULL, NULL);
840 *depth = path->depth;
842 return path->indices;
846 * gtk_tree_path_free:
847 * @path: a #GtkTreePath
852 gtk_tree_path_free (GtkTreePath *path)
857 g_free (path->indices);
858 g_slice_free (GtkTreePath, path);
862 * gtk_tree_path_copy:
863 * @path: a #GtkTreePath
865 * Creates a new #GtkTreePath as a copy of @path.
867 * Return value: a new #GtkTreePath
870 gtk_tree_path_copy (const GtkTreePath *path)
874 g_return_val_if_fail (path != NULL, NULL);
876 retval = g_slice_new (GtkTreePath);
877 retval->depth = path->depth;
878 retval->alloc = retval->depth;
879 retval->indices = g_new (gint, path->alloc);
880 memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
884 G_DEFINE_BOXED_TYPE (GtkTreePath, gtk_tree_path,
889 * gtk_tree_path_compare:
891 * @b: a #GtkTreePath to compare with
893 * Compares two paths.
895 * If @a appears before @b in a tree, then -1 is returned.
896 * If @b appears before @a, then 1 is returned.
897 * If the two nodes are equal, then 0 is returned.
899 * Return value: the relative positions of @a and @b
902 gtk_tree_path_compare (const GtkTreePath *a,
903 const GtkTreePath *b)
907 g_return_val_if_fail (a != NULL, 0);
908 g_return_val_if_fail (b != NULL, 0);
909 g_return_val_if_fail (a->depth > 0, 0);
910 g_return_val_if_fail (b->depth > 0, 0);
914 if (a->indices[p] == b->indices[q])
916 return (a->indices[p] < b->indices[q]?-1:1);
918 while (++p < a->depth && ++q < b->depth);
919 if (a->depth == b->depth)
921 return (a->depth < b->depth?-1:1);
925 * gtk_tree_path_is_ancestor:
926 * @path: a #GtkTreePath
927 * @descendant: another #GtkTreePath
929 * Returns %TRUE if @descendant is a descendant of @path.
931 * Return value: %TRUE if @descendant is contained inside @path
934 gtk_tree_path_is_ancestor (GtkTreePath *path,
935 GtkTreePath *descendant)
939 g_return_val_if_fail (path != NULL, FALSE);
940 g_return_val_if_fail (descendant != NULL, FALSE);
942 /* can't be an ancestor if we're deeper */
943 if (path->depth >= descendant->depth)
947 while (i < path->depth)
949 if (path->indices[i] != descendant->indices[i])
958 * gtk_tree_path_is_descendant:
959 * @path: a #GtkTreePath
960 * @ancestor: another #GtkTreePath
962 * Returns %TRUE if @path is a descendant of @ancestor.
964 * Return value: %TRUE if @ancestor contains @path somewhere below it
967 gtk_tree_path_is_descendant (GtkTreePath *path,
968 GtkTreePath *ancestor)
972 g_return_val_if_fail (path != NULL, FALSE);
973 g_return_val_if_fail (ancestor != NULL, FALSE);
975 /* can't be a descendant if we're shallower in the tree */
976 if (path->depth <= ancestor->depth)
980 while (i < ancestor->depth)
982 if (path->indices[i] != ancestor->indices[i])
992 * gtk_tree_path_next:
993 * @path: a #GtkTreePath
995 * Moves the @path to point to the next node at the current depth.
998 gtk_tree_path_next (GtkTreePath *path)
1000 g_return_if_fail (path != NULL);
1001 g_return_if_fail (path->depth > 0);
1003 path->indices[path->depth - 1] ++;
1007 * gtk_tree_path_prev:
1008 * @path: a #GtkTreePath
1010 * Moves the @path to point to the previous node at the
1011 * current depth, if it exists.
1013 * Return value: %TRUE if @path has a previous node, and
1017 gtk_tree_path_prev (GtkTreePath *path)
1019 g_return_val_if_fail (path != NULL, FALSE);
1021 if (path->depth == 0)
1024 if (path->indices[path->depth - 1] == 0)
1027 path->indices[path->depth - 1] -= 1;
1034 * @path: a #GtkTreePath
1036 * Moves the @path to point to its parent node, if it has a parent.
1038 * Return value: %TRUE if @path has a parent, and the move was made
1041 gtk_tree_path_up (GtkTreePath *path)
1043 g_return_val_if_fail (path != NULL, FALSE);
1045 if (path->depth == 0)
1054 * gtk_tree_path_down:
1055 * @path: a #GtkTreePath
1057 * Moves @path to point to the first child of the current path.
1060 gtk_tree_path_down (GtkTreePath *path)
1062 g_return_if_fail (path != NULL);
1064 gtk_tree_path_append_index (path, 0);
1068 * gtk_tree_iter_copy:
1069 * @iter: a #GtkTreeIter
1071 * Creates a dynamically allocated tree iterator as a copy of @iter.
1073 * This function is not intended for use in applications,
1074 * because you can just copy the structs by value
1075 * (<literal>GtkTreeIter new_iter = iter;</literal>).
1076 * You must free this iter with gtk_tree_iter_free().
1078 * Return value: a newly-allocated copy of @iter
1081 gtk_tree_iter_copy (GtkTreeIter *iter)
1083 GtkTreeIter *retval;
1085 g_return_val_if_fail (iter != NULL, NULL);
1087 retval = g_slice_new (GtkTreeIter);
1094 * gtk_tree_iter_free:
1095 * @iter: a dynamically allocated tree iterator
1097 * Frees an iterator that has been allocated by gtk_tree_iter_copy().
1099 * This function is mainly used for language bindings.
1102 gtk_tree_iter_free (GtkTreeIter *iter)
1104 g_return_if_fail (iter != NULL);
1106 g_slice_free (GtkTreeIter, iter);
1109 G_DEFINE_BOXED_TYPE (GtkTreeIter, gtk_tree_iter,
1114 * gtk_tree_model_get_flags:
1115 * @tree_model: a #GtkTreeModel
1117 * Returns a set of flags supported by this interface.
1119 * The flags are a bitwise combination of #GtkTreeModelFlags.
1120 * The flags supported should not change during the lifetime
1121 * of the @tree_model.
1123 * Return value: the flags supported by this interface
1126 gtk_tree_model_get_flags (GtkTreeModel *tree_model)
1128 GtkTreeModelIface *iface;
1130 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1132 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1133 if (iface->get_flags)
1134 return (* iface->get_flags) (tree_model);
1140 * gtk_tree_model_get_n_columns:
1141 * @tree_model: a #GtkTreeModel
1143 * Returns the number of columns supported by @tree_model.
1145 * Return value: the number of columns
1148 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
1150 GtkTreeModelIface *iface;
1151 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1153 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1154 g_return_val_if_fail (iface->get_n_columns != NULL, 0);
1156 return (* iface->get_n_columns) (tree_model);
1160 * gtk_tree_model_get_column_type:
1161 * @tree_model: a #GtkTreeModel
1162 * @index_: the column index
1164 * Returns the type of the column.
1166 * Return value: (transfer none): the type of the column
1169 gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
1172 GtkTreeModelIface *iface;
1174 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
1176 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1177 g_return_val_if_fail (iface->get_column_type != NULL, G_TYPE_INVALID);
1178 g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
1180 return (* iface->get_column_type) (tree_model, index);
1184 * gtk_tree_model_get_iter:
1185 * @tree_model: a #GtkTreeModel
1186 * @iter: (out): the uninitialized #GtkTreeIter
1187 * @path: the #GtkTreePath
1189 * Sets @iter to a valid iterator pointing to @path.
1191 * Return value: %TRUE, if @iter was set
1194 gtk_tree_model_get_iter (GtkTreeModel *tree_model,
1198 GtkTreeModelIface *iface;
1200 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1201 g_return_val_if_fail (iter != NULL, FALSE);
1202 g_return_val_if_fail (path != NULL, FALSE);
1204 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1205 g_return_val_if_fail (iface->get_iter != NULL, FALSE);
1206 g_return_val_if_fail (path->depth > 0, FALSE);
1208 INITIALIZE_TREE_ITER (iter);
1210 return (* iface->get_iter) (tree_model, iter, path);
1214 * gtk_tree_model_get_iter_from_string:
1215 * @tree_model: a #GtkTreeModel
1216 * @iter: (out): an uninitialized #GtkTreeIter
1217 * @path_string: a string representation of a #GtkTreePath
1219 * Sets @iter to a valid iterator pointing to @path_string, if it
1220 * exists. Otherwise, @iter is left invalid and %FALSE is returned.
1222 * Return value: %TRUE, if @iter was set
1225 gtk_tree_model_get_iter_from_string (GtkTreeModel *tree_model,
1227 const gchar *path_string)
1232 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1233 g_return_val_if_fail (iter != NULL, FALSE);
1234 g_return_val_if_fail (path_string != NULL, FALSE);
1236 path = gtk_tree_path_new_from_string (path_string);
1238 g_return_val_if_fail (path != NULL, FALSE);
1240 retval = gtk_tree_model_get_iter (tree_model, iter, path);
1241 gtk_tree_path_free (path);
1247 * gtk_tree_model_get_string_from_iter:
1248 * @tree_model: a #GtkTreeModel
1249 * @iter: a #GtkTreeIter
1251 * Generates a string representation of the iter.
1253 * This string is a ':' separated list of numbers.
1254 * For example, "4:10:0:3" would be an acceptable
1255 * return value for this string.
1257 * Return value: a newly-allocated string.
1258 * Must be freed with g_free().
1263 gtk_tree_model_get_string_from_iter (GtkTreeModel *tree_model,
1269 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1270 g_return_val_if_fail (iter != NULL, NULL);
1272 path = gtk_tree_model_get_path (tree_model, iter);
1274 g_return_val_if_fail (path != NULL, NULL);
1276 ret = gtk_tree_path_to_string (path);
1277 gtk_tree_path_free (path);
1283 * gtk_tree_model_get_iter_first:
1284 * @tree_model: a #GtkTreeModel
1285 * @iter: (out): the uninitialized #GtkTreeIter
1287 * Initializes @iter with the first iterator in the tree
1288 * (the one at the path "0") and returns %TRUE. Returns
1289 * %FALSE if the tree is empty.
1291 * Return value: %TRUE, if @iter was set
1294 gtk_tree_model_get_iter_first (GtkTreeModel *tree_model,
1300 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1301 g_return_val_if_fail (iter != NULL, FALSE);
1303 path = gtk_tree_path_new_first ();
1304 retval = gtk_tree_model_get_iter (tree_model, iter, path);
1305 gtk_tree_path_free (path);
1311 * gtk_tree_model_get_path:
1312 * @tree_model: a #GtkTreeModel
1313 * @iter: the #GtkTreeIter
1315 * Returns a newly-created #GtkTreePath referenced by @iter.
1317 * This path should be freed with gtk_tree_path_free().
1319 * Return value: a newly-created #GtkTreePath
1322 gtk_tree_model_get_path (GtkTreeModel *tree_model,
1325 GtkTreeModelIface *iface;
1327 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1328 g_return_val_if_fail (iter != NULL, NULL);
1330 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1331 g_return_val_if_fail (iface->get_path != NULL, NULL);
1333 return (* iface->get_path) (tree_model, iter);
1337 * gtk_tree_model_get_value:
1338 * @tree_model: a #GtkTreeModel
1339 * @iter: the #GtkTreeIter
1340 * @column: the column to lookup the value at
1341 * @value: (out) (transfer none): an empty #GValue to set
1343 * Initializes and sets @value to that at @column.
1345 * When done with @value, g_value_unset() needs to be called
1346 * to free any allocated memory.
1349 gtk_tree_model_get_value (GtkTreeModel *tree_model,
1354 GtkTreeModelIface *iface;
1356 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1357 g_return_if_fail (iter != NULL);
1358 g_return_if_fail (value != NULL);
1360 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1361 g_return_if_fail (iface->get_value != NULL);
1363 (* iface->get_value) (tree_model, iter, column, value);
1367 * gtk_tree_model_iter_next:
1368 * @tree_model: a #GtkTreeModel
1369 * @iter: (in): the #GtkTreeIter
1371 * Sets @iter to point to the node following it at the current level.
1373 * If there is no next @iter, %FALSE is returned and @iter is set
1376 * Return value: %TRUE if @iter has been changed to the next node
1379 gtk_tree_model_iter_next (GtkTreeModel *tree_model,
1382 GtkTreeModelIface *iface;
1384 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1385 g_return_val_if_fail (iter != NULL, FALSE);
1387 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1388 g_return_val_if_fail (iface->iter_next != NULL, FALSE);
1390 return (* iface->iter_next) (tree_model, iter);
1394 gtk_tree_model_iter_previous_default (GtkTreeModel *tree_model,
1400 path = gtk_tree_model_get_path (tree_model, iter);
1404 retval = gtk_tree_path_prev (path) &&
1405 gtk_tree_model_get_iter (tree_model, iter, path);
1406 if (retval == FALSE)
1409 gtk_tree_path_free (path);
1415 * gtk_tree_model_iter_previous:
1416 * @tree_model: a #GtkTreeModel
1417 * @iter: (in): the #GtkTreeIter
1419 * Sets @iter to point to the previous node at the current level.
1421 * If there is no previous @iter, %FALSE is returned and @iter is
1422 * set to be invalid.
1424 * Return value: %TRUE if @iter has been changed to the previous node
1429 gtk_tree_model_iter_previous (GtkTreeModel *tree_model,
1433 GtkTreeModelIface *iface;
1435 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1436 g_return_val_if_fail (iter != NULL, FALSE);
1438 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1440 if (iface->iter_previous)
1441 retval = (* iface->iter_previous) (tree_model, iter);
1443 retval = gtk_tree_model_iter_previous_default (tree_model, iter);
1449 * gtk_tree_model_iter_children:
1450 * @tree_model: a #GtkTreeModel
1451 * @iter: (out): the new #GtkTreeIter to be set to the child
1452 * @parent: (allow-none): the #GtkTreeIter, or %NULL
1454 * Sets @iter to point to the first child of @parent.
1456 * If @parent has no children, %FALSE is returned and @iter is
1457 * set to be invalid. @parent will remain a valid node after this
1458 * function has been called.
1460 * If @parent is %NULL returns the first node, equivalent to
1461 * <literal>gtk_tree_model_get_iter_first (tree_model, iter);</literal>
1463 * Return value: %TRUE, if @child has been set to the first child
1466 gtk_tree_model_iter_children (GtkTreeModel *tree_model,
1468 GtkTreeIter *parent)
1470 GtkTreeModelIface *iface;
1472 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1473 g_return_val_if_fail (iter != NULL, FALSE);
1475 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1476 g_return_val_if_fail (iface->iter_children != NULL, FALSE);
1478 INITIALIZE_TREE_ITER (iter);
1480 return (* iface->iter_children) (tree_model, iter, parent);
1484 * gtk_tree_model_iter_has_child:
1485 * @tree_model: a #GtkTreeModel
1486 * @iter: the #GtkTreeIter to test for children
1488 * Returns %TRUE if @iter has children, %FALSE otherwise.
1490 * Return value: %TRUE if @iter has children
1493 gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
1496 GtkTreeModelIface *iface;
1498 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1499 g_return_val_if_fail (iter != NULL, FALSE);
1501 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1502 g_return_val_if_fail (iface->iter_has_child != NULL, FALSE);
1504 return (* iface->iter_has_child) (tree_model, iter);
1508 * gtk_tree_model_iter_n_children:
1509 * @tree_model: a #GtkTreeModel
1510 * @iter: (allow-none): the #GtkTreeIter, or %NULL
1512 * Returns the number of children that @iter has.
1514 * As a special case, if @iter is %NULL, then the number
1515 * of toplevel nodes is returned.
1517 * Return value: the number of children of @iter
1520 gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
1523 GtkTreeModelIface *iface;
1525 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1527 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1528 g_return_val_if_fail (iface->iter_n_children != NULL, 0);
1530 return (* iface->iter_n_children) (tree_model, iter);
1534 * gtk_tree_model_iter_nth_child:
1535 * @tree_model: a #GtkTreeModel
1536 * @iter: (out): the #GtkTreeIter to set to the nth child
1537 * @parent: (allow-none): the #GtkTreeIter to get the child from, or %NULL.
1538 * @n: the index of the desired child
1540 * Sets @iter to be the child of @parent, using the given index.
1542 * The first index is 0. If @n is too big, or @parent has no children,
1543 * @iter is set to an invalid iterator and %FALSE is returned. @parent
1544 * will remain a valid node after this function has been called. As a
1545 * special case, if @parent is %NULL, then the @n<!-- -->th root node
1548 * Return value: %TRUE, if @parent has an @n<!-- -->th child
1551 gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
1553 GtkTreeIter *parent,
1556 GtkTreeModelIface *iface;
1558 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1559 g_return_val_if_fail (iter != NULL, FALSE);
1560 g_return_val_if_fail (n >= 0, FALSE);
1562 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1563 g_return_val_if_fail (iface->iter_nth_child != NULL, FALSE);
1565 INITIALIZE_TREE_ITER (iter);
1567 return (* iface->iter_nth_child) (tree_model, iter, parent, n);
1571 * gtk_tree_model_iter_parent:
1572 * @tree_model: a #GtkTreeModel
1573 * @iter: (out): the new #GtkTreeIter to set to the parent
1574 * @child: the #GtkTreeIter
1576 * Sets @iter to be the parent of @child.
1578 * If @child is at the toplevel, and doesn't have a parent, then
1579 * @iter is set to an invalid iterator and %FALSE is returned.
1580 * @child will remain a valid node after this function has been
1583 * Return value: %TRUE, if @iter is set to the parent of @child
1586 gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
1590 GtkTreeModelIface *iface;
1592 g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1593 g_return_val_if_fail (iter != NULL, FALSE);
1594 g_return_val_if_fail (child != NULL, FALSE);
1596 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1597 g_return_val_if_fail (iface->iter_parent != NULL, FALSE);
1599 INITIALIZE_TREE_ITER (iter);
1601 return (* iface->iter_parent) (tree_model, iter, child);
1605 * gtk_tree_model_ref_node:
1606 * @tree_model: a #GtkTreeModel
1607 * @iter: the #GtkTreeIter
1609 * Lets the tree ref the node.
1611 * This is an optional method for models to implement.
1612 * To be more specific, models may ignore this call as it exists
1613 * primarily for performance reasons.
1615 * This function is primarily meant as a way for views to let
1616 * caching models know when nodes are being displayed (and hence,
1617 * whether or not to cache that node). For example, a file-system
1618 * based model would not want to keep the entire file-hierarchy in
1619 * memory, just the sections that are currently being displayed by
1620 * every current view.
1622 * A model should be expected to be able to get an iter independent
1623 * of its reffed state.
1626 gtk_tree_model_ref_node (GtkTreeModel *tree_model,
1629 GtkTreeModelIface *iface;
1631 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1633 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1634 if (iface->ref_node)
1635 (* iface->ref_node) (tree_model, iter);
1639 * gtk_tree_model_unref_node:
1640 * @tree_model: a #GtkTreeModel
1641 * @iter: the #GtkTreeIter
1643 * Lets the tree unref the node.
1645 * This is an optional method for models to implement.
1646 * To be more specific, models may ignore this call as it exists
1647 * primarily for performance reasons. For more information on what
1648 * this means, see gtk_tree_model_ref_node().
1650 * Please note that nodes that are deleted are not unreffed.
1653 gtk_tree_model_unref_node (GtkTreeModel *tree_model,
1656 GtkTreeModelIface *iface;
1658 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1659 g_return_if_fail (iter != NULL);
1661 iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1662 if (iface->unref_node)
1663 (* iface->unref_node) (tree_model, iter);
1667 * gtk_tree_model_get:
1668 * @tree_model: a #GtkTreeModel
1669 * @iter: a row in @tree_model
1670 * @Varargs: pairs of column number and value return locations,
1673 * Gets the value of one or more cells in the row referenced by @iter.
1674 * The variable argument list should contain integer column numbers,
1675 * each column number followed by a place to store the value being
1676 * retrieved. The list is terminated by a -1. For example, to get a
1677 * value from column 0 with type %G_TYPE_STRING, you would
1678 * write: <literal>gtk_tree_model_get (model, iter, 0, &place_string_here, -1)</literal>,
1679 * where <literal>place_string_here</literal> is a <type>gchar*</type>
1680 * to be filled with the string.
1682 * Returned values with type %G_TYPE_OBJECT have to be unreferenced,
1683 * values with type %G_TYPE_STRING or %G_TYPE_BOXED have to be freed.
1684 * Other values are passed by value.
1687 gtk_tree_model_get (GtkTreeModel *tree_model,
1693 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1694 g_return_if_fail (iter != NULL);
1696 va_start (var_args, iter);
1697 gtk_tree_model_get_valist (tree_model, iter, var_args);
1702 * gtk_tree_model_get_valist:
1703 * @tree_model: a #GtkTreeModel
1704 * @iter: a row in @tree_model
1705 * @var_args: <type>va_list</type> of column/return location pairs
1707 * See gtk_tree_model_get(), this version takes a <type>va_list</type>
1708 * for language bindings to use.
1711 gtk_tree_model_get_valist (GtkTreeModel *tree_model,
1717 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1718 g_return_if_fail (iter != NULL);
1720 column = va_arg (var_args, gint);
1722 while (column != -1)
1724 GValue value = { 0, };
1725 gchar *error = NULL;
1727 if (column >= gtk_tree_model_get_n_columns (tree_model))
1729 g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
1733 gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, column, &value);
1735 G_VALUE_LCOPY (&value, var_args, 0, &error);
1738 g_warning ("%s: %s", G_STRLOC, error);
1741 /* we purposely leak the value here, it might not be
1742 * in a sane state if an error condition occurred
1747 g_value_unset (&value);
1749 column = va_arg (var_args, gint);
1754 * gtk_tree_model_row_changed:
1755 * @tree_model: a #GtkTreeModel
1756 * @path: a #GtkTreePath pointing to the changed row
1757 * @iter: a valid #GtkTreeIter pointing to the changed row
1759 * Emits the #GtkTreeModel::row-changed signal on @tree_model.
1762 gtk_tree_model_row_changed (GtkTreeModel *tree_model,
1766 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1767 g_return_if_fail (path != NULL);
1768 g_return_if_fail (iter != NULL);
1770 g_signal_emit (tree_model, tree_model_signals[ROW_CHANGED], 0, path, iter);
1774 * gtk_tree_model_row_inserted:
1775 * @tree_model: a #GtkTreeModel
1776 * @path: a #GtkTreePath pointing to the inserted row
1777 * @iter: a valid #GtkTreeIter pointing to the inserted row
1779 * Emits the #GtkTreeModel::row-inserted signal on @tree_model.
1782 gtk_tree_model_row_inserted (GtkTreeModel *tree_model,
1786 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1787 g_return_if_fail (path != NULL);
1788 g_return_if_fail (iter != NULL);
1790 g_signal_emit (tree_model, tree_model_signals[ROW_INSERTED], 0, path, iter);
1794 * gtk_tree_model_row_has_child_toggled:
1795 * @tree_model: a #GtkTreeModel
1796 * @path: a #GtkTreePath pointing to the changed row
1797 * @iter: a valid #GtkTreeIter pointing to the changed row
1799 * Emits the #GtkTreeModel::row-has-child-toggled signal on
1800 * @tree_model. This should be called by models after the child
1801 * state of a node changes.
1804 gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model,
1808 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1809 g_return_if_fail (path != NULL);
1810 g_return_if_fail (iter != NULL);
1812 g_signal_emit (tree_model, tree_model_signals[ROW_HAS_CHILD_TOGGLED], 0, path, iter);
1816 * gtk_tree_model_row_deleted:
1817 * @tree_model: a #GtkTreeModel
1818 * @path: a #GtkTreePath pointing to the previous location of
1821 * Emits the #GtkTreeModel::row-deleted signal on @tree_model.
1823 * This should be called by models after a row has been removed.
1824 * The location pointed to by @path should be the location that
1825 * the row previously was at. It may not be a valid location anymore.
1828 gtk_tree_model_row_deleted (GtkTreeModel *tree_model,
1831 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1832 g_return_if_fail (path != NULL);
1834 g_signal_emit (tree_model, tree_model_signals[ROW_DELETED], 0, path);
1838 * gtk_tree_model_rows_reordered: (skip)
1839 * @tree_model: a #GtkTreeModel
1840 * @path: a #GtkTreePath pointing to the tree node whose children
1841 * have been reordered
1842 * @iter: a valid #GtkTreeIter pointing to the node whose children
1843 * have been reordered, or %NULL if the depth of @path is 0
1844 * @new_order: an array of integers mapping the current position of
1845 * each child to its old position before the re-ordering,
1846 * i.e. @new_order<literal>[newpos] = oldpos</literal>
1848 * Emits the #GtkTreeModel::rows-reordered signal on @tree_model.
1850 * This should be called by models when their rows have been
1854 gtk_tree_model_rows_reordered (GtkTreeModel *tree_model,
1859 g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1860 g_return_if_fail (new_order != NULL);
1862 g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1867 gtk_tree_model_foreach_helper (GtkTreeModel *model,
1870 GtkTreeModelForeachFunc func,
1877 if ((* func) (model, path, iter, user_data))
1880 if (gtk_tree_model_iter_children (model, &child, iter))
1882 gtk_tree_path_down (path);
1883 if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
1885 gtk_tree_path_up (path);
1888 gtk_tree_path_next (path);
1890 while (gtk_tree_model_iter_next (model, iter));
1896 * gtk_tree_model_foreach:
1897 * @model: a #GtkTreeModel
1898 * @func: (scope call): a function to be called on each row
1899 * @user_data: user data to passed to @func
1901 * Calls func on each node in model in a depth-first fashion.
1903 * If @func returns %TRUE, then the tree ceases to be walked,
1904 * and gtk_tree_model_foreach() returns.
1907 gtk_tree_model_foreach (GtkTreeModel *model,
1908 GtkTreeModelForeachFunc func,
1914 g_return_if_fail (GTK_IS_TREE_MODEL (model));
1915 g_return_if_fail (func != NULL);
1917 path = gtk_tree_path_new_first ();
1918 if (gtk_tree_model_get_iter (model, &iter, path) == FALSE)
1920 gtk_tree_path_free (path);
1924 gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
1925 gtk_tree_path_free (path);
1930 * GtkTreeRowReference
1933 static void gtk_tree_row_reference_unref_path (GtkTreePath *path,
1934 GtkTreeModel *model,
1938 G_DEFINE_BOXED_TYPE (GtkTreeRowReference, gtk_tree_row_reference,
1939 gtk_tree_row_reference_copy,
1940 gtk_tree_row_reference_free)
1942 struct _GtkTreeRowReference
1945 GtkTreeModel *model;
1951 release_row_references (gpointer data)
1953 RowRefList *refs = data;
1954 GSList *tmp_list = NULL;
1956 tmp_list = refs->list;
1957 while (tmp_list != NULL)
1959 GtkTreeRowReference *reference = tmp_list->data;
1961 if (reference->proxy == (GObject *)reference->model)
1962 reference->model = NULL;
1963 reference->proxy = NULL;
1965 /* we don't free the reference, users are responsible for that. */
1967 tmp_list = g_slist_next (tmp_list);
1970 g_slist_free (refs->list);
1975 gtk_tree_row_ref_inserted (RowRefList *refs,
1984 /* This function corrects the path stored in the reference to
1985 * account for an insertion. Note that it's called _after_ the
1986 * insertion with the path to the newly-inserted row. Which means
1987 * that the inserted path is in a different "coordinate system" than
1988 * the old path (e.g. if the inserted path was just before the old
1989 * path, then inserted path and old path will be the same, and old
1990 * path must be moved down one).
1993 tmp_list = refs->list;
1995 while (tmp_list != NULL)
1997 GtkTreeRowReference *reference = tmp_list->data;
1999 if (reference->path == NULL)
2002 if (reference->path->depth >= path->depth)
2005 gboolean ancestor = TRUE;
2007 for (i = 0; i < path->depth - 1; i ++)
2009 if (path->indices[i] != reference->path->indices[i])
2015 if (ancestor == FALSE)
2018 if (path->indices[path->depth-1] <= reference->path->indices[path->depth-1])
2019 reference->path->indices[path->depth-1] += 1;
2022 tmp_list = g_slist_next (tmp_list);
2027 gtk_tree_row_ref_deleted (RowRefList *refs,
2035 /* This function corrects the path stored in the reference to
2036 * account for an deletion. Note that it's called _after_ the
2037 * deletion with the old path of the just-deleted row. Which means
2038 * that the deleted path is the same now-defunct "coordinate system"
2039 * as the path saved in the reference, which is what we want to fix.
2042 tmp_list = refs->list;
2044 while (tmp_list != NULL)
2046 GtkTreeRowReference *reference = tmp_list->data;
2048 if (reference->path)
2052 if (path->depth > reference->path->depth)
2054 for (i = 0; i < path->depth - 1; i++)
2056 if (path->indices[i] != reference->path->indices[i])
2060 /* We know it affects us. */
2061 if (path->indices[i] == reference->path->indices[i])
2063 if (reference->path->depth > path->depth)
2064 /* some parent was deleted, trying to unref any node
2065 * between the deleted parent and the node the reference
2066 * is pointing to is bad, as those nodes are already gone.
2068 gtk_tree_row_reference_unref_path (reference->path, reference->model, path->depth - 1);
2070 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth - 1);
2071 gtk_tree_path_free (reference->path);
2072 reference->path = NULL;
2074 else if (path->indices[i] < reference->path->indices[i])
2076 reference->path->indices[path->depth-1]-=1;
2081 tmp_list = g_slist_next (tmp_list);
2086 gtk_tree_row_ref_reordered (RowRefList *refs,
2097 tmp_list = refs->list;
2099 while (tmp_list != NULL)
2101 GtkTreeRowReference *reference = tmp_list->data;
2103 length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (reference->model), iter);
2108 if ((reference->path) &&
2109 (gtk_tree_path_is_ancestor (path, reference->path)))
2111 gint ref_depth = gtk_tree_path_get_depth (reference->path);
2112 gint depth = gtk_tree_path_get_depth (path);
2114 if (ref_depth > depth)
2117 gint *indices = gtk_tree_path_get_indices (reference->path);
2119 for (i = 0; i < length; i++)
2121 if (new_order[i] == indices[depth])
2130 tmp_list = g_slist_next (tmp_list);
2134 /* We do this recursively so that we can unref children nodes
2135 * before their parent
2138 gtk_tree_row_reference_unref_path_helper (GtkTreePath *path,
2139 GtkTreeModel *model,
2140 GtkTreeIter *parent_iter,
2146 if (depth == current_depth)
2149 gtk_tree_model_iter_nth_child (model, &iter, parent_iter, path->indices[current_depth]);
2150 gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, current_depth + 1);
2151 gtk_tree_model_unref_node (model, &iter);
2155 gtk_tree_row_reference_unref_path (GtkTreePath *path,
2156 GtkTreeModel *model,
2164 gtk_tree_model_iter_nth_child (model, &iter, NULL, path->indices[0]);
2165 gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, 1);
2166 gtk_tree_model_unref_node (model, &iter);
2170 * gtk_tree_row_reference_new:
2171 * @model: a #GtkTreeModel
2172 * @path: a valid #GtkTreePath to monitor
2174 * Creates a row reference based on @path.
2176 * This reference will keep pointing to the node pointed to
2177 * by @path, so long as it exists. It listens to all signals
2178 * emitted by @model, and updates its path appropriately. If
2179 * @path isn't a valid path in @model, then %NULL is returned.
2181 * Return value: a newly allocated #GtkTreeRowReference, or %NULL
2183 GtkTreeRowReference *
2184 gtk_tree_row_reference_new (GtkTreeModel *model,
2187 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2188 g_return_val_if_fail (path != NULL, NULL);
2190 /* We use the model itself as the proxy object; and call
2191 * gtk_tree_row_reference_inserted(), etc, in the
2192 * class closure (default handler) marshalers for the signal.
2194 return gtk_tree_row_reference_new_proxy (G_OBJECT (model), model, path);
2198 * gtk_tree_row_reference_new_proxy:
2199 * @proxy: a proxy #GObject
2200 * @model: a #GtkTreeModel
2201 * @path: a valid #GtkTreePath to monitor
2203 * You do not need to use this function.
2205 * Creates a row reference based on @path.
2207 * This reference will keep pointing to the node pointed to
2208 * by @path, so long as it exists. If @path isn't a valid
2209 * path in @model, then %NULL is returned. However, unlike
2210 * references created with gtk_tree_row_reference_new(), it
2211 * does not listen to the model for changes. The creator of
2212 * the row reference must do this explicitly using
2213 * gtk_tree_row_reference_inserted(), gtk_tree_row_reference_deleted(),
2214 * gtk_tree_row_reference_reordered().
2216 * These functions must be called exactly once per proxy when the
2217 * corresponding signal on the model is emitted. This single call
2218 * updates all row references for that proxy. Since built-in GTK+
2219 * objects like #GtkTreeView already use this mechanism internally,
2220 * using them as the proxy object will produce unpredictable results.
2221 * Further more, passing the same object as @model and @proxy
2222 * doesn't work for reasons of internal implementation.
2224 * This type of row reference is primarily meant by structures that
2225 * need to carefully monitor exactly when a row reference updates
2226 * itself, and is not generally needed by most applications.
2228 * Return value: a newly allocated #GtkTreeRowReference, or %NULL
2230 GtkTreeRowReference *
2231 gtk_tree_row_reference_new_proxy (GObject *proxy,
2232 GtkTreeModel *model,
2235 GtkTreeRowReference *reference;
2237 GtkTreeIter parent_iter;
2240 g_return_val_if_fail (G_IS_OBJECT (proxy), NULL);
2241 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2242 g_return_val_if_fail (path != NULL, NULL);
2243 g_return_val_if_fail (path->depth > 0, NULL);
2245 /* check that the path is valid */
2246 if (gtk_tree_model_get_iter (model, &parent_iter, path) == FALSE)
2249 /* Now we want to ref every node */
2250 gtk_tree_model_iter_nth_child (model, &parent_iter, NULL, path->indices[0]);
2251 gtk_tree_model_ref_node (model, &parent_iter);
2253 for (i = 1; i < path->depth; i++)
2256 gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, path->indices[i]);
2257 gtk_tree_model_ref_node (model, &iter);
2261 /* Make the row reference */
2262 reference = g_new (GtkTreeRowReference, 1);
2264 g_object_ref (proxy);
2265 g_object_ref (model);
2266 reference->proxy = proxy;
2267 reference->model = model;
2268 reference->path = gtk_tree_path_copy (path);
2270 refs = g_object_get_data (G_OBJECT (proxy), ROW_REF_DATA_STRING);
2274 refs = g_new (RowRefList, 1);
2277 g_object_set_data_full (G_OBJECT (proxy),
2278 I_(ROW_REF_DATA_STRING),
2279 refs, release_row_references);
2282 refs->list = g_slist_prepend (refs->list, reference);
2288 * gtk_tree_row_reference_get_path:
2289 * @reference: a #GtkTreeRowReference
2291 * Returns a path that the row reference currently points to,
2292 * or %NULL if the path pointed to is no longer valid.
2294 * Return value: a current path, or %NULL
2297 gtk_tree_row_reference_get_path (GtkTreeRowReference *reference)
2299 g_return_val_if_fail (reference != NULL, NULL);
2301 if (reference->proxy == NULL)
2304 if (reference->path == NULL)
2307 return gtk_tree_path_copy (reference->path);
2311 * gtk_tree_row_reference_get_model:
2312 * @reference: a #GtkTreeRowReference
2314 * Returns the model that the row reference is monitoring.
2316 * Return value: (transfer none): the model
2321 gtk_tree_row_reference_get_model (GtkTreeRowReference *reference)
2323 g_return_val_if_fail (reference != NULL, NULL);
2325 return reference->model;
2329 * gtk_tree_row_reference_valid:
2330 * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2332 * Returns %TRUE if the @reference is non-%NULL and refers to
2333 * a current valid path.
2335 * Return value: %TRUE if @reference points to a valid path
2338 gtk_tree_row_reference_valid (GtkTreeRowReference *reference)
2340 if (reference == NULL || reference->path == NULL)
2348 * gtk_tree_row_reference_copy:
2349 * @reference: a #GtkTreeRowReference
2351 * Copies a #GtkTreeRowReference.
2353 * Return value: a copy of @reference
2357 GtkTreeRowReference *
2358 gtk_tree_row_reference_copy (GtkTreeRowReference *reference)
2360 return gtk_tree_row_reference_new_proxy (reference->proxy,
2366 * gtk_tree_row_reference_free:
2367 * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2369 * Free's @reference. @reference may be %NULL
2372 gtk_tree_row_reference_free (GtkTreeRowReference *reference)
2376 if (reference == NULL)
2379 refs = g_object_get_data (G_OBJECT (reference->proxy), ROW_REF_DATA_STRING);
2383 g_warning (G_STRLOC": bad row reference, proxy has no outstanding row references");
2387 refs->list = g_slist_remove (refs->list, reference);
2389 if (refs->list == NULL)
2391 g_object_set_data (G_OBJECT (reference->proxy),
2392 I_(ROW_REF_DATA_STRING),
2396 if (reference->path)
2398 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth);
2399 gtk_tree_path_free (reference->path);
2402 g_object_unref (reference->proxy);
2403 g_object_unref (reference->model);
2408 * gtk_tree_row_reference_inserted:
2409 * @proxy: a #GObject
2410 * @path: the row position that was inserted
2412 * Lets a set of row reference created by
2413 * gtk_tree_row_reference_new_proxy() know that the
2414 * model emitted the #GtkTreeModel::row-inserted signal.
2417 gtk_tree_row_reference_inserted (GObject *proxy,
2420 g_return_if_fail (G_IS_OBJECT (proxy));
2422 gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, NULL);
2426 * gtk_tree_row_reference_deleted:
2427 * @proxy: a #GObject
2428 * @path: the path position that was deleted
2430 * Lets a set of row reference created by
2431 * gtk_tree_row_reference_new_proxy() know that the
2432 * model emitted the #GtkTreeModel::row-deleted signal.
2435 gtk_tree_row_reference_deleted (GObject *proxy,
2438 g_return_if_fail (G_IS_OBJECT (proxy));
2440 gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path);
2444 * gtk_tree_row_reference_reordered: (skip)
2445 * @proxy: a #GObject
2446 * @path: the parent path of the reordered signal
2447 * @iter: the iter pointing to the parent of the reordered
2448 * @new_order: the new order of rows
2450 * Lets a set of row reference created by
2451 * gtk_tree_row_reference_new_proxy() know that the
2452 * model emitted the #GtkTreeModel::rows-reordered signal.
2455 gtk_tree_row_reference_reordered (GObject *proxy,
2460 g_return_if_fail (G_IS_OBJECT (proxy));
2462 gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, iter, new_order);