1 /* gtktreemodel.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
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.
8  *
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.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "config.h"
19 #include <stdlib.h>
20 #include <string.h>
21 #include <glib.h>
22 #include <glib/gprintf.h>
23 #include <gobject/gvaluecollector.h>
24 #include "gtktreemodel.h"
25 #include "gtktreeview.h"
26 #include "gtktreeprivate.h"
27 #include "gtkmarshalers.h"
28 #include "gtkintl.h"
29 
30 /**
31  * SECTION:gtktreemodel
32  * @Title: GtkTreeModel
33  * @Short_description: The tree interface used by GtkTreeView
34  * @See_also: #GtkTreeView, #GtkTreeStore, #GtkListStore,
35  *     [GtkTreeView drag-and-drop][gtk3-GtkTreeView-drag-and-drop]
36  *     #GtkTreeSortable
37  *
38  * The #GtkTreeModel interface defines a generic tree interface for
39  * use by the #GtkTreeView widget. It is an abstract interface, and
40  * is designed to be usable with any appropriate data structure. The
41  * programmer just has to implement this interface on their own data
42  * type for it to be viewable by a #GtkTreeView widget.
43  *
44  * The model is represented as a hierarchical tree of strongly-typed,
45  * columned data. In other words, the model can be seen as a tree where
46  * every node has different values depending on which column is being
47  * queried. The type of data found in a column is determined by using
48  * the GType system (ie. #G_TYPE_INT, #GTK_TYPE_BUTTON, #G_TYPE_POINTER,
49  * etc). The types are homogeneous per column across all nodes. It is
50  * important to note that this interface only provides a way of examining
51  * a model and observing changes. The implementation of each individual
52  * model decides how and if changes are made.
53  *
54  * In order to make life simpler for programmers who do not need to
55  * write their own specialized model, two generic models are provided
56  * — the #GtkTreeStore and the #GtkListStore. To use these, the
57  * developer simply pushes data into these models as necessary. These
58  * models provide the data structure as well as all appropriate tree
59  * interfaces. As a result, implementing drag and drop, sorting, and
60  * storing data is trivial. For the vast majority of trees and lists,
61  * these two models are sufficient.
62  *
63  * Models are accessed on a node/column level of granularity. One can
64  * query for the value of a model at a certain node and a certain
65  * column on that node. There are two structures used to reference a
66  * particular node in a model. They are the #GtkTreePath-struct and
67  * the #GtkTreeIter-struct (“iter” is short for iterator). Most of the
68  * interface consists of operations on a #GtkTreeIter-struct.
69  *
70  * A path is essentially a potential node. It is a location on a model
71  * that may or may not actually correspond to a node on a specific
72  * model. The #GtkTreePath-struct can be converted into either an
73  * array of unsigned integers or a string. The string form is a list
74  * of numbers separated by a colon. Each number refers to the offset
75  * at that level. Thus, the path `0` refers to the root
76  * node and the path `2:4` refers to the fifth child of
77  * the third node.
78  *
79  * By contrast, a #GtkTreeIter-struct is a reference to a specific node on
80  * a specific model. It is a generic struct with an integer and three
81  * generic pointers. These are filled in by the model in a model-specific
82  * way. One can convert a path to an iterator by calling
83  * gtk_tree_model_get_iter(). These iterators are the primary way
84  * of accessing a model and are similar to the iterators used by
85  * #GtkTextBuffer. They are generally statically allocated on the
86  * stack and only used for a short time. The model interface defines
87  * a set of operations using them for navigating the model.
88  *
89  * It is expected that models fill in the iterator with private data.
90  * For example, the #GtkListStore model, which is internally a simple
91  * linked list, stores a list node in one of the pointers. The
92  * #GtkTreeModelSort stores an array and an offset in two of the
93  * pointers. Additionally, there is an integer field. This field is
94  * generally filled with a unique stamp per model. This stamp is for
95  * catching errors resulting from using invalid iterators with a model.
96  *
97  * The lifecycle of an iterator can be a little confusing at first.
98  * Iterators are expected to always be valid for as long as the model
99  * is unchanged (and doesn’t emit a signal). The model is considered
100  * to own all outstanding iterators and nothing needs to be done to
101  * free them from the user’s point of view. Additionally, some models
102  * guarantee that an iterator is valid for as long as the node it refers
103  * to is valid (most notably the #GtkTreeStore and #GtkListStore).
104  * Although generally uninteresting, as one always has to allow for
105  * the case where iterators do not persist beyond a signal, some very
106  * important performance enhancements were made in the sort model.
107  * As a result, the #GTK_TREE_MODEL_ITERS_PERSIST flag was added to
108  * indicate this behavior.
109  *
110  * To help show some common operation of a model, some examples are
111  * provided. The first example shows three ways of getting the iter at
112  * the location `3:2:5`. While the first method shown is
113  * easier, the second is much more common, as you often get paths from
114  * callbacks.
115  *
116  * ## Acquiring a #GtkTreeIter-struct
117  *
118  * |[<!-- language="C" -->
119  * // Three ways of getting the iter pointing to the location
120  * GtkTreePath *path;
121  * GtkTreeIter iter;
122  * GtkTreeIter parent_iter;
123  *
124  * // get the iterator from a string
125  * gtk_tree_model_get_iter_from_string (model,
126  *                                      &iter,
127  *                                      "3:2:5");
128  *
129  * // get the iterator from a path
130  * path = gtk_tree_path_new_from_string ("3:2:5");
131  * gtk_tree_model_get_iter (model, &iter, path);
132  * gtk_tree_path_free (path);
133  *
134  * // walk the tree to find the iterator
135  * gtk_tree_model_iter_nth_child (model, &iter,
136  *                                NULL, 3);
137  * parent_iter = iter;
138  * gtk_tree_model_iter_nth_child (model, &iter,
139  *                                &parent_iter, 2);
140  * parent_iter = iter;
141  * gtk_tree_model_iter_nth_child (model, &iter,
142  *                                &parent_iter, 5);
143  * ]|
144  *
145  * This second example shows a quick way of iterating through a list
146  * and getting a string and an integer from each row. The
147  * populate_model() function used below is not
148  * shown, as it is specific to the #GtkListStore. For information on
149  * how to write such a function, see the #GtkListStore documentation.
150  *
151  * ## Reading data from a #GtkTreeModel
152  *
153  * |[<!-- language="C" -->
154  * enum
155  * {
156  *   STRING_COLUMN,
157  *   INT_COLUMN,
158  *   N_COLUMNS
159  * };
160  *
161  * ...
162  *
163  * GtkTreeModel *list_store;
164  * GtkTreeIter iter;
165  * gboolean valid;
166  * gint row_count = 0;
167  *
168  * // make a new list_store
169  * list_store = gtk_list_store_new (N_COLUMNS,
170  *                                  G_TYPE_STRING,
171  *                                  G_TYPE_INT);
172  *
173  * // Fill the list store with data
174  * populate_model (list_store);
175  *
176  * // Get the first iter in the list, check it is valid and walk
177  * // through the list, reading each row.
178  *
179  * valid = gtk_tree_model_get_iter_first (list_store,
180  *                                        &iter);
181  * while (valid)
182  *  {
183  *    gchar *str_data;
184  *    gint   int_data;
185  *
186  *    // Make sure you terminate calls to gtk_tree_model_get() with a “-1” value
187  *    gtk_tree_model_get (list_store, &iter,
188  *                        STRING_COLUMN, &str_data,
189  *                        INT_COLUMN, &int_data,
190  *                        -1);
191  *
192  *    // Do something with the data
193  *    g_print ("Row %d: (%s,%d)\n",
194  *             row_count, str_data, int_data);
195  *    g_free (str_data);
196  *
197  *    valid = gtk_tree_model_iter_next (list_store,
198  *                                      &iter);
199  *    row_count++;
200  *  }
201  * ]|
202  *
203  * The #GtkTreeModel interface contains two methods for reference
204  * counting: gtk_tree_model_ref_node() and gtk_tree_model_unref_node().
205  * These two methods are optional to implement. The reference counting
206  * is meant as a way for views to let models know when nodes are being
207  * displayed. #GtkTreeView will take a reference on a node when it is
208  * visible, which means the node is either in the toplevel or expanded.
209  * Being displayed does not mean that the node is currently directly
210  * visible to the user in the viewport. Based on this reference counting
211  * scheme a caching model, for example, can decide whether or not to cache
212  * a node based on the reference count. A file-system based model would
213  * not want to keep the entire file hierarchy in memory, but just the
214  * folders that are currently expanded in every current view.
215  *
216  * When working with reference counting, the following rules must be taken
217  * into account:
218  *
219  * - Never take a reference on a node without owning a reference on its parent.
220  *   This means that all parent nodes of a referenced node must be referenced
221  *   as well.
222  *
223  * - Outstanding references on a deleted node are not released. This is not
224  *   possible because the node has already been deleted by the time the
225  *   row-deleted signal is received.
226  *
227  * - Models are not obligated to emit a signal on rows of which none of its
228  *   siblings are referenced. To phrase this differently, signals are only
229  *   required for levels in which nodes are referenced. For the root level
230  *   however, signals must be emitted at all times (however the root level
231  *   is always referenced when any view is attached).
232  */
233 
234 #define INITIALIZE_TREE_ITER(Iter) \
235     G_STMT_START{ \
236       (Iter)->stamp = 0; \
237       (Iter)->user_data  = NULL; \
238       (Iter)->user_data2 = NULL; \
239       (Iter)->user_data3 = NULL; \
240     }G_STMT_END
241 
242 #define ROW_REF_DATA_STRING "gtk-tree-row-refs"
243 
244 enum {
245   ROW_CHANGED,
246   ROW_INSERTED,
247   ROW_HAS_CHILD_TOGGLED,
248   ROW_DELETED,
249   ROWS_REORDERED,
250   LAST_SIGNAL
251 };
252 
253 static guint tree_model_signals[LAST_SIGNAL] = { 0 };
254 
255 struct _GtkTreePath
256 {
257   gint depth;    /* Number of elements */
258   gint alloc;    /* Number of allocated elements */
259   gint *indices;
260 };
261 
262 typedef struct
263 {
264   GSList *list;
265 } RowRefList;
266 
267 static void      gtk_tree_model_base_init   (gpointer           g_class);
268 
269 /* custom closures */
270 static void      row_inserted_marshal       (GClosure          *closure,
271                                              GValue /* out */  *return_value,
272                                              guint              n_param_value,
273                                              const GValue      *param_values,
274                                              gpointer           invocation_hint,
275                                              gpointer           marshal_data);
276 static void      row_deleted_marshal        (GClosure          *closure,
277                                              GValue /* out */  *return_value,
278                                              guint              n_param_value,
279                                              const GValue      *param_values,
280                                              gpointer           invocation_hint,
281                                              gpointer           marshal_data);
282 static void      rows_reordered_marshal     (GClosure          *closure,
283                                              GValue /* out */  *return_value,
284                                              guint              n_param_value,
285                                              const GValue      *param_values,
286                                              gpointer           invocation_hint,
287                                              gpointer           marshal_data);
288 
289 static void      gtk_tree_row_ref_inserted  (RowRefList        *refs,
290                                              GtkTreePath       *path,
291                                              GtkTreeIter       *iter);
292 static void      gtk_tree_row_ref_deleted   (RowRefList        *refs,
293                                              GtkTreePath       *path);
294 static void      gtk_tree_row_ref_reordered (RowRefList        *refs,
295                                              GtkTreePath       *path,
296                                              GtkTreeIter       *iter,
297                                              gint              *new_order);
298 
299 GType
gtk_tree_model_get_type(void)300 gtk_tree_model_get_type (void)
301 {
302   static GType tree_model_type = 0;
303 
304   if (! tree_model_type)
305     {
306       const GTypeInfo tree_model_info =
307       {
308         sizeof (GtkTreeModelIface), /* class_size */
309         gtk_tree_model_base_init,   /* base_init */
310         NULL,           /* base_finalize */
311         NULL,
312         NULL,           /* class_finalize */
313         NULL,           /* class_data */
314         0,
315         0,              /* n_preallocs */
316         NULL
317       };
318 
319       tree_model_type =
320         g_type_register_static (G_TYPE_INTERFACE, I_("GtkTreeModel"),
321                                 &tree_model_info, 0);
322 
323       g_type_interface_add_prerequisite (tree_model_type, G_TYPE_OBJECT);
324     }
325 
326   return tree_model_type;
327 }
328 
329 static void
gtk_tree_model_base_init(gpointer g_class)330 gtk_tree_model_base_init (gpointer g_class)
331 {
332   static gboolean initialized = FALSE;
333   GClosure *closure;
334 
335   if (! initialized)
336     {
337       GType row_inserted_params[2];
338       GType row_deleted_params[1];
339       GType rows_reordered_params[3];
340 
341       row_inserted_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
342       row_inserted_params[1] = GTK_TYPE_TREE_ITER;
343 
344       row_deleted_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
345 
346       rows_reordered_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
347       rows_reordered_params[1] = GTK_TYPE_TREE_ITER;
348       rows_reordered_params[2] = G_TYPE_POINTER;
349 
350       /**
351        * GtkTreeModel::row-changed:
352        * @tree_model: the #GtkTreeModel on which the signal is emitted
353        * @path: a #GtkTreePath-struct identifying the changed row
354        * @iter: a valid #GtkTreeIter-struct pointing to the changed row
355        *
356        * This signal is emitted when a row in the model has changed.
357        */
358       tree_model_signals[ROW_CHANGED] =
359         g_signal_new (I_("row-changed"),
360                       GTK_TYPE_TREE_MODEL,
361                       G_SIGNAL_RUN_LAST,
362                       G_STRUCT_OFFSET (GtkTreeModelIface, row_changed),
363                       NULL, NULL,
364                       _gtk_marshal_VOID__BOXED_BOXED,
365                       G_TYPE_NONE, 2,
366                       GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE,
367                       GTK_TYPE_TREE_ITER);
368       g_signal_set_va_marshaller (tree_model_signals[ROW_CHANGED],
369                                   G_TYPE_FROM_CLASS (g_class),
370                                   _gtk_marshal_VOID__BOXED_BOXEDv);
371 
372       /* We need to get notification about structure changes
373        * to update row references., so instead of using the
374        * standard g_signal_new() with an offset into our interface
375        * structure, we use a customs closures for the class
376        * closures (default handlers) that first update row references
377        * and then calls the function from the interface structure.
378        *
379        * The reason we don't simply update the row references from
380        * the wrapper functions (gtk_tree_model_row_inserted(), etc.)
381        * is to keep proper ordering with respect to signal handlers
382        * connected normally and after.
383        */
384 
385       /**
386        * GtkTreeModel::row-inserted:
387        * @tree_model: the #GtkTreeModel on which the signal is emitted
388        * @path: a #GtkTreePath-struct identifying the new row
389        * @iter: a valid #GtkTreeIter-struct pointing to the new row
390        *
391        * This signal is emitted when a new row has been inserted in
392        * the model.
393        *
394        * Note that the row may still be empty at this point, since
395        * it is a common pattern to first insert an empty row, and
396        * then fill it with the desired values.
397        */
398       closure = g_closure_new_simple (sizeof (GClosure), NULL);
399       g_closure_set_marshal (closure, row_inserted_marshal);
400       tree_model_signals[ROW_INSERTED] =
401         g_signal_newv (I_("row-inserted"),
402                        GTK_TYPE_TREE_MODEL,
403                        G_SIGNAL_RUN_FIRST,
404                        closure,
405                        NULL, NULL,
406                        _gtk_marshal_VOID__BOXED_BOXED,
407                        G_TYPE_NONE, 2,
408                        row_inserted_params);
409       g_signal_set_va_marshaller (tree_model_signals[ROW_INSERTED],
410                                   G_TYPE_FROM_CLASS (g_class),
411                                   _gtk_marshal_VOID__BOXED_BOXEDv);
412 
413       /**
414        * GtkTreeModel::row-has-child-toggled:
415        * @tree_model: the #GtkTreeModel on which the signal is emitted
416        * @path: a #GtkTreePath-struct identifying the row
417        * @iter: a valid #GtkTreeIter-struct pointing to the row
418        *
419        * This signal is emitted when a row has gotten the first child
420        * row or lost its last child row.
421        */
422       tree_model_signals[ROW_HAS_CHILD_TOGGLED] =
423         g_signal_new (I_("row-has-child-toggled"),
424                       GTK_TYPE_TREE_MODEL,
425                       G_SIGNAL_RUN_LAST,
426                       G_STRUCT_OFFSET (GtkTreeModelIface, row_has_child_toggled),
427                       NULL, NULL,
428                       _gtk_marshal_VOID__BOXED_BOXED,
429                       G_TYPE_NONE, 2,
430                       GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE,
431                       GTK_TYPE_TREE_ITER);
432       g_signal_set_va_marshaller (tree_model_signals[ROW_HAS_CHILD_TOGGLED],
433                                   G_TYPE_FROM_CLASS (g_class),
434                                   _gtk_marshal_VOID__BOXED_BOXEDv);
435 
436       /**
437        * GtkTreeModel::row-deleted:
438        * @tree_model: the #GtkTreeModel on which the signal is emitted
439        * @path: a #GtkTreePath-struct identifying the row
440        *
441        * This signal is emitted when a row has been deleted.
442        *
443        * Note that no iterator is passed to the signal handler,
444        * since the row is already deleted.
445        *
446        * This should be called by models after a row has been removed.
447        * The location pointed to by @path should be the location that
448        * the row previously was at. It may not be a valid location anymore.
449        */
450       closure = g_closure_new_simple (sizeof (GClosure), NULL);
451       g_closure_set_marshal (closure, row_deleted_marshal);
452       tree_model_signals[ROW_DELETED] =
453         g_signal_newv (I_("row-deleted"),
454                        GTK_TYPE_TREE_MODEL,
455                        G_SIGNAL_RUN_FIRST,
456                        closure,
457                        NULL, NULL,
458                        NULL,
459                        G_TYPE_NONE, 1,
460                        row_deleted_params);
461 
462       /**
463        * GtkTreeModel::rows-reordered: (skip)
464        * @tree_model: the #GtkTreeModel on which the signal is emitted
465        * @path: a #GtkTreePath-struct identifying the tree node whose children
466        *     have been reordered
467        * @iter: a valid #GtkTreeIter-struct pointing to the node whose children
468        *     have been reordered, or %NULL if the depth of @path is 0
469        * @new_order: an array of integers mapping the current position
470        *     of each child to its old position before the re-ordering,
471        *     i.e. @new_order`[newpos] = oldpos`
472        *
473        * This signal is emitted when the children of a node in the
474        * #GtkTreeModel have been reordered.
475        *
476        * Note that this signal is not emitted
477        * when rows are reordered by DND, since this is implemented
478        * by removing and then reinserting the row.
479        */
480       closure = g_closure_new_simple (sizeof (GClosure), NULL);
481       g_closure_set_marshal (closure, rows_reordered_marshal);
482       tree_model_signals[ROWS_REORDERED] =
483         g_signal_newv (I_("rows-reordered"),
484                        GTK_TYPE_TREE_MODEL,
485                        G_SIGNAL_RUN_FIRST,
486                        closure,
487                        NULL, NULL,
488                        _gtk_marshal_VOID__BOXED_BOXED_POINTER,
489                        G_TYPE_NONE, 3,
490                        rows_reordered_params);
491       g_signal_set_va_marshaller (tree_model_signals[ROWS_REORDERED],
492                                   G_TYPE_FROM_CLASS (g_class),
493                                   _gtk_marshal_VOID__BOXED_BOXED_POINTERv);
494       initialized = TRUE;
495     }
496 }
497 
498 static void
row_inserted_marshal(GClosure * closure,GValue * return_value,guint n_param_values,const GValue * param_values,gpointer invocation_hint,gpointer marshal_data)499 row_inserted_marshal (GClosure          *closure,
500                       GValue /* out */  *return_value,
501                       guint              n_param_values,
502                       const GValue      *param_values,
503                       gpointer           invocation_hint,
504                       gpointer           marshal_data)
505 {
506   GtkTreeModelIface *iface;
507 
508   void (* row_inserted_callback) (GtkTreeModel *tree_model,
509                                   GtkTreePath *path,
510                                   GtkTreeIter *iter) = NULL;
511 
512   GObject *model = g_value_get_object (param_values + 0);
513   GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
514   GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
515 
516   /* first, we need to update internal row references */
517   gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
518                              path, iter);
519 
520   /* fetch the interface ->row_inserted implementation */
521   iface = GTK_TREE_MODEL_GET_IFACE (model);
522   row_inserted_callback = G_STRUCT_MEMBER (gpointer, iface,
523                               G_STRUCT_OFFSET (GtkTreeModelIface,
524                                                row_inserted));
525 
526   /* Call that default signal handler, it if has been set */
527   if (row_inserted_callback)
528     row_inserted_callback (GTK_TREE_MODEL (model), path, iter);
529 }
530 
531 static void
row_deleted_marshal(GClosure * closure,GValue * return_value,guint n_param_values,const GValue * param_values,gpointer invocation_hint,gpointer marshal_data)532 row_deleted_marshal (GClosure          *closure,
533                      GValue /* out */  *return_value,
534                      guint              n_param_values,
535                      const GValue      *param_values,
536                      gpointer           invocation_hint,
537                      gpointer           marshal_data)
538 {
539   GtkTreeModelIface *iface;
540   void (* row_deleted_callback) (GtkTreeModel *tree_model,
541                                  GtkTreePath  *path) = NULL;
542   GObject *model = g_value_get_object (param_values + 0);
543   GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
544 
545   /* first, we need to update internal row references */
546   gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
547                             path);
548 
549   /* fetch the interface ->row_deleted implementation */
550   iface = GTK_TREE_MODEL_GET_IFACE (model);
551   row_deleted_callback = G_STRUCT_MEMBER (gpointer, iface,
552                               G_STRUCT_OFFSET (GtkTreeModelIface,
553                                                row_deleted));
554 
555   /* Call that default signal handler, it if has been set */
556   if (row_deleted_callback)
557     row_deleted_callback (GTK_TREE_MODEL (model), path);
558 }
559 
560 static void
rows_reordered_marshal(GClosure * closure,GValue * return_value,guint n_param_values,const GValue * param_values,gpointer invocation_hint,gpointer marshal_data)561 rows_reordered_marshal (GClosure          *closure,
562                         GValue /* out */  *return_value,
563                         guint              n_param_values,
564                         const GValue      *param_values,
565                         gpointer           invocation_hint,
566                         gpointer           marshal_data)
567 {
568   GtkTreeModelIface *iface;
569   void (* rows_reordered_callback) (GtkTreeModel *tree_model,
570                                     GtkTreePath  *path,
571                                     GtkTreeIter  *iter,
572                                     gint         *new_order);
573 
574   GObject *model = g_value_get_object (param_values + 0);
575   GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
576   GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
577   gint *new_order = (gint *)g_value_get_pointer (param_values + 3);
578 
579   /* first, we need to update internal row references */
580   gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
581                               path, iter, new_order);
582 
583   /* fetch the interface ->rows_reordered implementation */
584   iface = GTK_TREE_MODEL_GET_IFACE (model);
585   rows_reordered_callback = G_STRUCT_MEMBER (gpointer, iface,
586                               G_STRUCT_OFFSET (GtkTreeModelIface,
587                                                rows_reordered));
588 
589   /* Call that default signal handler, it if has been set */
590   if (rows_reordered_callback)
591     rows_reordered_callback (GTK_TREE_MODEL (model), path, iter, new_order);
592 }
593 
594 /**
595  * gtk_tree_path_new:
596  *
597  * Creates a new #GtkTreePath-struct.
598  * This refers to a row.
599  *
600  * Returns: A newly created #GtkTreePath-struct.
601  */
602 GtkTreePath *
gtk_tree_path_new(void)603 gtk_tree_path_new (void)
604 {
605   GtkTreePath *retval;
606   retval = g_slice_new (GtkTreePath);
607   retval->depth = 0;
608   retval->alloc = 0;
609   retval->indices = NULL;
610 
611   return retval;
612 }
613 
614 /**
615  * gtk_tree_path_new_from_string:
616  * @path: The string representation of a path
617  *
618  * Creates a new #GtkTreePath-struct initialized to @path.
619  *
620  * @path is expected to be a colon separated list of numbers.
621  * For example, the string “10:4:0” would create a path of depth
622  * 3 pointing to the 11th child of the root node, the 5th
623  * child of that 11th child, and the 1st child of that 5th child.
624  * If an invalid path string is passed in, %NULL is returned.
625  *
626  * Returns: A newly-created #GtkTreePath-struct, or %NULL
627  */
628 GtkTreePath *
gtk_tree_path_new_from_string(const gchar * path)629 gtk_tree_path_new_from_string (const gchar *path)
630 {
631   GtkTreePath *retval;
632   const gchar *orig_path = path;
633   gchar *ptr;
634   gint i;
635 
636   g_return_val_if_fail (path != NULL, NULL);
637   g_return_val_if_fail (*path != '\000', NULL);
638 
639   retval = gtk_tree_path_new ();
640 
641   while (1)
642     {
643       i = strtol (path, &ptr, 10);
644       if (i < 0)
645         {
646           g_warning (G_STRLOC ": Negative numbers in path %s passed to gtk_tree_path_new_from_string", orig_path);
647           gtk_tree_path_free (retval);
648           return NULL;
649         }
650 
651       gtk_tree_path_append_index (retval, i);
652 
653       if (*ptr == '\000')
654         break;
655       if (ptr == path || *ptr != ':')
656         {
657           g_warning (G_STRLOC ": Invalid path %s passed to gtk_tree_path_new_from_string", orig_path);
658           gtk_tree_path_free (retval);
659           return NULL;
660         }
661       path = ptr + 1;
662     }
663 
664   return retval;
665 }
666 
667 /**
668  * gtk_tree_path_new_from_indices:
669  * @first_index: first integer
670  * @...: list of integers terminated by -1
671  *
672  * Creates a new path with @first_index and @varargs as indices.
673  *
674  * Returns: A newly created #GtkTreePath-struct
675  *
676  * Since: 2.2
677  */
678 GtkTreePath *
gtk_tree_path_new_from_indices(gint first_index,...)679 gtk_tree_path_new_from_indices (gint first_index,
680                                 ...)
681 {
682   int arg;
683   va_list args;
684   GtkTreePath *path;
685 
686   path = gtk_tree_path_new ();
687 
688   va_start (args, first_index);
689   arg = first_index;
690 
691   while (arg != -1)
692     {
693       gtk_tree_path_append_index (path, arg);
694       arg = va_arg (args, gint);
695     }
696 
697   va_end (args);
698 
699   return path;
700 }
701 
702 /**
703  * gtk_tree_path_new_from_indicesv: (rename-to gtk_tree_path_new_from_indices)
704  * @indices: (array length=length): array of indices
705  * @length: length of @indices array
706  *
707  * Creates a new path with the given @indices array of @length.
708  *
709  * Returns: A newly created #GtkTreePath-struct
710  *
711  * Since: 3.12
712  */
713 GtkTreePath *
gtk_tree_path_new_from_indicesv(gint * indices,gsize length)714 gtk_tree_path_new_from_indicesv (gint *indices,
715                                  gsize length)
716 {
717   GtkTreePath *path;
718 
719   g_return_val_if_fail (indices != NULL && length != 0, NULL);
720 
721   path = gtk_tree_path_new ();
722   path->alloc = length;
723   path->depth = length;
724   path->indices = g_new (gint, length);
725   memcpy (path->indices, indices, length * sizeof (gint));
726 
727   return path;
728 }
729 
730 /**
731  * gtk_tree_path_to_string:
732  * @path: A #GtkTreePath-struct
733  *
734  * Generates a string representation of the path.
735  *
736  * This string is a “:” separated list of numbers.
737  * For example, “4:10:0:3” would be an acceptable
738  * return value for this string.
739  *
740  * Returns: A newly-allocated string.
741  *     Must be freed with g_free().
742  */
743 gchar *
gtk_tree_path_to_string(GtkTreePath * path)744 gtk_tree_path_to_string (GtkTreePath *path)
745 {
746   gchar *retval, *ptr, *end;
747   gint i, n;
748 
749   g_return_val_if_fail (path != NULL, NULL);
750 
751   if (path->depth == 0)
752     return NULL;
753 
754   n = path->depth * 12;
755   ptr = retval = g_new0 (gchar, n);
756   end = ptr + n;
757   g_snprintf (retval, end - ptr, "%d", path->indices[0]);
758   while (*ptr != '\000')
759     ptr++;
760 
761   for (i = 1; i < path->depth; i++)
762     {
763       g_snprintf (ptr, end - ptr, ":%d", path->indices[i]);
764       while (*ptr != '\000')
765         ptr++;
766     }
767 
768   return retval;
769 }
770 
771 /**
772  * gtk_tree_path_new_first:
773  *
774  * Creates a new #GtkTreePath-struct.
775  *
776  * The string representation of this path is “0”.
777  *
778  * Returns: A new #GtkTreePath-struct
779  */
780 GtkTreePath *
gtk_tree_path_new_first(void)781 gtk_tree_path_new_first (void)
782 {
783   GtkTreePath *retval;
784 
785   retval = gtk_tree_path_new ();
786   gtk_tree_path_append_index (retval, 0);
787 
788   return retval;
789 }
790 
791 /**
792  * gtk_tree_path_append_index:
793  * @path: a #GtkTreePath-struct
794  * @index_: the index
795  *
796  * Appends a new index to a path.
797  *
798  * As a result, the depth of the path is increased.
799  */
800 void
gtk_tree_path_append_index(GtkTreePath * path,gint index_)801 gtk_tree_path_append_index (GtkTreePath *path,
802                             gint         index_)
803 {
804   g_return_if_fail (path != NULL);
805   g_return_if_fail (index_ >= 0);
806 
807   if (path->depth == path->alloc)
808     {
809       gint *indices;
810       path->alloc = MAX (path->alloc * 2, 1);
811       indices = g_new (gint, path->alloc);
812       memcpy (indices, path->indices, path->depth * sizeof (gint));
813       g_free (path->indices);
814       path->indices = indices;
815     }
816 
817   path->depth += 1;
818   path->indices[path->depth - 1] = index_;
819 }
820 
821 /**
822  * gtk_tree_path_prepend_index:
823  * @path: a #GtkTreePath-struct
824  * @index_: the index
825  *
826  * Prepends a new index to a path.
827  *
828  * As a result, the depth of the path is increased.
829  */
830 void
gtk_tree_path_prepend_index(GtkTreePath * path,gint index)831 gtk_tree_path_prepend_index (GtkTreePath *path,
832                              gint       index)
833 {
834   if (path->depth == path->alloc)
835     {
836       gint *indices;
837       path->alloc = MAX (path->alloc * 2, 1);
838       indices = g_new (gint, path->alloc);
839       memcpy (indices + 1, path->indices, path->depth * sizeof (gint));
840       g_free (path->indices);
841       path->indices = indices;
842     }
843   else if (path->depth > 0)
844     memmove (path->indices + 1, path->indices, path->depth * sizeof (gint));
845 
846   path->depth += 1;
847   path->indices[0] = index;
848 }
849 
850 /**
851  * gtk_tree_path_get_depth:
852  * @path: a #GtkTreePath-struct
853  *
854  * Returns the current depth of @path.
855  *
856  * Returns: The depth of @path
857  */
858 gint
gtk_tree_path_get_depth(GtkTreePath * path)859 gtk_tree_path_get_depth (GtkTreePath *path)
860 {
861   g_return_val_if_fail (path != NULL, 0);
862 
863   return path->depth;
864 }
865 
866 /**
867  * gtk_tree_path_get_indices: (skip)
868  * @path: a #GtkTreePath-struct
869  *
870  * Returns the current indices of @path.
871  *
872  * This is an array of integers, each representing a node in a tree.
873  * This value should not be freed.
874  *
875  * The length of the array can be obtained with gtk_tree_path_get_depth().
876  *
877  * Returns: The current indices, or %NULL
878  */
879 gint *
gtk_tree_path_get_indices(GtkTreePath * path)880 gtk_tree_path_get_indices (GtkTreePath *path)
881 {
882   g_return_val_if_fail (path != NULL, NULL);
883 
884   return path->indices;
885 }
886 
887 /**
888  * gtk_tree_path_get_indices_with_depth: (rename-to gtk_tree_path_get_indices)
889  * @path: a #GtkTreePath-struct
890  * @depth: (out) (allow-none): return location for number of elements
891  *     returned in the integer array, or %NULL
892  *
893  * Returns the current indices of @path.
894  *
895  * This is an array of integers, each representing a node in a tree.
896  * It also returns the number of elements in the array.
897  * The array should not be freed.
898  *
899  * Returns: (array length=depth) (transfer none): The current
900  *     indices, or %NULL
901  *
902  * Since: 3.0
903  */
904 gint *
gtk_tree_path_get_indices_with_depth(GtkTreePath * path,gint * depth)905 gtk_tree_path_get_indices_with_depth (GtkTreePath *path,
906                                       gint        *depth)
907 {
908   g_return_val_if_fail (path != NULL, NULL);
909 
910   if (depth)
911     *depth = path->depth;
912 
913   return path->indices;
914 }
915 
916 /**
917  * gtk_tree_path_free:
918  * @path: (allow-none): a #GtkTreePath-struct
919  *
920  * Frees @path. If @path is %NULL, it simply returns.
921  */
922 void
gtk_tree_path_free(GtkTreePath * path)923 gtk_tree_path_free (GtkTreePath *path)
924 {
925   if (!path)
926     return;
927 
928   g_free (path->indices);
929   g_slice_free (GtkTreePath, path);
930 }
931 
932 /**
933  * gtk_tree_path_copy:
934  * @path: a #GtkTreePath-struct
935  *
936  * Creates a new #GtkTreePath-struct as a copy of @path.
937  *
938  * Returns: a new #GtkTreePath-struct
939  */
940 GtkTreePath *
gtk_tree_path_copy(const GtkTreePath * path)941 gtk_tree_path_copy (const GtkTreePath *path)
942 {
943   GtkTreePath *retval;
944 
945   g_return_val_if_fail (path != NULL, NULL);
946 
947   retval = g_slice_new (GtkTreePath);
948   retval->depth = path->depth;
949   retval->alloc = retval->depth;
950   retval->indices = g_new (gint, path->alloc);
951   memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
952   return retval;
953 }
954 
G_DEFINE_BOXED_TYPE(GtkTreePath,gtk_tree_path,gtk_tree_path_copy,gtk_tree_path_free)955 G_DEFINE_BOXED_TYPE (GtkTreePath, gtk_tree_path,
956                      gtk_tree_path_copy,
957                      gtk_tree_path_free)
958 
959 /**
960  * gtk_tree_path_compare:
961  * @a: a #GtkTreePath-struct
962  * @b: a #GtkTreePath-struct to compare with
963  *
964  * Compares two paths.
965  *
966  * If @a appears before @b in a tree, then -1 is returned.
967  * If @b appears before @a, then 1 is returned.
968  * If the two nodes are equal, then 0 is returned.
969  *
970  * Returns: the relative positions of @a and @b
971  */
972 gint
973 gtk_tree_path_compare (const GtkTreePath *a,
974                        const GtkTreePath *b)
975 {
976   gint p = 0, q = 0;
977 
978   g_return_val_if_fail (a != NULL, 0);
979   g_return_val_if_fail (b != NULL, 0);
980   g_return_val_if_fail (a->depth > 0, 0);
981   g_return_val_if_fail (b->depth > 0, 0);
982 
983   do
984     {
985       if (a->indices[p] == b->indices[q])
986         continue;
987       return (a->indices[p] < b->indices[q]?-1:1);
988     }
989   while (++p < a->depth && ++q < b->depth);
990   if (a->depth == b->depth)
991     return 0;
992   return (a->depth < b->depth?-1:1);
993 }
994 
995 /**
996  * gtk_tree_path_is_ancestor:
997  * @path: a #GtkTreePath-struct
998  * @descendant: another #GtkTreePath-struct
999  *
1000  * Returns %TRUE if @descendant is a descendant of @path.
1001  *
1002  * Returns: %TRUE if @descendant is contained inside @path
1003  */
1004 gboolean
gtk_tree_path_is_ancestor(GtkTreePath * path,GtkTreePath * descendant)1005 gtk_tree_path_is_ancestor (GtkTreePath *path,
1006                            GtkTreePath *descendant)
1007 {
1008   gint i;
1009 
1010   g_return_val_if_fail (path != NULL, FALSE);
1011   g_return_val_if_fail (descendant != NULL, FALSE);
1012 
1013   /* can't be an ancestor if we're deeper */
1014   if (path->depth >= descendant->depth)
1015     return FALSE;
1016 
1017   i = 0;
1018   while (i < path->depth)
1019     {
1020       if (path->indices[i] != descendant->indices[i])
1021         return FALSE;
1022       ++i;
1023     }
1024 
1025   return TRUE;
1026 }
1027 
1028 /**
1029  * gtk_tree_path_is_descendant:
1030  * @path: a #GtkTreePath-struct
1031  * @ancestor: another #GtkTreePath-struct
1032  *
1033  * Returns %TRUE if @path is a descendant of @ancestor.
1034  *
1035  * Returns: %TRUE if @ancestor contains @path somewhere below it
1036  */
1037 gboolean
gtk_tree_path_is_descendant(GtkTreePath * path,GtkTreePath * ancestor)1038 gtk_tree_path_is_descendant (GtkTreePath *path,
1039                              GtkTreePath *ancestor)
1040 {
1041   gint i;
1042 
1043   g_return_val_if_fail (path != NULL, FALSE);
1044   g_return_val_if_fail (ancestor != NULL, FALSE);
1045 
1046   /* can't be a descendant if we're shallower in the tree */
1047   if (path->depth <= ancestor->depth)
1048     return FALSE;
1049 
1050   i = 0;
1051   while (i < ancestor->depth)
1052     {
1053       if (path->indices[i] != ancestor->indices[i])
1054         return FALSE;
1055       ++i;
1056     }
1057 
1058   return TRUE;
1059 }
1060 
1061 
1062 /**
1063  * gtk_tree_path_next:
1064  * @path: a #GtkTreePath-struct
1065  *
1066  * Moves the @path to point to the next node at the current depth.
1067  */
1068 void
gtk_tree_path_next(GtkTreePath * path)1069 gtk_tree_path_next (GtkTreePath *path)
1070 {
1071   g_return_if_fail (path != NULL);
1072   g_return_if_fail (path->depth > 0);
1073 
1074   path->indices[path->depth - 1] ++;
1075 }
1076 
1077 /**
1078  * gtk_tree_path_prev:
1079  * @path: a #GtkTreePath-struct
1080  *
1081  * Moves the @path to point to the previous node at the
1082  * current depth, if it exists.
1083  *
1084  * Returns: %TRUE if @path has a previous node, and
1085  *     the move was made
1086  */
1087 gboolean
gtk_tree_path_prev(GtkTreePath * path)1088 gtk_tree_path_prev (GtkTreePath *path)
1089 {
1090   g_return_val_if_fail (path != NULL, FALSE);
1091 
1092   if (path->depth == 0)
1093     return FALSE;
1094 
1095   if (path->indices[path->depth - 1] == 0)
1096     return FALSE;
1097 
1098   path->indices[path->depth - 1] -= 1;
1099 
1100   return TRUE;
1101 }
1102 
1103 /**
1104  * gtk_tree_path_up:
1105  * @path: a #GtkTreePath-struct
1106  *
1107  * Moves the @path to point to its parent node, if it has a parent.
1108  *
1109  * Returns: %TRUE if @path has a parent, and the move was made
1110  */
1111 gboolean
gtk_tree_path_up(GtkTreePath * path)1112 gtk_tree_path_up (GtkTreePath *path)
1113 {
1114   g_return_val_if_fail (path != NULL, FALSE);
1115 
1116   if (path->depth == 0)
1117     return FALSE;
1118 
1119   path->depth--;
1120 
1121   return TRUE;
1122 }
1123 
1124 /**
1125  * gtk_tree_path_down:
1126  * @path: a #GtkTreePath-struct
1127  *
1128  * Moves @path to point to the first child of the current path.
1129  */
1130 void
gtk_tree_path_down(GtkTreePath * path)1131 gtk_tree_path_down (GtkTreePath *path)
1132 {
1133   g_return_if_fail (path != NULL);
1134 
1135   gtk_tree_path_append_index (path, 0);
1136 }
1137 
1138 /**
1139  * gtk_tree_iter_copy:
1140  * @iter: a #GtkTreeIter-struct
1141  *
1142  * Creates a dynamically allocated tree iterator as a copy of @iter.
1143  *
1144  * This function is not intended for use in applications,
1145  * because you can just copy the structs by value
1146  * (`GtkTreeIter new_iter = iter;`).
1147  * You must free this iter with gtk_tree_iter_free().
1148  *
1149  * Returns: a newly-allocated copy of @iter
1150  */
1151 GtkTreeIter *
gtk_tree_iter_copy(GtkTreeIter * iter)1152 gtk_tree_iter_copy (GtkTreeIter *iter)
1153 {
1154   GtkTreeIter *retval;
1155 
1156   g_return_val_if_fail (iter != NULL, NULL);
1157 
1158   retval = g_slice_new (GtkTreeIter);
1159   *retval = *iter;
1160 
1161   return retval;
1162 }
1163 
1164 /**
1165  * gtk_tree_iter_free:
1166  * @iter: a dynamically allocated tree iterator
1167  *
1168  * Frees an iterator that has been allocated by gtk_tree_iter_copy().
1169  *
1170  * This function is mainly used for language bindings.
1171  */
1172 void
gtk_tree_iter_free(GtkTreeIter * iter)1173 gtk_tree_iter_free (GtkTreeIter *iter)
1174 {
1175   g_return_if_fail (iter != NULL);
1176 
1177   g_slice_free (GtkTreeIter, iter);
1178 }
1179 
G_DEFINE_BOXED_TYPE(GtkTreeIter,gtk_tree_iter,gtk_tree_iter_copy,gtk_tree_iter_free)1180 G_DEFINE_BOXED_TYPE (GtkTreeIter,  gtk_tree_iter,
1181                      gtk_tree_iter_copy,
1182                      gtk_tree_iter_free)
1183 
1184 /**
1185  * gtk_tree_model_get_flags:
1186  * @tree_model: a #GtkTreeModel
1187  *
1188  * Returns a set of flags supported by this interface.
1189  *
1190  * The flags are a bitwise combination of #GtkTreeModelFlags.
1191  * The flags supported should not change during the lifetime
1192  * of the @tree_model.
1193  *
1194  * Returns: the flags supported by this interface
1195  */
1196 GtkTreeModelFlags
1197 gtk_tree_model_get_flags (GtkTreeModel *tree_model)
1198 {
1199   GtkTreeModelIface *iface;
1200 
1201   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1202 
1203   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1204   if (iface->get_flags)
1205     return (* iface->get_flags) (tree_model);
1206 
1207   return 0;
1208 }
1209 
1210 /**
1211  * gtk_tree_model_get_n_columns:
1212  * @tree_model: a #GtkTreeModel
1213  *
1214  * Returns the number of columns supported by @tree_model.
1215  *
1216  * Returns: the number of columns
1217  */
1218 gint
gtk_tree_model_get_n_columns(GtkTreeModel * tree_model)1219 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
1220 {
1221   GtkTreeModelIface *iface;
1222   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1223 
1224   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1225   g_return_val_if_fail (iface->get_n_columns != NULL, 0);
1226 
1227   return (* iface->get_n_columns) (tree_model);
1228 }
1229 
1230 /**
1231  * gtk_tree_model_get_column_type:
1232  * @tree_model: a #GtkTreeModel
1233  * @index_: the column index
1234  *
1235  * Returns the type of the column.
1236  *
1237  * Returns: the type of the column
1238  */
1239 GType
gtk_tree_model_get_column_type(GtkTreeModel * tree_model,gint index)1240 gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
1241                                 gint          index)
1242 {
1243   GtkTreeModelIface *iface;
1244 
1245   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
1246 
1247   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1248   g_return_val_if_fail (iface->get_column_type != NULL, G_TYPE_INVALID);
1249   g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
1250 
1251   return (* iface->get_column_type) (tree_model, index);
1252 }
1253 
1254 /**
1255  * gtk_tree_model_get_iter:
1256  * @tree_model: a #GtkTreeModel
1257  * @iter: (out): the uninitialized #GtkTreeIter-struct
1258  * @path: the #GtkTreePath-struct
1259  *
1260  * Sets @iter to a valid iterator pointing to @path.  If @path does
1261  * not exist, @iter is set to an invalid iterator and %FALSE is returned.
1262  *
1263  * Returns: %TRUE, if @iter was set
1264  */
1265 gboolean
gtk_tree_model_get_iter(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreePath * path)1266 gtk_tree_model_get_iter (GtkTreeModel *tree_model,
1267                          GtkTreeIter  *iter,
1268                          GtkTreePath  *path)
1269 {
1270   GtkTreeModelIface *iface;
1271 
1272   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1273   g_return_val_if_fail (iter != NULL, FALSE);
1274   g_return_val_if_fail (path != NULL, FALSE);
1275 
1276   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1277   g_return_val_if_fail (iface->get_iter != NULL, FALSE);
1278   g_return_val_if_fail (path->depth > 0, FALSE);
1279 
1280   INITIALIZE_TREE_ITER (iter);
1281 
1282   return (* iface->get_iter) (tree_model, iter, path);
1283 }
1284 
1285 /**
1286  * gtk_tree_model_get_iter_from_string:
1287  * @tree_model: a #GtkTreeModel
1288  * @iter: (out): an uninitialized #GtkTreeIter-struct
1289  * @path_string: a string representation of a #GtkTreePath-struct
1290  *
1291  * Sets @iter to a valid iterator pointing to @path_string, if it
1292  * exists. Otherwise, @iter is left invalid and %FALSE is returned.
1293  *
1294  * Returns: %TRUE, if @iter was set
1295  */
1296 gboolean
gtk_tree_model_get_iter_from_string(GtkTreeModel * tree_model,GtkTreeIter * iter,const gchar * path_string)1297 gtk_tree_model_get_iter_from_string (GtkTreeModel *tree_model,
1298                                      GtkTreeIter  *iter,
1299                                      const gchar  *path_string)
1300 {
1301   gboolean retval;
1302   GtkTreePath *path;
1303 
1304   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1305   g_return_val_if_fail (iter != NULL, FALSE);
1306   g_return_val_if_fail (path_string != NULL, FALSE);
1307 
1308   path = gtk_tree_path_new_from_string (path_string);
1309 
1310   g_return_val_if_fail (path != NULL, FALSE);
1311 
1312   retval = gtk_tree_model_get_iter (tree_model, iter, path);
1313   gtk_tree_path_free (path);
1314 
1315   return retval;
1316 }
1317 
1318 /**
1319  * gtk_tree_model_get_string_from_iter:
1320  * @tree_model: a #GtkTreeModel
1321  * @iter: a #GtkTreeIter-struct
1322  *
1323  * Generates a string representation of the iter.
1324  *
1325  * This string is a “:” separated list of numbers.
1326  * For example, “4:10:0:3” would be an acceptable
1327  * return value for this string.
1328  *
1329  * Returns: a newly-allocated string.
1330  *     Must be freed with g_free().
1331  *
1332  * Since: 2.2
1333  */
1334 gchar *
gtk_tree_model_get_string_from_iter(GtkTreeModel * tree_model,GtkTreeIter * iter)1335 gtk_tree_model_get_string_from_iter (GtkTreeModel *tree_model,
1336                                      GtkTreeIter  *iter)
1337 {
1338   GtkTreePath *path;
1339   gchar *ret;
1340 
1341   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1342   g_return_val_if_fail (iter != NULL, NULL);
1343 
1344   path = gtk_tree_model_get_path (tree_model, iter);
1345 
1346   g_return_val_if_fail (path != NULL, NULL);
1347 
1348   ret = gtk_tree_path_to_string (path);
1349   gtk_tree_path_free (path);
1350 
1351   return ret;
1352 }
1353 
1354 /**
1355  * gtk_tree_model_get_iter_first:
1356  * @tree_model: a #GtkTreeModel
1357  * @iter: (out): the uninitialized #GtkTreeIter-struct
1358  *
1359  * Initializes @iter with the first iterator in the tree
1360  * (the one at the path "0") and returns %TRUE. Returns
1361  * %FALSE if the tree is empty.
1362  *
1363  * Returns: %TRUE, if @iter was set
1364  */
1365 gboolean
gtk_tree_model_get_iter_first(GtkTreeModel * tree_model,GtkTreeIter * iter)1366 gtk_tree_model_get_iter_first (GtkTreeModel *tree_model,
1367                                GtkTreeIter  *iter)
1368 {
1369   GtkTreePath *path;
1370   gboolean retval;
1371 
1372   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1373   g_return_val_if_fail (iter != NULL, FALSE);
1374 
1375   path = gtk_tree_path_new_first ();
1376   retval = gtk_tree_model_get_iter (tree_model, iter, path);
1377   gtk_tree_path_free (path);
1378 
1379   return retval;
1380 }
1381 
1382 /**
1383  * gtk_tree_model_get_path:
1384  * @tree_model: a #GtkTreeModel
1385  * @iter: the #GtkTreeIter-struct
1386  *
1387  * Returns a newly-created #GtkTreePath-struct referenced by @iter.
1388  *
1389  * This path should be freed with gtk_tree_path_free().
1390  *
1391  * Returns: a newly-created #GtkTreePath-struct
1392  */
1393 GtkTreePath *
gtk_tree_model_get_path(GtkTreeModel * tree_model,GtkTreeIter * iter)1394 gtk_tree_model_get_path (GtkTreeModel *tree_model,
1395                          GtkTreeIter  *iter)
1396 {
1397   GtkTreeModelIface *iface;
1398 
1399   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1400   g_return_val_if_fail (iter != NULL, NULL);
1401 
1402   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1403   g_return_val_if_fail (iface->get_path != NULL, NULL);
1404 
1405   return (* iface->get_path) (tree_model, iter);
1406 }
1407 
1408 /**
1409  * gtk_tree_model_get_value:
1410  * @tree_model: a #GtkTreeModel
1411  * @iter: the #GtkTreeIter-struct
1412  * @column: the column to lookup the value at
1413  * @value: (out) (transfer none): an empty #GValue to set
1414  *
1415  * Initializes and sets @value to that at @column.
1416  *
1417  * When done with @value, g_value_unset() needs to be called
1418  * to free any allocated memory.
1419  */
1420 void
gtk_tree_model_get_value(GtkTreeModel * tree_model,GtkTreeIter * iter,gint column,GValue * value)1421 gtk_tree_model_get_value (GtkTreeModel *tree_model,
1422                           GtkTreeIter  *iter,
1423                           gint          column,
1424                           GValue       *value)
1425 {
1426   GtkTreeModelIface *iface;
1427 
1428   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1429   g_return_if_fail (iter != NULL);
1430   g_return_if_fail (value != NULL);
1431 
1432   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1433   g_return_if_fail (iface->get_value != NULL);
1434 
1435   (* iface->get_value) (tree_model, iter, column, value);
1436 }
1437 
1438 /**
1439  * gtk_tree_model_iter_next:
1440  * @tree_model: a #GtkTreeModel
1441  * @iter: (in): the #GtkTreeIter-struct
1442  *
1443  * Sets @iter to point to the node following it at the current level.
1444  *
1445  * If there is no next @iter, %FALSE is returned and @iter is set
1446  * to be invalid.
1447  *
1448  * Returns: %TRUE if @iter has been changed to the next node
1449  */
1450 gboolean
gtk_tree_model_iter_next(GtkTreeModel * tree_model,GtkTreeIter * iter)1451 gtk_tree_model_iter_next (GtkTreeModel  *tree_model,
1452                           GtkTreeIter   *iter)
1453 {
1454   GtkTreeModelIface *iface;
1455 
1456   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1457   g_return_val_if_fail (iter != NULL, FALSE);
1458 
1459   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1460   g_return_val_if_fail (iface->iter_next != NULL, FALSE);
1461 
1462   return (* iface->iter_next) (tree_model, iter);
1463 }
1464 
1465 static gboolean
gtk_tree_model_iter_previous_default(GtkTreeModel * tree_model,GtkTreeIter * iter)1466 gtk_tree_model_iter_previous_default (GtkTreeModel *tree_model,
1467                                       GtkTreeIter  *iter)
1468 {
1469   gboolean retval;
1470   GtkTreePath *path;
1471 
1472   path = gtk_tree_model_get_path (tree_model, iter);
1473   if (path == NULL)
1474     return FALSE;
1475 
1476   retval = gtk_tree_path_prev (path) &&
1477            gtk_tree_model_get_iter (tree_model, iter, path);
1478   if (retval == FALSE)
1479     iter->stamp = 0;
1480 
1481   gtk_tree_path_free (path);
1482 
1483   return retval;
1484 }
1485 
1486 /**
1487  * gtk_tree_model_iter_previous:
1488  * @tree_model: a #GtkTreeModel
1489  * @iter: (in): the #GtkTreeIter-struct
1490  *
1491  * Sets @iter to point to the previous node at the current level.
1492  *
1493  * If there is no previous @iter, %FALSE is returned and @iter is
1494  * set to be invalid.
1495  *
1496  * Returns: %TRUE if @iter has been changed to the previous node
1497  *
1498  * Since: 3.0
1499  */
1500 gboolean
gtk_tree_model_iter_previous(GtkTreeModel * tree_model,GtkTreeIter * iter)1501 gtk_tree_model_iter_previous (GtkTreeModel *tree_model,
1502                               GtkTreeIter  *iter)
1503 {
1504   gboolean retval;
1505   GtkTreeModelIface *iface;
1506 
1507   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1508   g_return_val_if_fail (iter != NULL, FALSE);
1509 
1510   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1511 
1512   if (iface->iter_previous)
1513     retval = (* iface->iter_previous) (tree_model, iter);
1514   else
1515     retval = gtk_tree_model_iter_previous_default (tree_model, iter);
1516 
1517   return retval;
1518 }
1519 
1520 /**
1521  * gtk_tree_model_iter_children:
1522  * @tree_model: a #GtkTreeModel
1523  * @iter: (out): the new #GtkTreeIter-struct to be set to the child
1524  * @parent: (allow-none): the #GtkTreeIter-struct, or %NULL
1525  *
1526  * Sets @iter to point to the first child of @parent.
1527  *
1528  * If @parent has no children, %FALSE is returned and @iter is
1529  * set to be invalid. @parent will remain a valid node after this
1530  * function has been called.
1531  *
1532  * If @parent is %NULL returns the first node, equivalent to
1533  * `gtk_tree_model_get_iter_first (tree_model, iter);`
1534  *
1535  * Returns: %TRUE, if @iter has been set to the first child
1536  */
1537 gboolean
gtk_tree_model_iter_children(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * parent)1538 gtk_tree_model_iter_children (GtkTreeModel *tree_model,
1539                               GtkTreeIter  *iter,
1540                               GtkTreeIter  *parent)
1541 {
1542   GtkTreeModelIface *iface;
1543 
1544   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1545   g_return_val_if_fail (iter != NULL, FALSE);
1546 
1547   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1548   g_return_val_if_fail (iface->iter_children != NULL, FALSE);
1549 
1550   INITIALIZE_TREE_ITER (iter);
1551 
1552   return (* iface->iter_children) (tree_model, iter, parent);
1553 }
1554 
1555 /**
1556  * gtk_tree_model_iter_has_child:
1557  * @tree_model: a #GtkTreeModel
1558  * @iter: the #GtkTreeIter-struct to test for children
1559  *
1560  * Returns %TRUE if @iter has children, %FALSE otherwise.
1561  *
1562  * Returns: %TRUE if @iter has children
1563  */
1564 gboolean
gtk_tree_model_iter_has_child(GtkTreeModel * tree_model,GtkTreeIter * iter)1565 gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
1566                                GtkTreeIter  *iter)
1567 {
1568   GtkTreeModelIface *iface;
1569 
1570   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1571   g_return_val_if_fail (iter != NULL, FALSE);
1572 
1573   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1574   g_return_val_if_fail (iface->iter_has_child != NULL, FALSE);
1575 
1576   return (* iface->iter_has_child) (tree_model, iter);
1577 }
1578 
1579 /**
1580  * gtk_tree_model_iter_n_children:
1581  * @tree_model: a #GtkTreeModel
1582  * @iter: (allow-none): the #GtkTreeIter-struct, or %NULL
1583  *
1584  * Returns the number of children that @iter has.
1585  *
1586  * As a special case, if @iter is %NULL, then the number
1587  * of toplevel nodes is returned.
1588  *
1589  * Returns: the number of children of @iter
1590  */
1591 gint
gtk_tree_model_iter_n_children(GtkTreeModel * tree_model,GtkTreeIter * iter)1592 gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
1593                                 GtkTreeIter  *iter)
1594 {
1595   GtkTreeModelIface *iface;
1596 
1597   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1598 
1599   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1600   g_return_val_if_fail (iface->iter_n_children != NULL, 0);
1601 
1602   return (* iface->iter_n_children) (tree_model, iter);
1603 }
1604 
1605 /**
1606  * gtk_tree_model_iter_nth_child:
1607  * @tree_model: a #GtkTreeModel
1608  * @iter: (out): the #GtkTreeIter-struct to set to the nth child
1609  * @parent: (allow-none): the #GtkTreeIter-struct to get the child from, or %NULL.
1610  * @n: the index of the desired child
1611  *
1612  * Sets @iter to be the child of @parent, using the given index.
1613  *
1614  * The first index is 0. If @n is too big, or @parent has no children,
1615  * @iter is set to an invalid iterator and %FALSE is returned. @parent
1616  * will remain a valid node after this function has been called. As a
1617  * special case, if @parent is %NULL, then the @n-th root node
1618  * is set.
1619  *
1620  * Returns: %TRUE, if @parent has an @n-th child
1621  */
1622 gboolean
gtk_tree_model_iter_nth_child(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * parent,gint n)1623 gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
1624                                GtkTreeIter  *iter,
1625                                GtkTreeIter  *parent,
1626                                gint          n)
1627 {
1628   GtkTreeModelIface *iface;
1629 
1630   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1631   g_return_val_if_fail (iter != NULL, FALSE);
1632   g_return_val_if_fail (n >= 0, FALSE);
1633 
1634   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1635   g_return_val_if_fail (iface->iter_nth_child != NULL, FALSE);
1636 
1637   INITIALIZE_TREE_ITER (iter);
1638 
1639   return (* iface->iter_nth_child) (tree_model, iter, parent, n);
1640 }
1641 
1642 /**
1643  * gtk_tree_model_iter_parent:
1644  * @tree_model: a #GtkTreeModel
1645  * @iter: (out): the new #GtkTreeIter-struct to set to the parent
1646  * @child: the #GtkTreeIter-struct
1647  *
1648  * Sets @iter to be the parent of @child.
1649  *
1650  * If @child is at the toplevel, and doesn’t have a parent, then
1651  * @iter is set to an invalid iterator and %FALSE is returned.
1652  * @child will remain a valid node after this function has been
1653  * called.
1654  *
1655  * @iter will be initialized before the lookup is performed, so @child
1656  * and @iter cannot point to the same memory location.
1657  *
1658  * Returns: %TRUE, if @iter is set to the parent of @child
1659  */
1660 gboolean
gtk_tree_model_iter_parent(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * child)1661 gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
1662                             GtkTreeIter  *iter,
1663                             GtkTreeIter  *child)
1664 {
1665   GtkTreeModelIface *iface;
1666 
1667   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1668   g_return_val_if_fail (iter != NULL, FALSE);
1669   g_return_val_if_fail (child != NULL, FALSE);
1670 
1671   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1672   g_return_val_if_fail (iface->iter_parent != NULL, FALSE);
1673 
1674   INITIALIZE_TREE_ITER (iter);
1675 
1676   return (* iface->iter_parent) (tree_model, iter, child);
1677 }
1678 
1679 /**
1680  * gtk_tree_model_ref_node:
1681  * @tree_model: a #GtkTreeModel
1682  * @iter: the #GtkTreeIter-struct
1683  *
1684  * Lets the tree ref the node.
1685  *
1686  * This is an optional method for models to implement.
1687  * To be more specific, models may ignore this call as it exists
1688  * primarily for performance reasons.
1689  *
1690  * This function is primarily meant as a way for views to let
1691  * caching models know when nodes are being displayed (and hence,
1692  * whether or not to cache that node). Being displayed means a node
1693  * is in an expanded branch, regardless of whether the node is currently
1694  * visible in the viewport. For example, a file-system based model
1695  * would not want to keep the entire file-hierarchy in memory,
1696  * just the sections that are currently being displayed by
1697  * every current view.
1698  *
1699  * A model should be expected to be able to get an iter independent
1700  * of its reffed state.
1701  */
1702 void
gtk_tree_model_ref_node(GtkTreeModel * tree_model,GtkTreeIter * iter)1703 gtk_tree_model_ref_node (GtkTreeModel *tree_model,
1704                          GtkTreeIter  *iter)
1705 {
1706   GtkTreeModelIface *iface;
1707 
1708   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1709 
1710   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1711   if (iface->ref_node)
1712     (* iface->ref_node) (tree_model, iter);
1713 }
1714 
1715 /**
1716  * gtk_tree_model_unref_node:
1717  * @tree_model: a #GtkTreeModel
1718  * @iter: the #GtkTreeIter-struct
1719  *
1720  * Lets the tree unref the node.
1721  *
1722  * This is an optional method for models to implement.
1723  * To be more specific, models may ignore this call as it exists
1724  * primarily for performance reasons. For more information on what
1725  * this means, see gtk_tree_model_ref_node().
1726  *
1727  * Please note that nodes that are deleted are not unreffed.
1728  */
1729 void
gtk_tree_model_unref_node(GtkTreeModel * tree_model,GtkTreeIter * iter)1730 gtk_tree_model_unref_node (GtkTreeModel *tree_model,
1731                            GtkTreeIter  *iter)
1732 {
1733   GtkTreeModelIface *iface;
1734 
1735   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1736   g_return_if_fail (iter != NULL);
1737 
1738   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1739   if (iface->unref_node)
1740     (* iface->unref_node) (tree_model, iter);
1741 }
1742 
1743 /**
1744  * gtk_tree_model_get:
1745  * @tree_model: a #GtkTreeModel
1746  * @iter: a row in @tree_model
1747  * @...: pairs of column number and value return locations,
1748  *     terminated by -1
1749  *
1750  * Gets the value of one or more cells in the row referenced by @iter.
1751  * The variable argument list should contain integer column numbers,
1752  * each column number followed by a place to store the value being
1753  * retrieved.  The list is terminated by a -1. For example, to get a
1754  * value from column 0 with type %G_TYPE_STRING, you would
1755  * write: `gtk_tree_model_get (model, iter, 0, &place_string_here, -1)`,
1756  * where `place_string_here` is a #gchararray
1757  * to be filled with the string.
1758  *
1759  * Returned values with type %G_TYPE_OBJECT have to be unreferenced,
1760  * values with type %G_TYPE_STRING or %G_TYPE_BOXED have to be freed.
1761  * Other values are passed by value.
1762  */
1763 void
gtk_tree_model_get(GtkTreeModel * tree_model,GtkTreeIter * iter,...)1764 gtk_tree_model_get (GtkTreeModel *tree_model,
1765                     GtkTreeIter  *iter,
1766                     ...)
1767 {
1768   va_list var_args;
1769 
1770   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1771   g_return_if_fail (iter != NULL);
1772 
1773   va_start (var_args, iter);
1774   gtk_tree_model_get_valist (tree_model, iter, var_args);
1775   va_end (var_args);
1776 }
1777 
1778 /**
1779  * gtk_tree_model_get_valist:
1780  * @tree_model: a #GtkTreeModel
1781  * @iter: a row in @tree_model
1782  * @var_args: va_list of column/return location pairs
1783  *
1784  * See gtk_tree_model_get(), this version takes a va_list
1785  * for language bindings to use.
1786  */
1787 void
gtk_tree_model_get_valist(GtkTreeModel * tree_model,GtkTreeIter * iter,va_list var_args)1788 gtk_tree_model_get_valist (GtkTreeModel *tree_model,
1789                            GtkTreeIter  *iter,
1790                            va_list      var_args)
1791 {
1792   gint column;
1793 
1794   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1795   g_return_if_fail (iter != NULL);
1796 
1797   column = va_arg (var_args, gint);
1798 
1799   while (column != -1)
1800     {
1801       GValue value = G_VALUE_INIT;
1802       gchar *error = NULL;
1803 
1804       if (column >= gtk_tree_model_get_n_columns (tree_model))
1805         {
1806           g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
1807           break;
1808         }
1809 
1810       gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, column, &value);
1811 
1812       G_VALUE_LCOPY (&value, var_args, 0, &error);
1813       if (error)
1814         {
1815           g_warning ("%s: %s", G_STRLOC, error);
1816           g_free (error);
1817 
1818           /* we purposely leak the value here, it might not be
1819            * in a sane state if an error condition occurred
1820            */
1821           break;
1822         }
1823 
1824       g_value_unset (&value);
1825 
1826       column = va_arg (var_args, gint);
1827     }
1828 }
1829 
1830 /**
1831  * gtk_tree_model_row_changed:
1832  * @tree_model: a #GtkTreeModel
1833  * @path: a #GtkTreePath-struct pointing to the changed row
1834  * @iter: a valid #GtkTreeIter-struct pointing to the changed row
1835  *
1836  * Emits the #GtkTreeModel::row-changed signal on @tree_model.
1837  */
1838 void
gtk_tree_model_row_changed(GtkTreeModel * tree_model,GtkTreePath * path,GtkTreeIter * iter)1839 gtk_tree_model_row_changed (GtkTreeModel *tree_model,
1840                             GtkTreePath  *path,
1841                             GtkTreeIter  *iter)
1842 {
1843   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1844   g_return_if_fail (path != NULL);
1845   g_return_if_fail (iter != NULL);
1846 
1847   g_signal_emit (tree_model, tree_model_signals[ROW_CHANGED], 0, path, iter);
1848 }
1849 
1850 /**
1851  * gtk_tree_model_row_inserted:
1852  * @tree_model: a #GtkTreeModel
1853  * @path: a #GtkTreePath-struct pointing to the inserted row
1854  * @iter: a valid #GtkTreeIter-struct pointing to the inserted row
1855  *
1856  * Emits the #GtkTreeModel::row-inserted signal on @tree_model.
1857  */
1858 void
gtk_tree_model_row_inserted(GtkTreeModel * tree_model,GtkTreePath * path,GtkTreeIter * iter)1859 gtk_tree_model_row_inserted (GtkTreeModel *tree_model,
1860                              GtkTreePath  *path,
1861                              GtkTreeIter  *iter)
1862 {
1863   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1864   g_return_if_fail (path != NULL);
1865   g_return_if_fail (iter != NULL);
1866 
1867   g_signal_emit (tree_model, tree_model_signals[ROW_INSERTED], 0, path, iter);
1868 }
1869 
1870 /**
1871  * gtk_tree_model_row_has_child_toggled:
1872  * @tree_model: a #GtkTreeModel
1873  * @path: a #GtkTreePath-struct pointing to the changed row
1874  * @iter: a valid #GtkTreeIter-struct pointing to the changed row
1875  *
1876  * Emits the #GtkTreeModel::row-has-child-toggled signal on
1877  * @tree_model. This should be called by models after the child
1878  * state of a node changes.
1879  */
1880 void
gtk_tree_model_row_has_child_toggled(GtkTreeModel * tree_model,GtkTreePath * path,GtkTreeIter * iter)1881 gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model,
1882                                       GtkTreePath  *path,
1883                                       GtkTreeIter  *iter)
1884 {
1885   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1886   g_return_if_fail (path != NULL);
1887   g_return_if_fail (iter != NULL);
1888 
1889   g_signal_emit (tree_model, tree_model_signals[ROW_HAS_CHILD_TOGGLED], 0, path, iter);
1890 }
1891 
1892 /**
1893  * gtk_tree_model_row_deleted:
1894  * @tree_model: a #GtkTreeModel
1895  * @path: a #GtkTreePath-struct pointing to the previous location of
1896  *     the deleted row
1897  *
1898  * Emits the #GtkTreeModel::row-deleted signal on @tree_model.
1899  *
1900  * This should be called by models after a row has been removed.
1901  * The location pointed to by @path should be the location that
1902  * the row previously was at. It may not be a valid location anymore.
1903  *
1904  * Nodes that are deleted are not unreffed, this means that any
1905  * outstanding references on the deleted node should not be released.
1906  */
1907 void
gtk_tree_model_row_deleted(GtkTreeModel * tree_model,GtkTreePath * path)1908 gtk_tree_model_row_deleted (GtkTreeModel *tree_model,
1909                             GtkTreePath  *path)
1910 {
1911   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1912   g_return_if_fail (path != NULL);
1913 
1914   g_signal_emit (tree_model, tree_model_signals[ROW_DELETED], 0, path);
1915 }
1916 
1917 /**
1918  * gtk_tree_model_rows_reordered: (skip)
1919  * @tree_model: a #GtkTreeModel
1920  * @path: a #GtkTreePath-struct pointing to the tree node whose children
1921  *     have been reordered
1922  * @iter: a valid #GtkTreeIter-struct pointing to the node whose children
1923  *     have been reordered, or %NULL if the depth of @path is 0
1924  * @new_order: an array of integers mapping the current position of
1925  *     each child to its old position before the re-ordering,
1926  *     i.e. @new_order`[newpos] = oldpos`
1927  *
1928  * Emits the #GtkTreeModel::rows-reordered signal on @tree_model.
1929  *
1930  * This should be called by models when their rows have been
1931  * reordered.
1932  */
1933 void
gtk_tree_model_rows_reordered(GtkTreeModel * tree_model,GtkTreePath * path,GtkTreeIter * iter,gint * new_order)1934 gtk_tree_model_rows_reordered (GtkTreeModel *tree_model,
1935                                GtkTreePath  *path,
1936                                GtkTreeIter  *iter,
1937                                gint         *new_order)
1938 {
1939   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1940   g_return_if_fail (new_order != NULL);
1941 
1942   g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1943 }
1944 
1945 /**
1946  * gtk_tree_model_rows_reordered_with_length: (rename-to gtk_tree_model_rows_reordered)
1947  * @tree_model: a #GtkTreeModel
1948  * @path: a #GtkTreePath-struct pointing to the tree node whose children
1949  *     have been reordered
1950  * @iter: (allow-none): a valid #GtkTreeIter-struct pointing to the node
1951  *     whose children have been reordered, or %NULL if the depth
1952  *     of @path is 0
1953  * @new_order: (array length=length): an array of integers
1954  *     mapping the current position of each child to its old
1955  *     position before the re-ordering,
1956  *     i.e. @new_order`[newpos] = oldpos`
1957  * @length: length of @new_order array
1958  *
1959  * Emits the #GtkTreeModel::rows-reordered signal on @tree_model.
1960  *
1961  * This should be called by models when their rows have been
1962  * reordered.
1963  *
1964  * Since: 3.10
1965  */
1966 void
gtk_tree_model_rows_reordered_with_length(GtkTreeModel * tree_model,GtkTreePath * path,GtkTreeIter * iter,gint * new_order,gint length)1967 gtk_tree_model_rows_reordered_with_length (GtkTreeModel *tree_model,
1968                                            GtkTreePath  *path,
1969                                            GtkTreeIter  *iter,
1970                                            gint         *new_order,
1971                                            gint          length)
1972 {
1973   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1974   g_return_if_fail (new_order != NULL);
1975   g_return_if_fail (length == gtk_tree_model_iter_n_children (tree_model, iter));
1976 
1977   g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1978 }
1979 
1980 static gboolean
gtk_tree_model_foreach_helper(GtkTreeModel * model,GtkTreeIter * iter,GtkTreePath * path,GtkTreeModelForeachFunc func,gpointer user_data)1981 gtk_tree_model_foreach_helper (GtkTreeModel            *model,
1982                                GtkTreeIter             *iter,
1983                                GtkTreePath             *path,
1984                                GtkTreeModelForeachFunc  func,
1985                                gpointer                 user_data)
1986 {
1987   gboolean iters_persist;
1988 
1989   iters_persist = gtk_tree_model_get_flags (model) & GTK_TREE_MODEL_ITERS_PERSIST;
1990 
1991   do
1992     {
1993       GtkTreeIter child;
1994 
1995       if ((* func) (model, path, iter, user_data))
1996         return TRUE;
1997 
1998       if (!iters_persist)
1999         {
2000           if (!gtk_tree_model_get_iter (model, iter, path))
2001             return TRUE;
2002         }
2003 
2004       if (gtk_tree_model_iter_children (model, &child, iter))
2005         {
2006           gtk_tree_path_down (path);
2007           if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
2008             return TRUE;
2009           gtk_tree_path_up (path);
2010         }
2011 
2012       gtk_tree_path_next (path);
2013     }
2014   while (gtk_tree_model_iter_next (model, iter));
2015 
2016   return FALSE;
2017 }
2018 
2019 /**
2020  * gtk_tree_model_foreach:
2021  * @model: a #GtkTreeModel
2022  * @func: (scope call): a function to be called on each row
2023  * @user_data: user data to passed to @func
2024  *
2025  * Calls func on each node in model in a depth-first fashion.
2026  *
2027  * If @func returns %TRUE, then the tree ceases to be walked,
2028  * and gtk_tree_model_foreach() returns.
2029  */
2030 void
gtk_tree_model_foreach(GtkTreeModel * model,GtkTreeModelForeachFunc func,gpointer user_data)2031 gtk_tree_model_foreach (GtkTreeModel            *model,
2032                         GtkTreeModelForeachFunc  func,
2033                         gpointer                 user_data)
2034 {
2035   GtkTreePath *path;
2036   GtkTreeIter iter;
2037 
2038   g_return_if_fail (GTK_IS_TREE_MODEL (model));
2039   g_return_if_fail (func != NULL);
2040 
2041   path = gtk_tree_path_new_first ();
2042   if (!gtk_tree_model_get_iter (model, &iter, path))
2043     {
2044       gtk_tree_path_free (path);
2045       return;
2046     }
2047 
2048   gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
2049   gtk_tree_path_free (path);
2050 }
2051 
2052 
2053 /*
2054  * GtkTreeRowReference
2055  */
2056 
2057 static void gtk_tree_row_reference_unref_path (GtkTreePath  *path,
2058                                                GtkTreeModel *model,
2059                                                gint          depth);
2060 
2061 
2062 G_DEFINE_BOXED_TYPE (GtkTreeRowReference, gtk_tree_row_reference,
2063                      gtk_tree_row_reference_copy,
2064                      gtk_tree_row_reference_free)
2065 
2066 struct _GtkTreeRowReference
2067 {
2068   GObject *proxy;
2069   GtkTreeModel *model;
2070   GtkTreePath *path;
2071 };
2072 
2073 
2074 static void
release_row_references(gpointer data)2075 release_row_references (gpointer data)
2076 {
2077   RowRefList *refs = data;
2078   GSList *tmp_list = NULL;
2079 
2080   tmp_list = refs->list;
2081   while (tmp_list != NULL)
2082     {
2083       GtkTreeRowReference *reference = tmp_list->data;
2084 
2085       if (reference->proxy == (GObject *)reference->model)
2086         reference->model = NULL;
2087       reference->proxy = NULL;
2088 
2089       /* we don't free the reference, users are responsible for that. */
2090 
2091       tmp_list = tmp_list->next;
2092     }
2093 
2094   g_slist_free (refs->list);
2095   g_free (refs);
2096 }
2097 
2098 static void
gtk_tree_row_ref_inserted(RowRefList * refs,GtkTreePath * path,GtkTreeIter * iter)2099 gtk_tree_row_ref_inserted (RowRefList  *refs,
2100                            GtkTreePath *path,
2101                            GtkTreeIter *iter)
2102 {
2103   GSList *tmp_list;
2104 
2105   if (refs == NULL)
2106     return;
2107 
2108   /* This function corrects the path stored in the reference to
2109    * account for an insertion. Note that it's called _after_ the
2110    * insertion with the path to the newly-inserted row. Which means
2111    * that the inserted path is in a different "coordinate system" than
2112    * the old path (e.g. if the inserted path was just before the old
2113    * path, then inserted path and old path will be the same, and old
2114    * path must be moved down one).
2115    */
2116 
2117   tmp_list = refs->list;
2118 
2119   while (tmp_list != NULL)
2120     {
2121       GtkTreeRowReference *reference = tmp_list->data;
2122 
2123       if (reference->path == NULL)
2124         goto done;
2125 
2126       if (reference->path->depth >= path->depth)
2127         {
2128           gint i;
2129           gboolean ancestor = TRUE;
2130 
2131           for (i = 0; i < path->depth - 1; i ++)
2132             {
2133               if (path->indices[i] != reference->path->indices[i])
2134                 {
2135                   ancestor = FALSE;
2136                   break;
2137                 }
2138             }
2139           if (ancestor == FALSE)
2140             goto done;
2141 
2142           if (path->indices[path->depth-1] <= reference->path->indices[path->depth-1])
2143             reference->path->indices[path->depth-1] += 1;
2144         }
2145     done:
2146       tmp_list = tmp_list->next;
2147     }
2148 }
2149 
2150 static void
gtk_tree_row_ref_deleted(RowRefList * refs,GtkTreePath * path)2151 gtk_tree_row_ref_deleted (RowRefList  *refs,
2152                           GtkTreePath *path)
2153 {
2154   GSList *tmp_list;
2155 
2156   if (refs == NULL)
2157     return;
2158 
2159   /* This function corrects the path stored in the reference to
2160    * account for an deletion. Note that it's called _after_ the
2161    * deletion with the old path of the just-deleted row. Which means
2162    * that the deleted path is the same now-defunct "coordinate system"
2163    * as the path saved in the reference, which is what we want to fix.
2164    */
2165 
2166   tmp_list = refs->list;
2167 
2168   while (tmp_list != NULL)
2169     {
2170       GtkTreeRowReference *reference = tmp_list->data;
2171 
2172       if (reference->path)
2173         {
2174           gint i;
2175 
2176           if (path->depth > reference->path->depth)
2177             goto next;
2178           for (i = 0; i < path->depth - 1; i++)
2179             {
2180               if (path->indices[i] != reference->path->indices[i])
2181                 goto next;
2182             }
2183 
2184           /* We know it affects us. */
2185           if (path->indices[i] == reference->path->indices[i])
2186             {
2187               if (reference->path->depth > path->depth)
2188                 /* some parent was deleted, trying to unref any node
2189                  * between the deleted parent and the node the reference
2190                  * is pointing to is bad, as those nodes are already gone.
2191                  */
2192                 gtk_tree_row_reference_unref_path (reference->path, reference->model, path->depth - 1);
2193               else
2194                 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth - 1);
2195               gtk_tree_path_free (reference->path);
2196               reference->path = NULL;
2197             }
2198           else if (path->indices[i] < reference->path->indices[i])
2199             {
2200               reference->path->indices[path->depth-1]-=1;
2201             }
2202         }
2203 
2204 next:
2205       tmp_list = tmp_list->next;
2206     }
2207 }
2208 
2209 static void
gtk_tree_row_ref_reordered(RowRefList * refs,GtkTreePath * path,GtkTreeIter * iter,gint * new_order)2210 gtk_tree_row_ref_reordered (RowRefList  *refs,
2211                             GtkTreePath *path,
2212                             GtkTreeIter *iter,
2213                             gint        *new_order)
2214 {
2215   GSList *tmp_list;
2216   gint length;
2217 
2218   if (refs == NULL)
2219     return;
2220 
2221   tmp_list = refs->list;
2222 
2223   while (tmp_list != NULL)
2224     {
2225       GtkTreeRowReference *reference = tmp_list->data;
2226 
2227       length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (reference->model), iter);
2228 
2229       if (length < 2)
2230         return;
2231 
2232       if ((reference->path) &&
2233           (gtk_tree_path_is_ancestor (path, reference->path)))
2234         {
2235           gint ref_depth = gtk_tree_path_get_depth (reference->path);
2236           gint depth = gtk_tree_path_get_depth (path);
2237 
2238           if (ref_depth > depth)
2239             {
2240               gint i;
2241               gint *indices = gtk_tree_path_get_indices (reference->path);
2242 
2243               for (i = 0; i < length; i++)
2244                 {
2245                   if (new_order[i] == indices[depth])
2246                     {
2247                       indices[depth] = i;
2248                       break;
2249                     }
2250                 }
2251             }
2252         }
2253 
2254       tmp_list = tmp_list->next;
2255     }
2256 }
2257 
2258 /* We do this recursively so that we can unref children nodes
2259  * before their parent
2260  */
2261 static void
gtk_tree_row_reference_unref_path_helper(GtkTreePath * path,GtkTreeModel * model,GtkTreeIter * parent_iter,gint depth,gint current_depth)2262 gtk_tree_row_reference_unref_path_helper (GtkTreePath  *path,
2263                                           GtkTreeModel *model,
2264                                           GtkTreeIter  *parent_iter,
2265                                           gint          depth,
2266                                           gint          current_depth)
2267 {
2268   GtkTreeIter iter;
2269 
2270   if (depth == current_depth)
2271     return;
2272 
2273   gtk_tree_model_iter_nth_child (model, &iter, parent_iter, path->indices[current_depth]);
2274   gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, current_depth + 1);
2275   gtk_tree_model_unref_node (model, &iter);
2276 }
2277 
2278 static void
gtk_tree_row_reference_unref_path(GtkTreePath * path,GtkTreeModel * model,gint depth)2279 gtk_tree_row_reference_unref_path (GtkTreePath  *path,
2280                                    GtkTreeModel *model,
2281                                    gint          depth)
2282 {
2283   GtkTreeIter iter;
2284 
2285   if (depth <= 0)
2286     return;
2287 
2288   gtk_tree_model_iter_nth_child (model, &iter, NULL, path->indices[0]);
2289   gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, 1);
2290   gtk_tree_model_unref_node (model, &iter);
2291 }
2292 
2293 /**
2294  * gtk_tree_row_reference_new:
2295  * @model: a #GtkTreeModel
2296  * @path: a valid #GtkTreePath-struct to monitor
2297  *
2298  * Creates a row reference based on @path.
2299  *
2300  * This reference will keep pointing to the node pointed to
2301  * by @path, so long as it exists. Any changes that occur on @model are
2302  * propagated, and the path is updated appropriately. If
2303  * @path isn’t a valid path in @model, then %NULL is returned.
2304  *
2305  * Returns: a newly allocated #GtkTreeRowReference, or %NULL
2306  */
2307 GtkTreeRowReference *
gtk_tree_row_reference_new(GtkTreeModel * model,GtkTreePath * path)2308 gtk_tree_row_reference_new (GtkTreeModel *model,
2309                             GtkTreePath  *path)
2310 {
2311   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2312   g_return_val_if_fail (path != NULL, NULL);
2313 
2314   /* We use the model itself as the proxy object; and call
2315    * gtk_tree_row_reference_inserted(), etc, in the
2316    * class closure (default handler) marshalers for the signal.
2317    */
2318   return gtk_tree_row_reference_new_proxy (G_OBJECT (model), model, path);
2319 }
2320 
2321 /**
2322  * gtk_tree_row_reference_new_proxy:
2323  * @proxy: a proxy #GObject
2324  * @model: a #GtkTreeModel
2325  * @path: a valid #GtkTreePath-struct to monitor
2326  *
2327  * You do not need to use this function.
2328  *
2329  * Creates a row reference based on @path.
2330  *
2331  * This reference will keep pointing to the node pointed to
2332  * by @path, so long as it exists. If @path isn’t a valid
2333  * path in @model, then %NULL is returned. However, unlike
2334  * references created with gtk_tree_row_reference_new(), it
2335  * does not listen to the model for changes. The creator of
2336  * the row reference must do this explicitly using
2337  * gtk_tree_row_reference_inserted(), gtk_tree_row_reference_deleted(),
2338  * gtk_tree_row_reference_reordered().
2339  *
2340  * These functions must be called exactly once per proxy when the
2341  * corresponding signal on the model is emitted. This single call
2342  * updates all row references for that proxy. Since built-in GTK+
2343  * objects like #GtkTreeView already use this mechanism internally,
2344  * using them as the proxy object will produce unpredictable results.
2345  * Further more, passing the same object as @model and @proxy
2346  * doesn’t work for reasons of internal implementation.
2347  *
2348  * This type of row reference is primarily meant by structures that
2349  * need to carefully monitor exactly when a row reference updates
2350  * itself, and is not generally needed by most applications.
2351  *
2352  * Returns: a newly allocated #GtkTreeRowReference, or %NULL
2353  */
2354 GtkTreeRowReference *
gtk_tree_row_reference_new_proxy(GObject * proxy,GtkTreeModel * model,GtkTreePath * path)2355 gtk_tree_row_reference_new_proxy (GObject      *proxy,
2356                                   GtkTreeModel *model,
2357                                   GtkTreePath  *path)
2358 {
2359   GtkTreeRowReference *reference;
2360   RowRefList *refs;
2361   GtkTreeIter parent_iter;
2362   gint i;
2363 
2364   g_return_val_if_fail (G_IS_OBJECT (proxy), NULL);
2365   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2366   g_return_val_if_fail (path != NULL, NULL);
2367   g_return_val_if_fail (path->depth > 0, NULL);
2368 
2369   /* check that the path is valid */
2370   if (gtk_tree_model_get_iter (model, &parent_iter, path) == FALSE)
2371     return NULL;
2372 
2373   /* Now we want to ref every node */
2374   gtk_tree_model_iter_nth_child (model, &parent_iter, NULL, path->indices[0]);
2375   gtk_tree_model_ref_node (model, &parent_iter);
2376 
2377   for (i = 1; i < path->depth; i++)
2378     {
2379       GtkTreeIter iter;
2380       gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, path->indices[i]);
2381       gtk_tree_model_ref_node (model, &iter);
2382       parent_iter = iter;
2383     }
2384 
2385   /* Make the row reference */
2386   reference = g_new (GtkTreeRowReference, 1);
2387 
2388   g_object_ref (proxy);
2389   g_object_ref (model);
2390   reference->proxy = proxy;
2391   reference->model = model;
2392   reference->path = gtk_tree_path_copy (path);
2393 
2394   refs = g_object_get_data (G_OBJECT (proxy), ROW_REF_DATA_STRING);
2395 
2396   if (refs == NULL)
2397     {
2398       refs = g_new (RowRefList, 1);
2399       refs->list = NULL;
2400 
2401       g_object_set_data_full (G_OBJECT (proxy),
2402                               I_(ROW_REF_DATA_STRING),
2403                               refs, release_row_references);
2404     }
2405 
2406   refs->list = g_slist_prepend (refs->list, reference);
2407 
2408   return reference;
2409 }
2410 
2411 /**
2412  * gtk_tree_row_reference_get_path:
2413  * @reference: a #GtkTreeRowReference
2414  *
2415  * Returns a path that the row reference currently points to,
2416  * or %NULL if the path pointed to is no longer valid.
2417  *
2418  * Returns: (nullable) (transfer full): a current path, or %NULL
2419  */
2420 GtkTreePath *
gtk_tree_row_reference_get_path(GtkTreeRowReference * reference)2421 gtk_tree_row_reference_get_path (GtkTreeRowReference *reference)
2422 {
2423   g_return_val_if_fail (reference != NULL, NULL);
2424 
2425   if (reference->proxy == NULL)
2426     return NULL;
2427 
2428   if (reference->path == NULL)
2429     return NULL;
2430 
2431   return gtk_tree_path_copy (reference->path);
2432 }
2433 
2434 /**
2435  * gtk_tree_row_reference_get_model:
2436  * @reference: a #GtkTreeRowReference
2437  *
2438  * Returns the model that the row reference is monitoring.
2439  *
2440  * Returns: (transfer none): the model
2441  *
2442  * Since: 2.8
2443  */
2444 GtkTreeModel *
gtk_tree_row_reference_get_model(GtkTreeRowReference * reference)2445 gtk_tree_row_reference_get_model (GtkTreeRowReference *reference)
2446 {
2447   g_return_val_if_fail (reference != NULL, NULL);
2448 
2449   return reference->model;
2450 }
2451 
2452 /**
2453  * gtk_tree_row_reference_valid:
2454  * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2455  *
2456  * Returns %TRUE if the @reference is non-%NULL and refers to
2457  * a current valid path.
2458  *
2459  * Returns: %TRUE if @reference points to a valid path
2460  */
2461 gboolean
gtk_tree_row_reference_valid(GtkTreeRowReference * reference)2462 gtk_tree_row_reference_valid (GtkTreeRowReference *reference)
2463 {
2464   if (reference == NULL || reference->path == NULL)
2465     return FALSE;
2466 
2467   return TRUE;
2468 }
2469 
2470 
2471 /**
2472  * gtk_tree_row_reference_copy:
2473  * @reference: a #GtkTreeRowReference
2474  *
2475  * Copies a #GtkTreeRowReference.
2476  *
2477  * Returns: a copy of @reference
2478  *
2479  * Since: 2.2
2480  */
2481 GtkTreeRowReference *
gtk_tree_row_reference_copy(GtkTreeRowReference * reference)2482 gtk_tree_row_reference_copy (GtkTreeRowReference *reference)
2483 {
2484   return gtk_tree_row_reference_new_proxy (reference->proxy,
2485                                            reference->model,
2486                                            reference->path);
2487 }
2488 
2489 /**
2490  * gtk_tree_row_reference_free:
2491  * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2492  *
2493  * Free’s @reference. @reference may be %NULL
2494  */
2495 void
gtk_tree_row_reference_free(GtkTreeRowReference * reference)2496 gtk_tree_row_reference_free (GtkTreeRowReference *reference)
2497 {
2498   RowRefList *refs;
2499 
2500   if (reference == NULL)
2501     return;
2502 
2503   refs = g_object_get_data (G_OBJECT (reference->proxy), ROW_REF_DATA_STRING);
2504 
2505   if (refs == NULL)
2506     {
2507       g_warning (G_STRLOC": bad row reference, proxy has no outstanding row references");
2508       return;
2509     }
2510 
2511   refs->list = g_slist_remove (refs->list, reference);
2512 
2513   if (refs->list == NULL)
2514     {
2515       g_object_set_data (G_OBJECT (reference->proxy),
2516                          I_(ROW_REF_DATA_STRING),
2517                          NULL);
2518     }
2519 
2520   if (reference->path)
2521     {
2522       gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth);
2523       gtk_tree_path_free (reference->path);
2524     }
2525 
2526   g_object_unref (reference->proxy);
2527   g_object_unref (reference->model);
2528   g_free (reference);
2529 }
2530 
2531 /**
2532  * gtk_tree_row_reference_inserted:
2533  * @proxy: a #GObject
2534  * @path: the row position that was inserted
2535  *
2536  * Lets a set of row reference created by
2537  * gtk_tree_row_reference_new_proxy() know that the
2538  * model emitted the #GtkTreeModel::row-inserted signal.
2539  */
2540 void
gtk_tree_row_reference_inserted(GObject * proxy,GtkTreePath * path)2541 gtk_tree_row_reference_inserted (GObject     *proxy,
2542                                  GtkTreePath *path)
2543 {
2544   g_return_if_fail (G_IS_OBJECT (proxy));
2545 
2546   gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, NULL);
2547 }
2548 
2549 /**
2550  * gtk_tree_row_reference_deleted:
2551  * @proxy: a #GObject
2552  * @path: the path position that was deleted
2553  *
2554  * Lets a set of row reference created by
2555  * gtk_tree_row_reference_new_proxy() know that the
2556  * model emitted the #GtkTreeModel::row-deleted signal.
2557  */
2558 void
gtk_tree_row_reference_deleted(GObject * proxy,GtkTreePath * path)2559 gtk_tree_row_reference_deleted (GObject     *proxy,
2560                                 GtkTreePath *path)
2561 {
2562   g_return_if_fail (G_IS_OBJECT (proxy));
2563 
2564   gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path);
2565 }
2566 
2567 /**
2568  * gtk_tree_row_reference_reordered: (skip)
2569  * @proxy: a #GObject
2570  * @path: the parent path of the reordered signal
2571  * @iter: the iter pointing to the parent of the reordered
2572  * @new_order: (array): the new order of rows
2573  *
2574  * Lets a set of row reference created by
2575  * gtk_tree_row_reference_new_proxy() know that the
2576  * model emitted the #GtkTreeModel::rows-reordered signal.
2577  */
2578 void
gtk_tree_row_reference_reordered(GObject * proxy,GtkTreePath * path,GtkTreeIter * iter,gint * new_order)2579 gtk_tree_row_reference_reordered (GObject     *proxy,
2580                                   GtkTreePath *path,
2581                                   GtkTreeIter *iter,
2582                                   gint        *new_order)
2583 {
2584   g_return_if_fail (G_IS_OBJECT (proxy));
2585 
2586   gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, iter, new_order);
2587 }
2588