Bug Summary

File:ctk/ctktreemodel.c
Warning:line 807, column 7
Null pointer passed to 2nd parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ctktreemodel.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/ctk -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Ctk" -D G_LOG_USE_STRUCTURED=1 -D CTK_VERSION="3.25.5" -D CTK_BINARY_VERSION="3.0.0" -D CTK_COMPILATION -D CTK_PRINT_BACKEND_ENABLE_UNSUPPORTED -D CTK_LIBDIR="/usr/lib" -D CTK_LOCALEDIR="/usr/share/locale" -D CTK_DATADIR="/usr/share" -D CTK_DATA_PREFIX="/usr" -D CTK_SYSCONFDIR="/usr/etc" -D CTK_HOST="x86_64-pc-linux-gnu" -D CTK_PRINT_BACKENDS="file,cups" -D X11_DATA_PREFIX="/usr" -D ISO_CODES_PREFIX="" -I .. -I ../ctk -I .. -I ../cdk -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/ctk -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-172934-43638-1 -x c ctktreemodel.c
1/* ctktreemodel.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 "ctktreemodel.h"
25#include "ctktreeview.h"
26#include "ctktreeprivate.h"
27#include "ctkmarshalers.h"
28#include "ctkintl.h"
29
30/**
31 * SECTION:ctktreemodel
32 * @Title: CtkTreeModel
33 * @Short_description: The tree interface used by CtkTreeView
34 * @See_also: #CtkTreeView, #CtkTreeStore, #CtkListStore,
35 * [CtkTreeView drag-and-drop][ctk3-CtkTreeView-drag-and-drop]
36 * #CtkTreeSortable
37 *
38 * The #CtkTreeModel interface defines a generic tree interface for
39 * use by the #CtkTreeView 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 #CtkTreeView 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, #CTK_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 #CtkTreeStore and the #CtkListStore. 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 #CtkTreePath-struct and
67 * the #CtkTreeIter-struct (“iter” is short for iterator). Most of the
68 * interface consists of operations on a #CtkTreeIter-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 #CtkTreePath-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 #CtkTreeIter-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 * ctk_tree_model_get_iter(). These iterators are the primary way
84 * of accessing a model and are similar to the iterators used by
85 * #CtkTextBuffer. 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 #CtkListStore model, which is internally a simple
91 * linked list, stores a list node in one of the pointers. The
92 * #CtkTreeModelSort 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 #CtkTreeStore and #CtkListStore).
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 #CTK_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 #CtkTreeIter-struct
117 *
118 * |[<!-- language="C" -->
119 * // Three ways of getting the iter pointing to the location
120 * CtkTreePath *path;
121 * CtkTreeIter iter;
122 * CtkTreeIter parent_iter;
123 *
124 * // get the iterator from a string
125 * ctk_tree_model_get_iter_from_string (model,
126 * &iter,
127 * "3:2:5");
128 *
129 * // get the iterator from a path
130 * path = ctk_tree_path_new_from_string ("3:2:5");
131 * ctk_tree_model_get_iter (model, &iter, path);
132 * ctk_tree_path_free (path);
133 *
134 * // walk the tree to find the iterator
135 * ctk_tree_model_iter_nth_child (model, &iter,
136 * NULL, 3);
137 * parent_iter = iter;
138 * ctk_tree_model_iter_nth_child (model, &iter,
139 * &parent_iter, 2);
140 * parent_iter = iter;
141 * ctk_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 #CtkListStore. For information on
149 * how to write such a function, see the #CtkListStore documentation.
150 *
151 * ## Reading data from a #CtkTreeModel
152 *
153 * |[<!-- language="C" -->
154 * enum
155 * {
156 * STRING_COLUMN,
157 * INT_COLUMN,
158 * N_COLUMNS
159 * };
160 *
161 * ...
162 *
163 * CtkTreeModel *list_store;
164 * CtkTreeIter iter;
165 * gboolean valid;
166 * gint row_count = 0;
167 *
168 * // make a new list_store
169 * list_store = ctk_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 = ctk_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 ctk_tree_model_get() with a “-1” value
187 * ctk_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 = ctk_tree_model_iter_next (list_store,
198 * &iter);
199 * row_count++;
200 * }
201 * ]|
202 *
203 * The #CtkTreeModel interface contains two methods for reference
204 * counting: ctk_tree_model_ref_node() and ctk_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. #CtkTreeView 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)do{ (Iter)->stamp = 0; (Iter)->user_data = ((void*)0); (
Iter)->user_data2 = ((void*)0); (Iter)->user_data3 = ((
void*)0); }while (0)
\
235 G_STMT_STARTdo{ \
236 (Iter)->stamp = 0; \
237 (Iter)->user_data = NULL((void*)0); \
238 (Iter)->user_data2 = NULL((void*)0); \
239 (Iter)->user_data3 = NULL((void*)0); \
240 }G_STMT_ENDwhile (0)
241
242#define ROW_REF_DATA_STRING"ctk-tree-row-refs" "ctk-tree-row-refs"
243
244enum {
245 ROW_CHANGED,
246 ROW_INSERTED,
247 ROW_HAS_CHILD_TOGGLED,
248 ROW_DELETED,
249 ROWS_REORDERED,
250 LAST_SIGNAL
251};
252
253static guint tree_model_signals[LAST_SIGNAL] = { 0 };
254
255struct _CtkTreePath
256{
257 gint depth; /* Number of elements */
258 gint alloc; /* Number of allocated elements */
259 gint *indices;
260};
261
262typedef struct
263{
264 GSList *list;
265} RowRefList;
266
267static void ctk_tree_model_base_init (gpointer g_class);
268
269/* custom closures */
270static 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);
276static 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);
282static 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
289static void ctk_tree_row_ref_inserted (RowRefList *refs,
290 CtkTreePath *path,
291 CtkTreeIter *iter);
292static void ctk_tree_row_ref_deleted (RowRefList *refs,
293 CtkTreePath *path);
294static void ctk_tree_row_ref_reordered (RowRefList *refs,
295 CtkTreePath *path,
296 CtkTreeIter *iter,
297 gint *new_order);
298
299GType
300ctk_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 .class_size = sizeof (CtkTreeModelIface),
309 .base_init = ctk_tree_model_base_init,
310 .instance_size = 0,
311 .n_preallocs = 0
312 };
313
314 tree_model_type =
315 g_type_register_static (G_TYPE_INTERFACE((GType) ((2) << (2))), I_("CtkTreeModel")g_intern_static_string ("CtkTreeModel"),
316 &tree_model_info, 0);
317
318 g_type_interface_add_prerequisite (tree_model_type, G_TYPE_OBJECT((GType) ((20) << (2))));
319 }
320
321 return tree_model_type;
322}
323
324static void
325ctk_tree_model_base_init (gpointer g_class)
326{
327 static gboolean initialized = FALSE(0);
328 GClosure *closure;
329
330 if (! initialized)
331 {
332 GType row_inserted_params[2];
333 GType row_deleted_params[1];
334 GType rows_reordered_params[3];
335
336 row_inserted_params[0] = CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ()) | G_SIGNAL_TYPE_STATIC_SCOPE(((GType) (1 << 0)));
337 row_inserted_params[1] = CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ());
338
339 row_deleted_params[0] = CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ()) | G_SIGNAL_TYPE_STATIC_SCOPE(((GType) (1 << 0)));
340
341 rows_reordered_params[0] = CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ()) | G_SIGNAL_TYPE_STATIC_SCOPE(((GType) (1 << 0)));
342 rows_reordered_params[1] = CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ());
343 rows_reordered_params[2] = G_TYPE_POINTER((GType) ((17) << (2)));
344
345 /**
346 * CtkTreeModel::row-changed:
347 * @tree_model: the #CtkTreeModel on which the signal is emitted
348 * @path: a #CtkTreePath-struct identifying the changed row
349 * @iter: a valid #CtkTreeIter-struct pointing to the changed row
350 *
351 * This signal is emitted when a row in the model has changed.
352 */
353 tree_model_signals[ROW_CHANGED] =
354 g_signal_new (I_("row-changed")g_intern_static_string ("row-changed"),
355 CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()),
356 G_SIGNAL_RUN_LAST,
357 G_STRUCT_OFFSET (CtkTreeModelIface, row_changed)((glong) __builtin_offsetof(CtkTreeModelIface, row_changed)),
358 NULL((void*)0), NULL((void*)0),
359 _ctk_marshal_VOID__BOXED_BOXED,
360 G_TYPE_NONE((GType) ((1) << (2))), 2,
361 CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ()) | G_SIGNAL_TYPE_STATIC_SCOPE(((GType) (1 << 0))),
362 CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ()));
363 g_signal_set_va_marshaller (tree_model_signals[ROW_CHANGED],
364 G_TYPE_FROM_CLASS (g_class)(((GTypeClass*) (g_class))->g_type),
365 _ctk_marshal_VOID__BOXED_BOXEDv);
366
367 /* We need to get notification about structure changes
368 * to update row references., so instead of using the
369 * standard g_signal_new() with an offset into our interface
370 * structure, we use a customs closures for the class
371 * closures (default handlers) that first update row references
372 * and then calls the function from the interface structure.
373 *
374 * The reason we don't simply update the row references from
375 * the wrapper functions (ctk_tree_model_row_inserted(), etc.)
376 * is to keep proper ordering with respect to signal handlers
377 * connected normally and after.
378 */
379
380 /**
381 * CtkTreeModel::row-inserted:
382 * @tree_model: the #CtkTreeModel on which the signal is emitted
383 * @path: a #CtkTreePath-struct identifying the new row
384 * @iter: a valid #CtkTreeIter-struct pointing to the new row
385 *
386 * This signal is emitted when a new row has been inserted in
387 * the model.
388 *
389 * Note that the row may still be empty at this point, since
390 * it is a common pattern to first insert an empty row, and
391 * then fill it with the desired values.
392 */
393 closure = g_closure_new_simple (sizeof (GClosure), NULL((void*)0));
394 g_closure_set_marshal (closure, row_inserted_marshal);
395 tree_model_signals[ROW_INSERTED] =
396 g_signal_newv (I_("row-inserted")g_intern_static_string ("row-inserted"),
397 CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()),
398 G_SIGNAL_RUN_FIRST,
399 closure,
400 NULL((void*)0), NULL((void*)0),
401 _ctk_marshal_VOID__BOXED_BOXED,
402 G_TYPE_NONE((GType) ((1) << (2))), 2,
403 row_inserted_params);
404 g_signal_set_va_marshaller (tree_model_signals[ROW_INSERTED],
405 G_TYPE_FROM_CLASS (g_class)(((GTypeClass*) (g_class))->g_type),
406 _ctk_marshal_VOID__BOXED_BOXEDv);
407
408 /**
409 * CtkTreeModel::row-has-child-toggled:
410 * @tree_model: the #CtkTreeModel on which the signal is emitted
411 * @path: a #CtkTreePath-struct identifying the row
412 * @iter: a valid #CtkTreeIter-struct pointing to the row
413 *
414 * This signal is emitted when a row has gotten the first child
415 * row or lost its last child row.
416 */
417 tree_model_signals[ROW_HAS_CHILD_TOGGLED] =
418 g_signal_new (I_("row-has-child-toggled")g_intern_static_string ("row-has-child-toggled"),
419 CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()),
420 G_SIGNAL_RUN_LAST,
421 G_STRUCT_OFFSET (CtkTreeModelIface, row_has_child_toggled)((glong) __builtin_offsetof(CtkTreeModelIface, row_has_child_toggled
))
,
422 NULL((void*)0), NULL((void*)0),
423 _ctk_marshal_VOID__BOXED_BOXED,
424 G_TYPE_NONE((GType) ((1) << (2))), 2,
425 CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ()) | G_SIGNAL_TYPE_STATIC_SCOPE(((GType) (1 << 0))),
426 CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ()));
427 g_signal_set_va_marshaller (tree_model_signals[ROW_HAS_CHILD_TOGGLED],
428 G_TYPE_FROM_CLASS (g_class)(((GTypeClass*) (g_class))->g_type),
429 _ctk_marshal_VOID__BOXED_BOXEDv);
430
431 /**
432 * CtkTreeModel::row-deleted:
433 * @tree_model: the #CtkTreeModel on which the signal is emitted
434 * @path: a #CtkTreePath-struct identifying the row
435 *
436 * This signal is emitted when a row has been deleted.
437 *
438 * Note that no iterator is passed to the signal handler,
439 * since the row is already deleted.
440 *
441 * This should be called by models after a row has been removed.
442 * The location pointed to by @path should be the location that
443 * the row previously was at. It may not be a valid location anymore.
444 */
445 closure = g_closure_new_simple (sizeof (GClosure), NULL((void*)0));
446 g_closure_set_marshal (closure, row_deleted_marshal);
447 tree_model_signals[ROW_DELETED] =
448 g_signal_newv (I_("row-deleted")g_intern_static_string ("row-deleted"),
449 CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()),
450 G_SIGNAL_RUN_FIRST,
451 closure,
452 NULL((void*)0), NULL((void*)0),
453 NULL((void*)0),
454 G_TYPE_NONE((GType) ((1) << (2))), 1,
455 row_deleted_params);
456
457 /**
458 * CtkTreeModel::rows-reordered: (skip)
459 * @tree_model: the #CtkTreeModel on which the signal is emitted
460 * @path: a #CtkTreePath-struct identifying the tree node whose children
461 * have been reordered
462 * @iter: a valid #CtkTreeIter-struct pointing to the node whose children
463 * have been reordered, or %NULL if the depth of @path is 0
464 * @new_order: an array of integers mapping the current position
465 * of each child to its old position before the re-ordering,
466 * i.e. @new_order`[newpos] = oldpos`
467 *
468 * This signal is emitted when the children of a node in the
469 * #CtkTreeModel have been reordered.
470 *
471 * Note that this signal is not emitted
472 * when rows are reordered by DND, since this is implemented
473 * by removing and then reinserting the row.
474 */
475 closure = g_closure_new_simple (sizeof (GClosure), NULL((void*)0));
476 g_closure_set_marshal (closure, rows_reordered_marshal);
477 tree_model_signals[ROWS_REORDERED] =
478 g_signal_newv (I_("rows-reordered")g_intern_static_string ("rows-reordered"),
479 CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()),
480 G_SIGNAL_RUN_FIRST,
481 closure,
482 NULL((void*)0), NULL((void*)0),
483 _ctk_marshal_VOID__BOXED_BOXED_POINTER,
484 G_TYPE_NONE((GType) ((1) << (2))), 3,
485 rows_reordered_params);
486 g_signal_set_va_marshaller (tree_model_signals[ROWS_REORDERED],
487 G_TYPE_FROM_CLASS (g_class)(((GTypeClass*) (g_class))->g_type),
488 _ctk_marshal_VOID__BOXED_BOXED_POINTERv);
489 initialized = TRUE(!(0));
490 }
491}
492
493static void
494row_inserted_marshal (GClosure *closure G_GNUC_UNUSED__attribute__ ((__unused__)),
495 GValue /* out */ *return_value G_GNUC_UNUSED__attribute__ ((__unused__)),
496 guint n_param_values G_GNUC_UNUSED__attribute__ ((__unused__)),
497 const GValue *param_values,
498 gpointer invocation_hint G_GNUC_UNUSED__attribute__ ((__unused__)),
499 gpointer marshal_data G_GNUC_UNUSED__attribute__ ((__unused__)))
500{
501 CtkTreeModelIface *iface;
502
503 void (* row_inserted_callback) (CtkTreeModel *tree_model,
504 CtkTreePath *path,
505 CtkTreeIter *iter) = NULL((void*)0);
506
507 GObject *model = g_value_get_object (param_values + 0);
508 CtkTreePath *path = (CtkTreePath *)g_value_get_boxed (param_values + 1);
509 CtkTreeIter *iter = (CtkTreeIter *)g_value_get_boxed (param_values + 2);
510
511 /* first, we need to update internal row references */
512 ctk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING"ctk-tree-row-refs"),
513 path, iter);
514
515 /* fetch the interface ->row_inserted implementation */
516 iface = CTK_TREE_MODEL_GET_IFACE (model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((model)))->g_class, ((ctk_tree_model_get_type ()))))))
;
517 row_inserted_callback = G_STRUCT_MEMBER (gpointer, iface,(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, row_inserted))))
)))
518 G_STRUCT_OFFSET (CtkTreeModelIface,(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, row_inserted))))
)))
519 row_inserted))(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, row_inserted))))
)))
;
520
521 /* Call that default signal handler, it if has been set */
522 if (row_inserted_callback)
523 row_inserted_callback (CTK_TREE_MODEL (model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_model_get_type ()))))))
, path, iter);
524}
525
526static void
527row_deleted_marshal (GClosure *closure G_GNUC_UNUSED__attribute__ ((__unused__)),
528 GValue /* out */ *return_value G_GNUC_UNUSED__attribute__ ((__unused__)),
529 guint n_param_values G_GNUC_UNUSED__attribute__ ((__unused__)),
530 const GValue *param_values,
531 gpointer invocation_hint G_GNUC_UNUSED__attribute__ ((__unused__)),
532 gpointer marshal_data G_GNUC_UNUSED__attribute__ ((__unused__)))
533{
534 CtkTreeModelIface *iface;
535 void (* row_deleted_callback) (CtkTreeModel *tree_model,
536 CtkTreePath *path) = NULL((void*)0);
537 GObject *model = g_value_get_object (param_values + 0);
538 CtkTreePath *path = (CtkTreePath *)g_value_get_boxed (param_values + 1);
539
540 /* first, we need to update internal row references */
541 ctk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING"ctk-tree-row-refs"),
542 path);
543
544 /* fetch the interface ->row_deleted implementation */
545 iface = CTK_TREE_MODEL_GET_IFACE (model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((model)))->g_class, ((ctk_tree_model_get_type ()))))))
;
546 row_deleted_callback = G_STRUCT_MEMBER (gpointer, iface,(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, row_deleted)))))
))
547 G_STRUCT_OFFSET (CtkTreeModelIface,(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, row_deleted)))))
))
548 row_deleted))(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, row_deleted)))))
))
;
549
550 /* Call that default signal handler, it if has been set */
551 if (row_deleted_callback)
552 row_deleted_callback (CTK_TREE_MODEL (model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_model_get_type ()))))))
, path);
553}
554
555static void
556rows_reordered_marshal (GClosure *closure G_GNUC_UNUSED__attribute__ ((__unused__)),
557 GValue /* out */ *return_value G_GNUC_UNUSED__attribute__ ((__unused__)),
558 guint n_param_values G_GNUC_UNUSED__attribute__ ((__unused__)),
559 const GValue *param_values,
560 gpointer invocation_hint G_GNUC_UNUSED__attribute__ ((__unused__)),
561 gpointer marshal_data G_GNUC_UNUSED__attribute__ ((__unused__)))
562{
563 CtkTreeModelIface *iface;
564 void (* rows_reordered_callback) (CtkTreeModel *tree_model,
565 CtkTreePath *path,
566 CtkTreeIter *iter,
567 gint *new_order);
568
569 GObject *model = g_value_get_object (param_values + 0);
570 CtkTreePath *path = (CtkTreePath *)g_value_get_boxed (param_values + 1);
571 CtkTreeIter *iter = (CtkTreeIter *)g_value_get_boxed (param_values + 2);
572 gint *new_order = (gint *)g_value_get_pointer (param_values + 3);
573
574 /* first, we need to update internal row references */
575 ctk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING"ctk-tree-row-refs"),
576 path, iter, new_order);
577
578 /* fetch the interface ->rows_reordered implementation */
579 iface = CTK_TREE_MODEL_GET_IFACE (model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((model)))->g_class, ((ctk_tree_model_get_type ()))))))
;
580 rows_reordered_callback = G_STRUCT_MEMBER (gpointer, iface,(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, rows_reordered))
)))))
581 G_STRUCT_OFFSET (CtkTreeModelIface,(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, rows_reordered))
)))))
582 rows_reordered))(*(gpointer*) ((gpointer) ((guint8*) ((iface)) + (glong) ((((
glong) __builtin_offsetof(CtkTreeModelIface, rows_reordered))
)))))
;
583
584 /* Call that default signal handler, it if has been set */
585 if (rows_reordered_callback)
586 rows_reordered_callback (CTK_TREE_MODEL (model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_model_get_type ()))))))
, path, iter, new_order);
587}
588
589/**
590 * ctk_tree_path_new:
591 *
592 * Creates a new #CtkTreePath-struct.
593 * This refers to a row.
594 *
595 * Returns: A newly created #CtkTreePath-struct.
596 */
597CtkTreePath *
598ctk_tree_path_new (void)
599{
600 CtkTreePath *retval;
601 retval = g_slice_new (CtkTreePath)((CtkTreePath*) g_slice_alloc (sizeof (CtkTreePath)));
602 retval->depth = 0;
603 retval->alloc = 0;
604 retval->indices = NULL((void*)0);
12
Null pointer value stored to field 'indices'
605
606 return retval;
607}
608
609/**
610 * ctk_tree_path_new_from_string:
611 * @path: The string representation of a path
612 *
613 * Creates a new #CtkTreePath-struct initialized to @path.
614 *
615 * @path is expected to be a colon separated list of numbers.
616 * For example, the string “10:4:0” would create a path of depth
617 * 3 pointing to the 11th child of the root node, the 5th
618 * child of that 11th child, and the 1st child of that 5th child.
619 * If an invalid path string is passed in, %NULL is returned.
620 *
621 * Returns: A newly-created #CtkTreePath-struct, or %NULL
622 */
623CtkTreePath *
624ctk_tree_path_new_from_string (const gchar *path)
625{
626 CtkTreePath *retval;
627 const gchar *orig_path = path;
628 gchar *ptr;
629 gint i;
630
631 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
632 g_return_val_if_fail (*path != '\000', NULL)do { if ((*path != '\000')) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "*path != '\\000'"); return
(((void*)0)); } } while (0)
;
633
634 retval = ctk_tree_path_new ();
635
636 while (1)
637 {
638 i = strtol (path, &ptr, 10);
639 if (i < 0)
640 {
641 g_warning (G_STRLOC"ctktreemodel.c" ":" "641" ": Negative numbers in path %s passed to ctk_tree_path_new_from_string", orig_path);
642 ctk_tree_path_free (retval);
643 return NULL((void*)0);
644 }
645
646 ctk_tree_path_append_index (retval, i);
647
648 if (*ptr == '\000')
649 break;
650 if (ptr == path || *ptr != ':')
651 {
652 g_warning (G_STRLOC"ctktreemodel.c" ":" "652" ": Invalid path %s passed to ctk_tree_path_new_from_string", orig_path);
653 ctk_tree_path_free (retval);
654 return NULL((void*)0);
655 }
656 path = ptr + 1;
657 }
658
659 return retval;
660}
661
662/**
663 * ctk_tree_path_new_from_indices:
664 * @first_index: first integer
665 * @...: list of integers terminated by -1
666 *
667 * Creates a new path with @first_index and @varargs as indices.
668 *
669 * Returns: A newly created #CtkTreePath-struct
670 *
671 * Since: 2.2
672 */
673CtkTreePath *
674ctk_tree_path_new_from_indices (gint first_index,
675 ...)
676{
677 int arg;
678 va_list args;
679 CtkTreePath *path;
680
681 path = ctk_tree_path_new ();
682
683 va_start (args, first_index)__builtin_va_start(args, first_index);
684 arg = first_index;
685
686 while (arg != -1)
687 {
688 ctk_tree_path_append_index (path, arg);
689 arg = va_arg (args, gint)__builtin_va_arg(args, gint);
690 }
691
692 va_end (args)__builtin_va_end(args);
693
694 return path;
695}
696
697/**
698 * ctk_tree_path_new_from_indicesv: (rename-to ctk_tree_path_new_from_indices)
699 * @indices: (array length=length): array of indices
700 * @length: length of @indices array
701 *
702 * Creates a new path with the given @indices array of @length.
703 *
704 * Returns: A newly created #CtkTreePath-struct
705 *
706 * Since: 3.12
707 */
708CtkTreePath *
709ctk_tree_path_new_from_indicesv (gint *indices,
710 gsize length)
711{
712 CtkTreePath *path;
713
714 g_return_val_if_fail (indices != NULL && length != 0, NULL)do { if ((indices != ((void*)0) && length != 0)) { } else
{ g_return_if_fail_warning ("Ctk", ((const char*) (__func__)
), "indices != NULL && length != 0"); return (((void*
)0)); } } while (0)
;
715
716 path = ctk_tree_path_new ();
717 path->alloc = length;
718 path->depth = length;
719 path->indices = g_new (gint, length)((gint *) g_malloc_n ((length), sizeof (gint)));
720 memcpy (path->indices, indices, length * sizeof (gint));
721
722 return path;
723}
724
725/**
726 * ctk_tree_path_to_string:
727 * @path: A #CtkTreePath-struct
728 *
729 * Generates a string representation of the path.
730 *
731 * This string is a “:” separated list of numbers.
732 * For example, “4:10:0:3” would be an acceptable
733 * return value for this string.
734 *
735 * Returns: A newly-allocated string.
736 * Must be freed with g_free().
737 */
738gchar *
739ctk_tree_path_to_string (CtkTreePath *path)
740{
741 gchar *retval, *ptr, *end;
742 gint i, n;
743
744 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
745
746 if (path->depth == 0)
747 return NULL((void*)0);
748
749 n = path->depth * 12;
750 ptr = retval = g_new0 (gchar, n)((gchar *) g_malloc0_n ((n), sizeof (gchar)));
751 end = ptr + n;
752 g_snprintf (retval, end - ptr, "%d", path->indices[0]);
753 while (*ptr != '\000')
754 ptr++;
755
756 for (i = 1; i < path->depth; i++)
757 {
758 g_snprintf (ptr, end - ptr, ":%d", path->indices[i]);
759 while (*ptr != '\000')
760 ptr++;
761 }
762
763 return retval;
764}
765
766/**
767 * ctk_tree_path_new_first:
768 *
769 * Creates a new #CtkTreePath-struct.
770 *
771 * The string representation of this path is “0”.
772 *
773 * Returns: A new #CtkTreePath-struct
774 */
775CtkTreePath *
776ctk_tree_path_new_first (void)
777{
778 CtkTreePath *retval;
779
780 retval = ctk_tree_path_new ();
11
Calling 'ctk_tree_path_new'
13
Returning from 'ctk_tree_path_new'
781 ctk_tree_path_append_index (retval, 0);
14
Calling 'ctk_tree_path_append_index'
782
783 return retval;
784}
785
786/**
787 * ctk_tree_path_append_index:
788 * @path: a #CtkTreePath-struct
789 * @index_: the index
790 *
791 * Appends a new index to a path.
792 *
793 * As a result, the depth of the path is increased.
794 */
795void
796ctk_tree_path_append_index (CtkTreePath *path,
797 gint index_)
798{
799 g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return;
} } while (0)
;
15
Taking true branch
16
Loop condition is false. Exiting loop
800 g_return_if_fail (index_ >= 0)do { if ((index_ >= 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "index_ >= 0"); return
; } } while (0)
;
17
Taking true branch
18
Loop condition is false. Exiting loop
801
802 if (path->depth
18.1
Field 'depth' is equal to field 'alloc'
== path->alloc)
19
Taking true branch
803 {
804 gint *indices;
805 path->alloc = MAX (path->alloc * 2, 1)(((path->alloc * 2) > (1)) ? (path->alloc * 2) : (1)
)
;
20
'?' condition is false
806 indices = g_new (gint, path->alloc)((gint *) g_malloc_n ((path->alloc), sizeof (gint)));
807 memcpy (indices, path->indices, path->depth * sizeof (gint));
21
Null pointer passed to 2nd parameter expecting 'nonnull'
808 g_free (path->indices);
809 path->indices = indices;
810 }
811
812 path->depth += 1;
813 path->indices[path->depth - 1] = index_;
814}
815
816/**
817 * ctk_tree_path_prepend_index:
818 * @path: a #CtkTreePath-struct
819 * @index_: the index
820 *
821 * Prepends a new index to a path.
822 *
823 * As a result, the depth of the path is increased.
824 */
825void
826ctk_tree_path_prepend_index (CtkTreePath *path,
827 gint index)
828{
829 if (path->depth == path->alloc)
830 {
831 gint *indices;
832 path->alloc = MAX (path->alloc * 2, 1)(((path->alloc * 2) > (1)) ? (path->alloc * 2) : (1)
)
;
833 indices = g_new (gint, path->alloc)((gint *) g_malloc_n ((path->alloc), sizeof (gint)));
834 memcpy (indices + 1, path->indices, path->depth * sizeof (gint));
835 g_free (path->indices);
836 path->indices = indices;
837 }
838 else if (path->depth > 0)
839 memmove (path->indices + 1, path->indices, path->depth * sizeof (gint));
840
841 path->depth += 1;
842 path->indices[0] = index;
843}
844
845/**
846 * ctk_tree_path_get_depth:
847 * @path: a #CtkTreePath-struct
848 *
849 * Returns the current depth of @path.
850 *
851 * Returns: The depth of @path
852 */
853gint
854ctk_tree_path_get_depth (CtkTreePath *path)
855{
856 g_return_val_if_fail (path != NULL, 0)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
0); } } while (0)
;
857
858 return path->depth;
859}
860
861/**
862 * ctk_tree_path_get_indices: (skip)
863 * @path: a #CtkTreePath-struct
864 *
865 * Returns the current indices of @path.
866 *
867 * This is an array of integers, each representing a node in a tree.
868 * This value should not be freed.
869 *
870 * The length of the array can be obtained with ctk_tree_path_get_depth().
871 *
872 * Returns: The current indices, or %NULL
873 */
874gint *
875ctk_tree_path_get_indices (CtkTreePath *path)
876{
877 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
878
879 return path->indices;
880}
881
882/**
883 * ctk_tree_path_get_indices_with_depth: (rename-to ctk_tree_path_get_indices)
884 * @path: a #CtkTreePath-struct
885 * @depth: (out) (allow-none): return location for number of elements
886 * returned in the integer array, or %NULL
887 *
888 * Returns the current indices of @path.
889 *
890 * This is an array of integers, each representing a node in a tree.
891 * It also returns the number of elements in the array.
892 * The array should not be freed.
893 *
894 * Returns: (array length=depth) (transfer none): The current
895 * indices, or %NULL
896 *
897 * Since: 3.0
898 */
899gint *
900ctk_tree_path_get_indices_with_depth (CtkTreePath *path,
901 gint *depth)
902{
903 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
904
905 if (depth)
906 *depth = path->depth;
907
908 return path->indices;
909}
910
911/**
912 * ctk_tree_path_free:
913 * @path: (allow-none): a #CtkTreePath-struct
914 *
915 * Frees @path. If @path is %NULL, it simply returns.
916 */
917void
918ctk_tree_path_free (CtkTreePath *path)
919{
920 if (!path)
921 return;
922
923 g_free (path->indices);
924 g_slice_free (CtkTreePath, path)do { if (1) g_slice_free1 (sizeof (CtkTreePath), (path)); else
(void) ((CtkTreePath*) 0 == (path)); } while (0)
;
925}
926
927/**
928 * ctk_tree_path_copy:
929 * @path: a #CtkTreePath-struct
930 *
931 * Creates a new #CtkTreePath-struct as a copy of @path.
932 *
933 * Returns: a new #CtkTreePath-struct
934 */
935CtkTreePath *
936ctk_tree_path_copy (const CtkTreePath *path)
937{
938 CtkTreePath *retval;
939
940 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
941
942 retval = g_slice_new (CtkTreePath)((CtkTreePath*) g_slice_alloc (sizeof (CtkTreePath)));
943 retval->depth = path->depth;
944 retval->alloc = retval->depth;
945 retval->indices = g_new (gint, path->alloc)((gint *) g_malloc_n ((path->alloc), sizeof (gint)));
946 memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
947 return retval;
948}
949
950G_DEFINE_BOXED_TYPE (CtkTreePath, ctk_tree_path,static GType ctk_tree_path_get_type_once (void); GType ctk_tree_path_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_path_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_tree_path_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkTreePath
* (*do_copy_type) (CtkTreePath *); CtkTreePath * (*do_const_copy_type
) (const CtkTreePath *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkTreePath
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkTreePath"), ctk_tree_path_copy
, ctk_tree_path_free); { {{};} } return g_define_type_id; }
951 ctk_tree_path_copy,static GType ctk_tree_path_get_type_once (void); GType ctk_tree_path_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_path_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_tree_path_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkTreePath
* (*do_copy_type) (CtkTreePath *); CtkTreePath * (*do_const_copy_type
) (const CtkTreePath *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkTreePath
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkTreePath"), ctk_tree_path_copy
, ctk_tree_path_free); { {{};} } return g_define_type_id; }
952 ctk_tree_path_free)static GType ctk_tree_path_get_type_once (void); GType ctk_tree_path_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_path_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_tree_path_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkTreePath
* (*do_copy_type) (CtkTreePath *); CtkTreePath * (*do_const_copy_type
) (const CtkTreePath *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkTreePath
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkTreePath"), ctk_tree_path_copy
, ctk_tree_path_free); { {{};} } return g_define_type_id; }
953
954/**
955 * ctk_tree_path_compare:
956 * @a: a #CtkTreePath-struct
957 * @b: a #CtkTreePath-struct to compare with
958 *
959 * Compares two paths.
960 *
961 * If @a appears before @b in a tree, then -1 is returned.
962 * If @b appears before @a, then 1 is returned.
963 * If the two nodes are equal, then 0 is returned.
964 *
965 * Returns: the relative positions of @a and @b
966 */
967gint
968ctk_tree_path_compare (const CtkTreePath *a,
969 const CtkTreePath *b)
970{
971 gint p = 0, q = 0;
972
973 g_return_val_if_fail (a != NULL, 0)do { if ((a != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "a != NULL"); return (0)
; } } while (0)
;
974 g_return_val_if_fail (b != NULL, 0)do { if ((b != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "b != NULL"); return (0)
; } } while (0)
;
975 g_return_val_if_fail (a->depth > 0, 0)do { if ((a->depth > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "a->depth > 0"); return
(0); } } while (0)
;
976 g_return_val_if_fail (b->depth > 0, 0)do { if ((b->depth > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "b->depth > 0"); return
(0); } } while (0)
;
977
978 do
979 {
980 if (a->indices[p] == b->indices[q])
981 continue;
982 return (a->indices[p] < b->indices[q]?-1:1);
983 }
984 while (++p < a->depth && ++q < b->depth);
985 if (a->depth == b->depth)
986 return 0;
987 return (a->depth < b->depth?-1:1);
988}
989
990/**
991 * ctk_tree_path_is_ancestor:
992 * @path: a #CtkTreePath-struct
993 * @descendant: another #CtkTreePath-struct
994 *
995 * Returns %TRUE if @descendant is a descendant of @path.
996 *
997 * Returns: %TRUE if @descendant is contained inside @path
998 */
999gboolean
1000ctk_tree_path_is_ancestor (CtkTreePath *path,
1001 CtkTreePath *descendant)
1002{
1003 gint i;
1004
1005 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
(0)); } } while (0)
;
1006 g_return_val_if_fail (descendant != NULL, FALSE)do { if ((descendant != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "descendant != NULL"); return
((0)); } } while (0)
;
1007
1008 /* can't be an ancestor if we're deeper */
1009 if (path->depth >= descendant->depth)
1010 return FALSE(0);
1011
1012 i = 0;
1013 while (i < path->depth)
1014 {
1015 if (path->indices[i] != descendant->indices[i])
1016 return FALSE(0);
1017 ++i;
1018 }
1019
1020 return TRUE(!(0));
1021}
1022
1023/**
1024 * ctk_tree_path_is_descendant:
1025 * @path: a #CtkTreePath-struct
1026 * @ancestor: another #CtkTreePath-struct
1027 *
1028 * Returns %TRUE if @path is a descendant of @ancestor.
1029 *
1030 * Returns: %TRUE if @ancestor contains @path somewhere below it
1031 */
1032gboolean
1033ctk_tree_path_is_descendant (CtkTreePath *path,
1034 CtkTreePath *ancestor)
1035{
1036 gint i;
1037
1038 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
(0)); } } while (0)
;
1039 g_return_val_if_fail (ancestor != NULL, FALSE)do { if ((ancestor != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "ancestor != NULL"); return
((0)); } } while (0)
;
1040
1041 /* can't be a descendant if we're shallower in the tree */
1042 if (path->depth <= ancestor->depth)
1043 return FALSE(0);
1044
1045 i = 0;
1046 while (i < ancestor->depth)
1047 {
1048 if (path->indices[i] != ancestor->indices[i])
1049 return FALSE(0);
1050 ++i;
1051 }
1052
1053 return TRUE(!(0));
1054}
1055
1056
1057/**
1058 * ctk_tree_path_next:
1059 * @path: a #CtkTreePath-struct
1060 *
1061 * Moves the @path to point to the next node at the current depth.
1062 */
1063void
1064ctk_tree_path_next (CtkTreePath *path)
1065{
1066 g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return;
} } while (0)
;
1067 g_return_if_fail (path->depth > 0)do { if ((path->depth > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path->depth > 0")
; return; } } while (0)
;
1068
1069 path->indices[path->depth - 1] ++;
1070}
1071
1072/**
1073 * ctk_tree_path_prev:
1074 * @path: a #CtkTreePath-struct
1075 *
1076 * Moves the @path to point to the previous node at the
1077 * current depth, if it exists.
1078 *
1079 * Returns: %TRUE if @path has a previous node, and
1080 * the move was made
1081 */
1082gboolean
1083ctk_tree_path_prev (CtkTreePath *path)
1084{
1085 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
(0)); } } while (0)
;
1086
1087 if (path->depth == 0)
1088 return FALSE(0);
1089
1090 if (path->indices[path->depth - 1] == 0)
1091 return FALSE(0);
1092
1093 path->indices[path->depth - 1] -= 1;
1094
1095 return TRUE(!(0));
1096}
1097
1098/**
1099 * ctk_tree_path_up:
1100 * @path: a #CtkTreePath-struct
1101 *
1102 * Moves the @path to point to its parent node, if it has a parent.
1103 *
1104 * Returns: %TRUE if @path has a parent, and the move was made
1105 */
1106gboolean
1107ctk_tree_path_up (CtkTreePath *path)
1108{
1109 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
(0)); } } while (0)
;
1110
1111 if (path->depth == 0)
1112 return FALSE(0);
1113
1114 path->depth--;
1115
1116 return TRUE(!(0));
1117}
1118
1119/**
1120 * ctk_tree_path_down:
1121 * @path: a #CtkTreePath-struct
1122 *
1123 * Moves @path to point to the first child of the current path.
1124 */
1125void
1126ctk_tree_path_down (CtkTreePath *path)
1127{
1128 g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return;
} } while (0)
;
1129
1130 ctk_tree_path_append_index (path, 0);
1131}
1132
1133/**
1134 * ctk_tree_iter_copy:
1135 * @iter: a #CtkTreeIter-struct
1136 *
1137 * Creates a dynamically allocated tree iterator as a copy of @iter.
1138 *
1139 * This function is not intended for use in applications,
1140 * because you can just copy the structs by value
1141 * (`CtkTreeIter new_iter = iter;`).
1142 * You must free this iter with ctk_tree_iter_free().
1143 *
1144 * Returns: a newly-allocated copy of @iter
1145 */
1146CtkTreeIter *
1147ctk_tree_iter_copy (CtkTreeIter *iter)
1148{
1149 CtkTreeIter *retval;
1150
1151 g_return_val_if_fail (iter != NULL, NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
((void*)0)); } } while (0)
;
1152
1153 retval = g_slice_new (CtkTreeIter)((CtkTreeIter*) g_slice_alloc (sizeof (CtkTreeIter)));
1154 *retval = *iter;
1155
1156 return retval;
1157}
1158
1159/**
1160 * ctk_tree_iter_free:
1161 * @iter: a dynamically allocated tree iterator
1162 *
1163 * Frees an iterator that has been allocated by ctk_tree_iter_copy().
1164 *
1165 * This function is mainly used for language bindings.
1166 */
1167void
1168ctk_tree_iter_free (CtkTreeIter *iter)
1169{
1170 g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return;
} } while (0)
;
1171
1172 g_slice_free (CtkTreeIter, iter)do { if (1) g_slice_free1 (sizeof (CtkTreeIter), (iter)); else
(void) ((CtkTreeIter*) 0 == (iter)); } while (0)
;
1173}
1174
1175G_DEFINE_BOXED_TYPE (CtkTreeIter, ctk_tree_iter,static GType ctk_tree_iter_get_type_once (void); GType ctk_tree_iter_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_iter_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_tree_iter_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkTreeIter
* (*do_copy_type) (CtkTreeIter *); CtkTreeIter * (*do_const_copy_type
) (const CtkTreeIter *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkTreeIter
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkTreeIter"), ctk_tree_iter_copy
, ctk_tree_iter_free); { {{};} } return g_define_type_id; }
1176 ctk_tree_iter_copy,static GType ctk_tree_iter_get_type_once (void); GType ctk_tree_iter_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_iter_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_tree_iter_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkTreeIter
* (*do_copy_type) (CtkTreeIter *); CtkTreeIter * (*do_const_copy_type
) (const CtkTreeIter *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkTreeIter
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkTreeIter"), ctk_tree_iter_copy
, ctk_tree_iter_free); { {{};} } return g_define_type_id; }
1177 ctk_tree_iter_free)static GType ctk_tree_iter_get_type_once (void); GType ctk_tree_iter_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_iter_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType ctk_tree_iter_get_type_once (void
) { GType (* _g_register_boxed) (const gchar *, union { CtkTreeIter
* (*do_copy_type) (CtkTreeIter *); CtkTreeIter * (*do_const_copy_type
) (const CtkTreeIter *); GBoxedCopyFunc do_copy_boxed; } __attribute__
((__transparent_union__)), union { void (* do_free_type) (CtkTreeIter
*); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__
)) ) = g_boxed_type_register_static; GType g_define_type_id =
_g_register_boxed (g_intern_static_string ("CtkTreeIter"), ctk_tree_iter_copy
, ctk_tree_iter_free); { {{};} } return g_define_type_id; }
1178
1179/**
1180 * ctk_tree_model_get_flags:
1181 * @tree_model: a #CtkTreeModel
1182 *
1183 * Returns a set of flags supported by this interface.
1184 *
1185 * The flags are a bitwise combination of #CtkTreeModelFlags.
1186 * The flags supported should not change during the lifetime
1187 * of the @tree_model.
1188 *
1189 * Returns: the flags supported by this interface
1190 */
1191CtkTreeModelFlags
1192ctk_tree_model_get_flags (CtkTreeModel *tree_model)
1193{
1194 CtkTreeModelIface *iface;
1195
1196 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return (0)
; } } while (0)
;
1197
1198 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1199 if (iface->get_flags)
1200 return (* iface->get_flags) (tree_model);
1201
1202 return 0;
1203}
1204
1205/**
1206 * ctk_tree_model_get_n_columns:
1207 * @tree_model: a #CtkTreeModel
1208 *
1209 * Returns the number of columns supported by @tree_model.
1210 *
1211 * Returns: the number of columns
1212 */
1213gint
1214ctk_tree_model_get_n_columns (CtkTreeModel *tree_model)
1215{
1216 CtkTreeModelIface *iface;
1217 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return (0)
; } } while (0)
;
1218
1219 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1220 g_return_val_if_fail (iface->get_n_columns != NULL, 0)do { if ((iface->get_n_columns != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iface->get_n_columns != NULL"
); return (0); } } while (0)
;
1221
1222 return (* iface->get_n_columns) (tree_model);
1223}
1224
1225/**
1226 * ctk_tree_model_get_column_type:
1227 * @tree_model: a #CtkTreeModel
1228 * @index_: the column index
1229 *
1230 * Returns the type of the column.
1231 *
1232 * Returns: the type of the column
1233 */
1234GType
1235ctk_tree_model_get_column_type (CtkTreeModel *tree_model,
1236 gint index)
1237{
1238 CtkTreeModelIface *iface;
1239
1240 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return (((
GType) ((0) << (2)))); } } while (0)
;
1241
1242 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1243 g_return_val_if_fail (iface->get_column_type != NULL, G_TYPE_INVALID)do { if ((iface->get_column_type != ((void*)0))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"iface->get_column_type != NULL"); return (((GType) ((0) <<
(2)))); } } while (0)
;
1244 g_return_val_if_fail (index >= 0, G_TYPE_INVALID)do { if ((index >= 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "index >= 0"); return
(((GType) ((0) << (2)))); } } while (0)
;
1245
1246 return (* iface->get_column_type) (tree_model, index);
1247}
1248
1249/**
1250 * ctk_tree_model_get_iter:
1251 * @tree_model: a #CtkTreeModel
1252 * @iter: (out): the uninitialized #CtkTreeIter-struct
1253 * @path: the #CtkTreePath-struct
1254 *
1255 * Sets @iter to a valid iterator pointing to @path. If @path does
1256 * not exist, @iter is set to an invalid iterator and %FALSE is returned.
1257 *
1258 * Returns: %TRUE, if @iter was set
1259 */
1260gboolean
1261ctk_tree_model_get_iter (CtkTreeModel *tree_model,
1262 CtkTreeIter *iter,
1263 CtkTreePath *path)
1264{
1265 CtkTreeModelIface *iface;
1266
1267 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1268 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1269 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
(0)); } } while (0)
;
1270
1271 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1272 g_return_val_if_fail (iface->get_iter != NULL, FALSE)do { if ((iface->get_iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iface->get_iter != NULL"
); return ((0)); } } while (0)
;
1273 g_return_val_if_fail (path->depth > 0, FALSE)do { if ((path->depth > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path->depth > 0")
; return ((0)); } } while (0)
;
1274
1275 INITIALIZE_TREE_ITER (iter)do{ (iter)->stamp = 0; (iter)->user_data = ((void*)0); (
iter)->user_data2 = ((void*)0); (iter)->user_data3 = ((
void*)0); }while (0)
;
1276
1277 return (* iface->get_iter) (tree_model, iter, path);
1278}
1279
1280/**
1281 * ctk_tree_model_get_iter_from_string:
1282 * @tree_model: a #CtkTreeModel
1283 * @iter: (out): an uninitialized #CtkTreeIter-struct
1284 * @path_string: a string representation of a #CtkTreePath-struct
1285 *
1286 * Sets @iter to a valid iterator pointing to @path_string, if it
1287 * exists. Otherwise, @iter is left invalid and %FALSE is returned.
1288 *
1289 * Returns: %TRUE, if @iter was set
1290 */
1291gboolean
1292ctk_tree_model_get_iter_from_string (CtkTreeModel *tree_model,
1293 CtkTreeIter *iter,
1294 const gchar *path_string)
1295{
1296 gboolean retval;
1297 CtkTreePath *path;
1298
1299 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1300 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1301 g_return_val_if_fail (path_string != NULL, FALSE)do { if ((path_string != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path_string != NULL"); return
((0)); } } while (0)
;
1302
1303 path = ctk_tree_path_new_from_string (path_string);
1304
1305 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
(0)); } } while (0)
;
1306
1307 retval = ctk_tree_model_get_iter (tree_model, iter, path);
1308 ctk_tree_path_free (path);
1309
1310 return retval;
1311}
1312
1313/**
1314 * ctk_tree_model_get_string_from_iter:
1315 * @tree_model: a #CtkTreeModel
1316 * @iter: a #CtkTreeIter-struct
1317 *
1318 * Generates a string representation of the iter.
1319 *
1320 * This string is a “:” separated list of numbers.
1321 * For example, “4:10:0:3” would be an acceptable
1322 * return value for this string.
1323 *
1324 * Returns: a newly-allocated string.
1325 * Must be freed with g_free().
1326 *
1327 * Since: 2.2
1328 */
1329gchar *
1330ctk_tree_model_get_string_from_iter (CtkTreeModel *tree_model,
1331 CtkTreeIter *iter)
1332{
1333 CtkTreePath *path;
1334 gchar *ret;
1335
1336 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return (((
void*)0)); } } while (0)
;
1337 g_return_val_if_fail (iter != NULL, NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
((void*)0)); } } while (0)
;
1338
1339 path = ctk_tree_model_get_path (tree_model, iter);
1340
1341 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
1342
1343 ret = ctk_tree_path_to_string (path);
1344 ctk_tree_path_free (path);
1345
1346 return ret;
1347}
1348
1349/**
1350 * ctk_tree_model_get_iter_first:
1351 * @tree_model: a #CtkTreeModel
1352 * @iter: (out): the uninitialized #CtkTreeIter-struct
1353 *
1354 * Initializes @iter with the first iterator in the tree
1355 * (the one at the path "0") and returns %TRUE. Returns
1356 * %FALSE if the tree is empty.
1357 *
1358 * Returns: %TRUE, if @iter was set
1359 */
1360gboolean
1361ctk_tree_model_get_iter_first (CtkTreeModel *tree_model,
1362 CtkTreeIter *iter)
1363{
1364 CtkTreePath *path;
1365 gboolean retval;
1366
1367 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1368 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1369
1370 path = ctk_tree_path_new_first ();
1371 retval = ctk_tree_model_get_iter (tree_model, iter, path);
1372 ctk_tree_path_free (path);
1373
1374 return retval;
1375}
1376
1377/**
1378 * ctk_tree_model_get_path:
1379 * @tree_model: a #CtkTreeModel
1380 * @iter: the #CtkTreeIter-struct
1381 *
1382 * Returns a newly-created #CtkTreePath-struct referenced by @iter.
1383 *
1384 * This path should be freed with ctk_tree_path_free().
1385 *
1386 * Returns: a newly-created #CtkTreePath-struct
1387 */
1388CtkTreePath *
1389ctk_tree_model_get_path (CtkTreeModel *tree_model,
1390 CtkTreeIter *iter)
1391{
1392 CtkTreeModelIface *iface;
1393
1394 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return (((
void*)0)); } } while (0)
;
1395 g_return_val_if_fail (iter != NULL, NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
((void*)0)); } } while (0)
;
1396
1397 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1398 g_return_val_if_fail (iface->get_path != NULL, NULL)do { if ((iface->get_path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iface->get_path != NULL"
); return (((void*)0)); } } while (0)
;
1399
1400 return (* iface->get_path) (tree_model, iter);
1401}
1402
1403/**
1404 * ctk_tree_model_get_value:
1405 * @tree_model: a #CtkTreeModel
1406 * @iter: the #CtkTreeIter-struct
1407 * @column: the column to lookup the value at
1408 * @value: (out) (transfer none): an empty #GValue to set
1409 *
1410 * Initializes and sets @value to that at @column.
1411 *
1412 * When done with @value, g_value_unset() needs to be called
1413 * to free any allocated memory.
1414 */
1415void
1416ctk_tree_model_get_value (CtkTreeModel *tree_model,
1417 CtkTreeIter *iter,
1418 gint column,
1419 GValue *value)
1420{
1421 CtkTreeModelIface *iface;
1422
1423 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1424 g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return;
} } while (0)
;
1425 g_return_if_fail (value != NULL)do { if ((value != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "value != NULL"); return
; } } while (0)
;
1426
1427 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1428 g_return_if_fail (iface->get_value != NULL)do { if ((iface->get_value != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iface->get_value != NULL"
); return; } } while (0)
;
1429
1430 (* iface->get_value) (tree_model, iter, column, value);
1431}
1432
1433/**
1434 * ctk_tree_model_iter_next:
1435 * @tree_model: a #CtkTreeModel
1436 * @iter: (in): the #CtkTreeIter-struct
1437 *
1438 * Sets @iter to point to the node following it at the current level.
1439 *
1440 * If there is no next @iter, %FALSE is returned and @iter is set
1441 * to be invalid.
1442 *
1443 * Returns: %TRUE if @iter has been changed to the next node
1444 */
1445gboolean
1446ctk_tree_model_iter_next (CtkTreeModel *tree_model,
1447 CtkTreeIter *iter)
1448{
1449 CtkTreeModelIface *iface;
1450
1451 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1452 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1453
1454 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1455 g_return_val_if_fail (iface->iter_next != NULL, FALSE)do { if ((iface->iter_next != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iface->iter_next != NULL"
); return ((0)); } } while (0)
;
1456
1457 return (* iface->iter_next) (tree_model, iter);
1458}
1459
1460static gboolean
1461ctk_tree_model_iter_previous_default (CtkTreeModel *tree_model,
1462 CtkTreeIter *iter)
1463{
1464 gboolean retval;
1465 CtkTreePath *path;
1466
1467 path = ctk_tree_model_get_path (tree_model, iter);
1468 if (path == NULL((void*)0))
1469 return FALSE(0);
1470
1471 retval = ctk_tree_path_prev (path) &&
1472 ctk_tree_model_get_iter (tree_model, iter, path);
1473 if (retval == FALSE(0))
1474 iter->stamp = 0;
1475
1476 ctk_tree_path_free (path);
1477
1478 return retval;
1479}
1480
1481/**
1482 * ctk_tree_model_iter_previous:
1483 * @tree_model: a #CtkTreeModel
1484 * @iter: (in): the #CtkTreeIter-struct
1485 *
1486 * Sets @iter to point to the previous node at the current level.
1487 *
1488 * If there is no previous @iter, %FALSE is returned and @iter is
1489 * set to be invalid.
1490 *
1491 * Returns: %TRUE if @iter has been changed to the previous node
1492 *
1493 * Since: 3.0
1494 */
1495gboolean
1496ctk_tree_model_iter_previous (CtkTreeModel *tree_model,
1497 CtkTreeIter *iter)
1498{
1499 gboolean retval;
1500 CtkTreeModelIface *iface;
1501
1502 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1503 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1504
1505 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1506
1507 if (iface->iter_previous)
1508 retval = (* iface->iter_previous) (tree_model, iter);
1509 else
1510 retval = ctk_tree_model_iter_previous_default (tree_model, iter);
1511
1512 return retval;
1513}
1514
1515/**
1516 * ctk_tree_model_iter_children:
1517 * @tree_model: a #CtkTreeModel
1518 * @iter: (out): the new #CtkTreeIter-struct to be set to the child
1519 * @parent: (allow-none): the #CtkTreeIter-struct, or %NULL
1520 *
1521 * Sets @iter to point to the first child of @parent.
1522 *
1523 * If @parent has no children, %FALSE is returned and @iter is
1524 * set to be invalid. @parent will remain a valid node after this
1525 * function has been called.
1526 *
1527 * If @parent is %NULL returns the first node, equivalent to
1528 * `ctk_tree_model_get_iter_first (tree_model, iter);`
1529 *
1530 * Returns: %TRUE, if @iter has been set to the first child
1531 */
1532gboolean
1533ctk_tree_model_iter_children (CtkTreeModel *tree_model,
1534 CtkTreeIter *iter,
1535 CtkTreeIter *parent)
1536{
1537 CtkTreeModelIface *iface;
1538
1539 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1540 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1541
1542 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1543 g_return_val_if_fail (iface->iter_children != NULL, FALSE)do { if ((iface->iter_children != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iface->iter_children != NULL"
); return ((0)); } } while (0)
;
1544
1545 INITIALIZE_TREE_ITER (iter)do{ (iter)->stamp = 0; (iter)->user_data = ((void*)0); (
iter)->user_data2 = ((void*)0); (iter)->user_data3 = ((
void*)0); }while (0)
;
1546
1547 return (* iface->iter_children) (tree_model, iter, parent);
1548}
1549
1550/**
1551 * ctk_tree_model_iter_has_child:
1552 * @tree_model: a #CtkTreeModel
1553 * @iter: the #CtkTreeIter-struct to test for children
1554 *
1555 * Returns %TRUE if @iter has children, %FALSE otherwise.
1556 *
1557 * Returns: %TRUE if @iter has children
1558 */
1559gboolean
1560ctk_tree_model_iter_has_child (CtkTreeModel *tree_model,
1561 CtkTreeIter *iter)
1562{
1563 CtkTreeModelIface *iface;
1564
1565 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1566 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1567
1568 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1569 g_return_val_if_fail (iface->iter_has_child != NULL, FALSE)do { if ((iface->iter_has_child != ((void*)0))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"iface->iter_has_child != NULL"); return ((0)); } } while
(0)
;
1570
1571 return (* iface->iter_has_child) (tree_model, iter);
1572}
1573
1574/**
1575 * ctk_tree_model_iter_n_children:
1576 * @tree_model: a #CtkTreeModel
1577 * @iter: (allow-none): the #CtkTreeIter-struct, or %NULL
1578 *
1579 * Returns the number of children that @iter has.
1580 *
1581 * As a special case, if @iter is %NULL, then the number
1582 * of toplevel nodes is returned.
1583 *
1584 * Returns: the number of children of @iter
1585 */
1586gint
1587ctk_tree_model_iter_n_children (CtkTreeModel *tree_model,
1588 CtkTreeIter *iter)
1589{
1590 CtkTreeModelIface *iface;
1591
1592 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return (0)
; } } while (0)
;
1593
1594 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1595 g_return_val_if_fail (iface->iter_n_children != NULL, 0)do { if ((iface->iter_n_children != ((void*)0))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"iface->iter_n_children != NULL"); return (0); } } while (
0)
;
1596
1597 return (* iface->iter_n_children) (tree_model, iter);
1598}
1599
1600/**
1601 * ctk_tree_model_iter_nth_child:
1602 * @tree_model: a #CtkTreeModel
1603 * @iter: (out): the #CtkTreeIter-struct to set to the nth child
1604 * @parent: (allow-none): the #CtkTreeIter-struct to get the child from, or %NULL.
1605 * @n: the index of the desired child
1606 *
1607 * Sets @iter to be the child of @parent, using the given index.
1608 *
1609 * The first index is 0. If @n is too big, or @parent has no children,
1610 * @iter is set to an invalid iterator and %FALSE is returned. @parent
1611 * will remain a valid node after this function has been called. As a
1612 * special case, if @parent is %NULL, then the @n-th root node
1613 * is set.
1614 *
1615 * Returns: %TRUE, if @parent has an @n-th child
1616 */
1617gboolean
1618ctk_tree_model_iter_nth_child (CtkTreeModel *tree_model,
1619 CtkTreeIter *iter,
1620 CtkTreeIter *parent,
1621 gint n)
1622{
1623 CtkTreeModelIface *iface;
1624
1625 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1626 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1627 g_return_val_if_fail (n >= 0, FALSE)do { if ((n >= 0)) { } else { g_return_if_fail_warning ("Ctk"
, ((const char*) (__func__)), "n >= 0"); return ((0)); } }
while (0)
;
1628
1629 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1630 g_return_val_if_fail (iface->iter_nth_child != NULL, FALSE)do { if ((iface->iter_nth_child != ((void*)0))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"iface->iter_nth_child != NULL"); return ((0)); } } while
(0)
;
1631
1632 INITIALIZE_TREE_ITER (iter)do{ (iter)->stamp = 0; (iter)->user_data = ((void*)0); (
iter)->user_data2 = ((void*)0); (iter)->user_data3 = ((
void*)0); }while (0)
;
1633
1634 return (* iface->iter_nth_child) (tree_model, iter, parent, n);
1635}
1636
1637/**
1638 * ctk_tree_model_iter_parent:
1639 * @tree_model: a #CtkTreeModel
1640 * @iter: (out): the new #CtkTreeIter-struct to set to the parent
1641 * @child: the #CtkTreeIter-struct
1642 *
1643 * Sets @iter to be the parent of @child.
1644 *
1645 * If @child is at the toplevel, and doesn’t have a parent, then
1646 * @iter is set to an invalid iterator and %FALSE is returned.
1647 * @child will remain a valid node after this function has been
1648 * called.
1649 *
1650 * @iter will be initialized before the lookup is performed, so @child
1651 * and @iter cannot point to the same memory location.
1652 *
1653 * Returns: %TRUE, if @iter is set to the parent of @child
1654 */
1655gboolean
1656ctk_tree_model_iter_parent (CtkTreeModel *tree_model,
1657 CtkTreeIter *iter,
1658 CtkTreeIter *child)
1659{
1660 CtkTreeModelIface *iface;
1661
1662 g_return_val_if_fail (CTK_IS_TREE_MODEL (tree_model), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return ((0
)); } } while (0)
;
1663 g_return_val_if_fail (iter != NULL, FALSE)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return (
(0)); } } while (0)
;
1664 g_return_val_if_fail (child != NULL, FALSE)do { if ((child != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "child != NULL"); return
((0)); } } while (0)
;
1665
1666 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1667 g_return_val_if_fail (iface->iter_parent != NULL, FALSE)do { if ((iface->iter_parent != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iface->iter_parent != NULL"
); return ((0)); } } while (0)
;
1668
1669 INITIALIZE_TREE_ITER (iter)do{ (iter)->stamp = 0; (iter)->user_data = ((void*)0); (
iter)->user_data2 = ((void*)0); (iter)->user_data3 = ((
void*)0); }while (0)
;
1670
1671 return (* iface->iter_parent) (tree_model, iter, child);
1672}
1673
1674/**
1675 * ctk_tree_model_ref_node:
1676 * @tree_model: a #CtkTreeModel
1677 * @iter: the #CtkTreeIter-struct
1678 *
1679 * Lets the tree ref the node.
1680 *
1681 * This is an optional method for models to implement.
1682 * To be more specific, models may ignore this call as it exists
1683 * primarily for performance reasons.
1684 *
1685 * This function is primarily meant as a way for views to let
1686 * caching models know when nodes are being displayed (and hence,
1687 * whether or not to cache that node). Being displayed means a node
1688 * is in an expanded branch, regardless of whether the node is currently
1689 * visible in the viewport. For example, a file-system based model
1690 * would not want to keep the entire file-hierarchy in memory,
1691 * just the sections that are currently being displayed by
1692 * every current view.
1693 *
1694 * A model should be expected to be able to get an iter independent
1695 * of its reffed state.
1696 */
1697void
1698ctk_tree_model_ref_node (CtkTreeModel *tree_model,
1699 CtkTreeIter *iter)
1700{
1701 CtkTreeModelIface *iface;
1702
1703 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1704
1705 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1706 if (iface->ref_node)
1707 (* iface->ref_node) (tree_model, iter);
1708}
1709
1710/**
1711 * ctk_tree_model_unref_node:
1712 * @tree_model: a #CtkTreeModel
1713 * @iter: the #CtkTreeIter-struct
1714 *
1715 * Lets the tree unref the node.
1716 *
1717 * This is an optional method for models to implement.
1718 * To be more specific, models may ignore this call as it exists
1719 * primarily for performance reasons. For more information on what
1720 * this means, see ctk_tree_model_ref_node().
1721 *
1722 * Please note that nodes that are deleted are not unreffed.
1723 */
1724void
1725ctk_tree_model_unref_node (CtkTreeModel *tree_model,
1726 CtkTreeIter *iter)
1727{
1728 CtkTreeModelIface *iface;
1729
1730 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1731 g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return;
} } while (0)
;
1732
1733 iface = CTK_TREE_MODEL_GET_IFACE (tree_model)((((CtkTreeModelIface*) g_type_interface_peek (((GTypeInstance
*) ((tree_model)))->g_class, ((ctk_tree_model_get_type ())
)))))
;
1734 if (iface->unref_node)
1735 (* iface->unref_node) (tree_model, iter);
1736}
1737
1738/**
1739 * ctk_tree_model_get:
1740 * @tree_model: a #CtkTreeModel
1741 * @iter: a row in @tree_model
1742 * @...: pairs of column number and value return locations,
1743 * terminated by -1
1744 *
1745 * Gets the value of one or more cells in the row referenced by @iter.
1746 * The variable argument list should contain integer column numbers,
1747 * each column number followed by a place to store the value being
1748 * retrieved. The list is terminated by a -1. For example, to get a
1749 * value from column 0 with type %G_TYPE_STRING, you would
1750 * write: `ctk_tree_model_get (model, iter, 0, &place_string_here, -1)`,
1751 * where `place_string_here` is a #gchararray
1752 * to be filled with the string.
1753 *
1754 * Returned values with type %G_TYPE_OBJECT have to be unreferenced,
1755 * values with type %G_TYPE_STRING or %G_TYPE_BOXED have to be freed.
1756 * Other values are passed by value.
1757 */
1758void
1759ctk_tree_model_get (CtkTreeModel *tree_model,
1760 CtkTreeIter *iter,
1761 ...)
1762{
1763 va_list var_args;
1764
1765 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1766 g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return;
} } while (0)
;
1767
1768 va_start (var_args, iter)__builtin_va_start(var_args, iter);
1769 ctk_tree_model_get_valist (tree_model, iter, var_args);
1770 va_end (var_args)__builtin_va_end(var_args);
1771}
1772
1773/**
1774 * ctk_tree_model_get_valist:
1775 * @tree_model: a #CtkTreeModel
1776 * @iter: a row in @tree_model
1777 * @var_args: va_list of column/return location pairs
1778 *
1779 * See ctk_tree_model_get(), this version takes a va_list
1780 * for language bindings to use.
1781 */
1782void
1783ctk_tree_model_get_valist (CtkTreeModel *tree_model,
1784 CtkTreeIter *iter,
1785 va_list var_args)
1786{
1787 gint column;
1788
1789 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1790 g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return;
} } while (0)
;
1791
1792 column = va_arg (var_args, gint)__builtin_va_arg(var_args, gint);
1793
1794 while (column != -1)
1795 {
1796 GValue value = G_VALUE_INIT{ 0, { { 0 } } };
1797 gchar *error = NULL((void*)0);
1798
1799 if (column >= ctk_tree_model_get_n_columns (tree_model))
1800 {
1801 g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC"ctktreemodel.c" ":" "1801", column);
1802 break;
1803 }
1804
1805 ctk_tree_model_get_value (CTK_TREE_MODEL (tree_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tree_model)), ((ctk_tree_model_get_type ()))))))
, iter, column, &value);
1806
1807 G_VALUE_LCOPY (&value, var_args, 0, &error)do { const GValue *g_vl_value = (&value); guint g_vl_flags
= (0); GType g_vl_value_type = (((GValue*) (g_vl_value))->
g_type); GTypeValueTable *g_vl_vtable = g_type_value_table_peek
(g_vl_value_type); const gchar *g_vl_lcopy_format = g_vl_vtable
->lcopy_format; GTypeCValue g_vl_cvalues[(8)] = { { 0, }, }
; guint g_vl_n_values = 0; while (*g_vl_lcopy_format) { GTypeCValue
*g_vl_cvalue = g_vl_cvalues + g_vl_n_values++; switch (*g_vl_lcopy_format
++) { case G_VALUE_COLLECT_INT: g_vl_cvalue->v_int = __builtin_va_arg
((var_args), gint); break; case G_VALUE_COLLECT_LONG: g_vl_cvalue
->v_long = __builtin_va_arg((var_args), glong); break; case
G_VALUE_COLLECT_INT64: g_vl_cvalue->v_int64 = __builtin_va_arg
((var_args), gint64); break; case G_VALUE_COLLECT_DOUBLE: g_vl_cvalue
->v_double = __builtin_va_arg((var_args), gdouble); break;
case G_VALUE_COLLECT_POINTER: g_vl_cvalue->v_pointer = __builtin_va_arg
((var_args), gpointer); break; default: do { g_assertion_message_expr
("Ctk", "ctktreemodel.c", 1807, ((const char*) (__func__)), (
(void*)0)); } while (0); } } *(&error) = g_vl_vtable->
lcopy_value (g_vl_value, g_vl_n_values, g_vl_cvalues, g_vl_flags
); } while (0)
;
1808 if (error)
1809 {
1810 g_warning ("%s: %s", G_STRLOC"ctktreemodel.c" ":" "1810", error);
1811 g_free (error);
1812
1813 /* we purposely leak the value here, it might not be
1814 * in a sane state if an error condition occurred
1815 */
1816 break;
1817 }
1818
1819 g_value_unset (&value);
1820
1821 column = va_arg (var_args, gint)__builtin_va_arg(var_args, gint);
1822 }
1823}
1824
1825/**
1826 * ctk_tree_model_row_changed:
1827 * @tree_model: a #CtkTreeModel
1828 * @path: a #CtkTreePath-struct pointing to the changed row
1829 * @iter: a valid #CtkTreeIter-struct pointing to the changed row
1830 *
1831 * Emits the #CtkTreeModel::row-changed signal on @tree_model.
1832 */
1833void
1834ctk_tree_model_row_changed (CtkTreeModel *tree_model,
1835 CtkTreePath *path,
1836 CtkTreeIter *iter)
1837{
1838 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1839 g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return;
} } while (0)
;
1840 g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return;
} } while (0)
;
1841
1842 g_signal_emit (tree_model, tree_model_signals[ROW_CHANGED], 0, path, iter);
1843}
1844
1845/**
1846 * ctk_tree_model_row_inserted:
1847 * @tree_model: a #CtkTreeModel
1848 * @path: a #CtkTreePath-struct pointing to the inserted row
1849 * @iter: a valid #CtkTreeIter-struct pointing to the inserted row
1850 *
1851 * Emits the #CtkTreeModel::row-inserted signal on @tree_model.
1852 */
1853void
1854ctk_tree_model_row_inserted (CtkTreeModel *tree_model,
1855 CtkTreePath *path,
1856 CtkTreeIter *iter)
1857{
1858 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1859 g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return;
} } while (0)
;
1860 g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return;
} } while (0)
;
1861
1862 g_signal_emit (tree_model, tree_model_signals[ROW_INSERTED], 0, path, iter);
1863}
1864
1865/**
1866 * ctk_tree_model_row_has_child_toggled:
1867 * @tree_model: a #CtkTreeModel
1868 * @path: a #CtkTreePath-struct pointing to the changed row
1869 * @iter: a valid #CtkTreeIter-struct pointing to the changed row
1870 *
1871 * Emits the #CtkTreeModel::row-has-child-toggled signal on
1872 * @tree_model. This should be called by models after the child
1873 * state of a node changes.
1874 */
1875void
1876ctk_tree_model_row_has_child_toggled (CtkTreeModel *tree_model,
1877 CtkTreePath *path,
1878 CtkTreeIter *iter)
1879{
1880 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1881 g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return;
} } while (0)
;
1882 g_return_if_fail (iter != NULL)do { if ((iter != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "iter != NULL"); return;
} } while (0)
;
1883
1884 g_signal_emit (tree_model, tree_model_signals[ROW_HAS_CHILD_TOGGLED], 0, path, iter);
1885}
1886
1887/**
1888 * ctk_tree_model_row_deleted:
1889 * @tree_model: a #CtkTreeModel
1890 * @path: a #CtkTreePath-struct pointing to the previous location of
1891 * the deleted row
1892 *
1893 * Emits the #CtkTreeModel::row-deleted signal on @tree_model.
1894 *
1895 * This should be called by models after a row has been removed.
1896 * The location pointed to by @path should be the location that
1897 * the row previously was at. It may not be a valid location anymore.
1898 *
1899 * Nodes that are deleted are not unreffed, this means that any
1900 * outstanding references on the deleted node should not be released.
1901 */
1902void
1903ctk_tree_model_row_deleted (CtkTreeModel *tree_model,
1904 CtkTreePath *path)
1905{
1906 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1907 g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return;
} } while (0)
;
1908
1909 g_signal_emit (tree_model, tree_model_signals[ROW_DELETED], 0, path);
1910}
1911
1912/**
1913 * ctk_tree_model_rows_reordered: (skip)
1914 * @tree_model: a #CtkTreeModel
1915 * @path: a #CtkTreePath-struct pointing to the tree node whose children
1916 * have been reordered
1917 * @iter: a valid #CtkTreeIter-struct pointing to the node whose children
1918 * have been reordered, or %NULL if the depth of @path is 0
1919 * @new_order: an array of integers mapping the current position of
1920 * each child to its old position before the re-ordering,
1921 * i.e. @new_order`[newpos] = oldpos`
1922 *
1923 * Emits the #CtkTreeModel::rows-reordered signal on @tree_model.
1924 *
1925 * This should be called by models when their rows have been
1926 * reordered.
1927 */
1928void
1929ctk_tree_model_rows_reordered (CtkTreeModel *tree_model,
1930 CtkTreePath *path,
1931 CtkTreeIter *iter,
1932 gint *new_order)
1933{
1934 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1935 g_return_if_fail (new_order != NULL)do { if ((new_order != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "new_order != NULL"); return
; } } while (0)
;
1936
1937 g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1938}
1939
1940/**
1941 * ctk_tree_model_rows_reordered_with_length: (rename-to ctk_tree_model_rows_reordered)
1942 * @tree_model: a #CtkTreeModel
1943 * @path: a #CtkTreePath-struct pointing to the tree node whose children
1944 * have been reordered
1945 * @iter: (allow-none): a valid #CtkTreeIter-struct pointing to the node
1946 * whose children have been reordered, or %NULL if the depth
1947 * of @path is 0
1948 * @new_order: (array length=length): an array of integers
1949 * mapping the current position of each child to its old
1950 * position before the re-ordering,
1951 * i.e. @new_order`[newpos] = oldpos`
1952 * @length: length of @new_order array
1953 *
1954 * Emits the #CtkTreeModel::rows-reordered signal on @tree_model.
1955 *
1956 * This should be called by models when their rows have been
1957 * reordered.
1958 *
1959 * Since: 3.10
1960 */
1961void
1962ctk_tree_model_rows_reordered_with_length (CtkTreeModel *tree_model,
1963 CtkTreePath *path,
1964 CtkTreeIter *iter,
1965 gint *new_order,
1966 gint length)
1967{
1968 g_return_if_fail (CTK_IS_TREE_MODEL (tree_model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((tree_model)); GType __t = ((ctk_tree_model_get_type ()))
; gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class
&& __inst->g_class->g_type == __t) __r = (!(0)
); else __r = g_type_check_instance_is_a (__inst, __t); __r; }
)))))) { } else { g_return_if_fail_warning ("Ctk", ((const char
*) (__func__)), "CTK_IS_TREE_MODEL (tree_model)"); return; } }
while (0)
;
1969 g_return_if_fail (new_order != NULL)do { if ((new_order != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "new_order != NULL"); return
; } } while (0)
;
1970 g_return_if_fail (length == ctk_tree_model_iter_n_children (tree_model, iter))do { if ((length == ctk_tree_model_iter_n_children (tree_model
, iter))) { } else { g_return_if_fail_warning ("Ctk", ((const
char*) (__func__)), "length == ctk_tree_model_iter_n_children (tree_model, iter)"
); return; } } while (0)
;
1971
1972 g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1973}
1974
1975static gboolean
1976ctk_tree_model_foreach_helper (CtkTreeModel *model,
1977 CtkTreeIter *iter,
1978 CtkTreePath *path,
1979 CtkTreeModelForeachFunc func,
1980 gpointer user_data)
1981{
1982 gboolean iters_persist;
1983
1984 iters_persist = ctk_tree_model_get_flags (model) & CTK_TREE_MODEL_ITERS_PERSIST;
1985
1986 do
1987 {
1988 CtkTreeIter child;
1989
1990 if ((* func) (model, path, iter, user_data))
1991 return TRUE(!(0));
1992
1993 if (!iters_persist)
1994 {
1995 if (!ctk_tree_model_get_iter (model, iter, path))
1996 return TRUE(!(0));
1997 }
1998
1999 if (ctk_tree_model_iter_children (model, &child, iter))
2000 {
2001 ctk_tree_path_down (path);
2002 if (ctk_tree_model_foreach_helper (model, &child, path, func, user_data))
2003 return TRUE(!(0));
2004 ctk_tree_path_up (path);
2005 }
2006
2007 ctk_tree_path_next (path);
2008 }
2009 while (ctk_tree_model_iter_next (model, iter));
2010
2011 return FALSE(0);
2012}
2013
2014/**
2015 * ctk_tree_model_foreach:
2016 * @model: a #CtkTreeModel
2017 * @func: (scope call): a function to be called on each row
2018 * @user_data: user data to passed to @func
2019 *
2020 * Calls func on each node in model in a depth-first fashion.
2021 *
2022 * If @func returns %TRUE, then the tree ceases to be walked,
2023 * and ctk_tree_model_foreach() returns.
2024 */
2025void
2026ctk_tree_model_foreach (CtkTreeModel *model,
2027 CtkTreeModelForeachFunc func,
2028 gpointer user_data)
2029{
2030 CtkTreePath *path;
2031 CtkTreeIter iter;
2032
2033 g_return_if_fail (CTK_IS_TREE_MODEL (model))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((model)); GType __t = ((ctk_tree_model_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_TREE_MODEL (model)"); return; } } while (0)
;
1
Assuming '__inst' is non-null
2
Taking false branch
3
Assuming field 'g_class' is null
4
Assuming the condition is true
5
Taking true branch
6
Loop condition is false. Exiting loop
2034 g_return_if_fail (func != NULL)do { if ((func != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "func != NULL"); return;
} } while (0)
;
7
Assuming 'func' is not equal to null
8
Taking true branch
9
Loop condition is false. Exiting loop
2035
2036 path = ctk_tree_path_new_first ();
10
Calling 'ctk_tree_path_new_first'
2037 if (!ctk_tree_model_get_iter (model, &iter, path))
2038 {
2039 ctk_tree_path_free (path);
2040 return;
2041 }
2042
2043 ctk_tree_model_foreach_helper (model, &iter, path, func, user_data);
2044 ctk_tree_path_free (path);
2045}
2046
2047
2048/*
2049 * CtkTreeRowReference
2050 */
2051
2052static void ctk_tree_row_reference_unref_path (CtkTreePath *path,
2053 CtkTreeModel *model,
2054 gint depth);
2055
2056
2057G_DEFINE_BOXED_TYPE (CtkTreeRowReference, ctk_tree_row_reference,static GType ctk_tree_row_reference_get_type_once (void); GType
ctk_tree_row_reference_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_row_reference_get_type_once (); (__extension__ ({
_Static_assert (sizeof *(&static_g_define_type_id) == sizeof
(gpointer), "Expression evaluates to false"); 0 ? (void) (*(
&static_g_define_type_id) = (g_define_type_id)) : (void) 0
; g_once_init_leave_pointer ((&static_g_define_type_id), (
gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType ctk_tree_row_reference_get_type_once
(void) { GType (* _g_register_boxed) (const gchar *, union {
CtkTreeRowReference * (*do_copy_type) (CtkTreeRowReference *
); CtkTreeRowReference * (*do_const_copy_type) (const CtkTreeRowReference
*); GBoxedCopyFunc do_copy_boxed; } __attribute__((__transparent_union__
)), union { void (* do_free_type) (CtkTreeRowReference *); GBoxedFreeFunc
do_free_boxed; } __attribute__((__transparent_union__)) ) = g_boxed_type_register_static
; GType g_define_type_id = _g_register_boxed (g_intern_static_string
("CtkTreeRowReference"), ctk_tree_row_reference_copy, ctk_tree_row_reference_free
); { {{};} } return g_define_type_id; }
2058 ctk_tree_row_reference_copy,static GType ctk_tree_row_reference_get_type_once (void); GType
ctk_tree_row_reference_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_row_reference_get_type_once (); (__extension__ ({
_Static_assert (sizeof *(&static_g_define_type_id) == sizeof
(gpointer), "Expression evaluates to false"); 0 ? (void) (*(
&static_g_define_type_id) = (g_define_type_id)) : (void) 0
; g_once_init_leave_pointer ((&static_g_define_type_id), (
gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType ctk_tree_row_reference_get_type_once
(void) { GType (* _g_register_boxed) (const gchar *, union {
CtkTreeRowReference * (*do_copy_type) (CtkTreeRowReference *
); CtkTreeRowReference * (*do_const_copy_type) (const CtkTreeRowReference
*); GBoxedCopyFunc do_copy_boxed; } __attribute__((__transparent_union__
)), union { void (* do_free_type) (CtkTreeRowReference *); GBoxedFreeFunc
do_free_boxed; } __attribute__((__transparent_union__)) ) = g_boxed_type_register_static
; GType g_define_type_id = _g_register_boxed (g_intern_static_string
("CtkTreeRowReference"), ctk_tree_row_reference_copy, ctk_tree_row_reference_free
); { {{};} } return g_define_type_id; }
2059 ctk_tree_row_reference_free)static GType ctk_tree_row_reference_get_type_once (void); GType
ctk_tree_row_reference_get_type (void) { static GType static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*)
0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= ctk_tree_row_reference_get_type_once (); (__extension__ ({
_Static_assert (sizeof *(&static_g_define_type_id) == sizeof
(gpointer), "Expression evaluates to false"); 0 ? (void) (*(
&static_g_define_type_id) = (g_define_type_id)) : (void) 0
; g_once_init_leave_pointer ((&static_g_define_type_id), (
gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType ctk_tree_row_reference_get_type_once
(void) { GType (* _g_register_boxed) (const gchar *, union {
CtkTreeRowReference * (*do_copy_type) (CtkTreeRowReference *
); CtkTreeRowReference * (*do_const_copy_type) (const CtkTreeRowReference
*); GBoxedCopyFunc do_copy_boxed; } __attribute__((__transparent_union__
)), union { void (* do_free_type) (CtkTreeRowReference *); GBoxedFreeFunc
do_free_boxed; } __attribute__((__transparent_union__)) ) = g_boxed_type_register_static
; GType g_define_type_id = _g_register_boxed (g_intern_static_string
("CtkTreeRowReference"), ctk_tree_row_reference_copy, ctk_tree_row_reference_free
); { {{};} } return g_define_type_id; }
2060
2061struct _CtkTreeRowReference
2062{
2063 GObject *proxy;
2064 CtkTreeModel *model;
2065 CtkTreePath *path;
2066};
2067
2068
2069static void
2070release_row_references (gpointer data)
2071{
2072 RowRefList *refs = data;
2073 GSList *tmp_list = NULL((void*)0);
2074
2075 tmp_list = refs->list;
2076 while (tmp_list != NULL((void*)0))
2077 {
2078 CtkTreeRowReference *reference = tmp_list->data;
2079
2080 if (reference->proxy == (GObject *)reference->model)
2081 reference->model = NULL((void*)0);
2082 reference->proxy = NULL((void*)0);
2083
2084 /* we don't free the reference, users are responsible for that. */
2085
2086 tmp_list = tmp_list->next;
2087 }
2088
2089 g_slist_free (refs->list);
2090 g_free (refs);
2091}
2092
2093static void
2094ctk_tree_row_ref_inserted (RowRefList *refs,
2095 CtkTreePath *path,
2096 CtkTreeIter *iter G_GNUC_UNUSED__attribute__ ((__unused__)))
2097{
2098 GSList *tmp_list;
2099
2100 if (refs == NULL((void*)0))
2101 return;
2102
2103 /* This function corrects the path stored in the reference to
2104 * account for an insertion. Note that it's called _after_ the
2105 * insertion with the path to the newly-inserted row. Which means
2106 * that the inserted path is in a different "coordinate system" than
2107 * the old path (e.g. if the inserted path was just before the old
2108 * path, then inserted path and old path will be the same, and old
2109 * path must be moved down one).
2110 */
2111
2112 tmp_list = refs->list;
2113
2114 while (tmp_list != NULL((void*)0))
2115 {
2116 CtkTreeRowReference *reference = tmp_list->data;
2117
2118 if (reference->path == NULL((void*)0))
2119 goto done;
2120
2121 if (reference->path->depth >= path->depth)
2122 {
2123 gint i;
2124 gboolean ancestor = TRUE(!(0));
2125
2126 for (i = 0; i < path->depth - 1; i ++)
2127 {
2128 if (path->indices[i] != reference->path->indices[i])
2129 {
2130 ancestor = FALSE(0);
2131 break;
2132 }
2133 }
2134 if (ancestor == FALSE(0))
2135 goto done;
2136
2137 if (path->indices[path->depth-1] <= reference->path->indices[path->depth-1])
2138 reference->path->indices[path->depth-1] += 1;
2139 }
2140 done:
2141 tmp_list = tmp_list->next;
2142 }
2143}
2144
2145static void
2146ctk_tree_row_ref_deleted (RowRefList *refs,
2147 CtkTreePath *path)
2148{
2149 GSList *tmp_list;
2150
2151 if (refs == NULL((void*)0))
2152 return;
2153
2154 /* This function corrects the path stored in the reference to
2155 * account for an deletion. Note that it's called _after_ the
2156 * deletion with the old path of the just-deleted row. Which means
2157 * that the deleted path is the same now-defunct "coordinate system"
2158 * as the path saved in the reference, which is what we want to fix.
2159 */
2160
2161 tmp_list = refs->list;
2162
2163 while (tmp_list != NULL((void*)0))
2164 {
2165 CtkTreeRowReference *reference = tmp_list->data;
2166
2167 if (reference->path)
2168 {
2169 gint i;
2170
2171 if (path->depth > reference->path->depth)
2172 goto next;
2173 for (i = 0; i < path->depth - 1; i++)
2174 {
2175 if (path->indices[i] != reference->path->indices[i])
2176 goto next;
2177 }
2178
2179 /* We know it affects us. */
2180 if (path->indices[i] == reference->path->indices[i])
2181 {
2182 if (reference->path->depth > path->depth)
2183 /* some parent was deleted, trying to unref any node
2184 * between the deleted parent and the node the reference
2185 * is pointing to is bad, as those nodes are already gone.
2186 */
2187 ctk_tree_row_reference_unref_path (reference->path, reference->model, path->depth - 1);
2188 else
2189 ctk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth - 1);
2190 ctk_tree_path_free (reference->path);
2191 reference->path = NULL((void*)0);
2192 }
2193 else if (path->indices[i] < reference->path->indices[i])
2194 {
2195 reference->path->indices[path->depth-1]-=1;
2196 }
2197 }
2198
2199next:
2200 tmp_list = tmp_list->next;
2201 }
2202}
2203
2204static void
2205ctk_tree_row_ref_reordered (RowRefList *refs,
2206 CtkTreePath *path,
2207 CtkTreeIter *iter,
2208 gint *new_order)
2209{
2210 GSList *tmp_list;
2211 gint length;
2212
2213 if (refs == NULL((void*)0))
2214 return;
2215
2216 tmp_list = refs->list;
2217
2218 while (tmp_list != NULL((void*)0))
2219 {
2220 CtkTreeRowReference *reference = tmp_list->data;
2221
2222 length = ctk_tree_model_iter_n_children (CTK_TREE_MODEL (reference->model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((reference->model)), ((ctk_tree_model_get_type ())))))
)
, iter);
2223
2224 if (length < 2)
2225 return;
2226
2227 if ((reference->path) &&
2228 (ctk_tree_path_is_ancestor (path, reference->path)))
2229 {
2230 gint ref_depth = ctk_tree_path_get_depth (reference->path);
2231 gint depth = ctk_tree_path_get_depth (path);
2232
2233 if (ref_depth > depth)
2234 {
2235 gint i;
2236 gint *indices = ctk_tree_path_get_indices (reference->path);
2237
2238 for (i = 0; i < length; i++)
2239 {
2240 if (new_order[i] == indices[depth])
2241 {
2242 indices[depth] = i;
2243 break;
2244 }
2245 }
2246 }
2247 }
2248
2249 tmp_list = tmp_list->next;
2250 }
2251}
2252
2253/* We do this recursively so that we can unref children nodes
2254 * before their parent
2255 */
2256static void
2257ctk_tree_row_reference_unref_path_helper (CtkTreePath *path,
2258 CtkTreeModel *model,
2259 CtkTreeIter *parent_iter,
2260 gint depth,
2261 gint current_depth)
2262{
2263 CtkTreeIter iter;
2264
2265 if (depth == current_depth)
2266 return;
2267
2268 ctk_tree_model_iter_nth_child (model, &iter, parent_iter, path->indices[current_depth]);
2269 ctk_tree_row_reference_unref_path_helper (path, model, &iter, depth, current_depth + 1);
2270 ctk_tree_model_unref_node (model, &iter);
2271}
2272
2273static void
2274ctk_tree_row_reference_unref_path (CtkTreePath *path,
2275 CtkTreeModel *model,
2276 gint depth)
2277{
2278 CtkTreeIter iter;
2279
2280 if (depth <= 0)
2281 return;
2282
2283 ctk_tree_model_iter_nth_child (model, &iter, NULL((void*)0), path->indices[0]);
2284 ctk_tree_row_reference_unref_path_helper (path, model, &iter, depth, 1);
2285 ctk_tree_model_unref_node (model, &iter);
2286}
2287
2288/**
2289 * ctk_tree_row_reference_new:
2290 * @model: a #CtkTreeModel
2291 * @path: a valid #CtkTreePath-struct to monitor
2292 *
2293 * Creates a row reference based on @path.
2294 *
2295 * This reference will keep pointing to the node pointed to
2296 * by @path, so long as it exists. Any changes that occur on @model are
2297 * propagated, and the path is updated appropriately. If
2298 * @path isn’t a valid path in @model, then %NULL is returned.
2299 *
2300 * Returns: a newly allocated #CtkTreeRowReference, or %NULL
2301 */
2302CtkTreeRowReference *
2303ctk_tree_row_reference_new (CtkTreeModel *model,
2304 CtkTreePath *path)
2305{
2306 g_return_val_if_fail (CTK_IS_TREE_MODEL (model), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((model)); GType __t = ((ctk_tree_model_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_TREE_MODEL (model)"); return (((void*)0)); } } while
(0)
;
2307 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
2308
2309 /* We use the model itself as the proxy object; and call
2310 * ctk_tree_row_reference_inserted(), etc, in the
2311 * class closure (default handler) marshalers for the signal.
2312 */
2313 return ctk_tree_row_reference_new_proxy (G_OBJECT (model)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), (((GType) ((20) << (2))))))))
, model, path);
2314}
2315
2316/**
2317 * ctk_tree_row_reference_new_proxy:
2318 * @proxy: a proxy #GObject
2319 * @model: a #CtkTreeModel
2320 * @path: a valid #CtkTreePath-struct to monitor
2321 *
2322 * You do not need to use this function.
2323 *
2324 * Creates a row reference based on @path.
2325 *
2326 * This reference will keep pointing to the node pointed to
2327 * by @path, so long as it exists. If @path isn’t a valid
2328 * path in @model, then %NULL is returned. However, unlike
2329 * references created with ctk_tree_row_reference_new(), it
2330 * does not listen to the model for changes. The creator of
2331 * the row reference must do this explicitly using
2332 * ctk_tree_row_reference_inserted(), ctk_tree_row_reference_deleted(),
2333 * ctk_tree_row_reference_reordered().
2334 *
2335 * These functions must be called exactly once per proxy when the
2336 * corresponding signal on the model is emitted. This single call
2337 * updates all row references for that proxy. Since built-in CTK+
2338 * objects like #CtkTreeView already use this mechanism internally,
2339 * using them as the proxy object will produce unpredictable results.
2340 * Further more, passing the same object as @model and @proxy
2341 * doesn’t work for reasons of internal implementation.
2342 *
2343 * This type of row reference is primarily meant by structures that
2344 * need to carefully monitor exactly when a row reference updates
2345 * itself, and is not generally needed by most applications.
2346 *
2347 * Returns: a newly allocated #CtkTreeRowReference, or %NULL
2348 */
2349CtkTreeRowReference *
2350ctk_tree_row_reference_new_proxy (GObject *proxy,
2351 CtkTreeModel *model,
2352 CtkTreePath *path)
2353{
2354 CtkTreeRowReference *reference;
2355 RowRefList *refs;
2356 CtkTreeIter parent_iter;
2357 gint i;
2358
2359 g_return_val_if_fail (G_IS_OBJECT (proxy), NULL)do { if (((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((proxy)), (((GType) ((20) << (2)))))))))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"G_IS_OBJECT (proxy)"); return (((void*)0)); } } while (0)
;
2360 g_return_val_if_fail (CTK_IS_TREE_MODEL (model), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((model)); GType __t = ((ctk_tree_model_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__
)), "CTK_IS_TREE_MODEL (model)"); return (((void*)0)); } } while
(0)
;
2361 g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path != NULL"); return (
((void*)0)); } } while (0)
;
2362 g_return_val_if_fail (path->depth > 0, NULL)do { if ((path->depth > 0)) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "path->depth > 0")
; return (((void*)0)); } } while (0)
;
2363
2364 /* check that the path is valid */
2365 if (ctk_tree_model_get_iter (model, &parent_iter, path) == FALSE(0))
2366 return NULL((void*)0);
2367
2368 /* Now we want to ref every node */
2369 ctk_tree_model_iter_nth_child (model, &parent_iter, NULL((void*)0), path->indices[0]);
2370 ctk_tree_model_ref_node (model, &parent_iter);
2371
2372 for (i = 1; i < path->depth; i++)
2373 {
2374 CtkTreeIter iter;
2375 ctk_tree_model_iter_nth_child (model, &iter, &parent_iter, path->indices[i]);
2376 ctk_tree_model_ref_node (model, &iter);
2377 parent_iter = iter;
2378 }
2379
2380 /* Make the row reference */
2381 reference = g_new (CtkTreeRowReference, 1)((CtkTreeRowReference *) g_malloc_n ((1), sizeof (CtkTreeRowReference
)))
;
2382
2383 g_object_ref (proxy)((__typeof__ (proxy)) (g_object_ref) (proxy));
2384 g_object_ref (model)((__typeof__ (model)) (g_object_ref) (model));
2385 reference->proxy = proxy;
2386 reference->model = model;
2387 reference->path = ctk_tree_path_copy (path);
2388
2389 refs = g_object_get_data (G_OBJECT (proxy)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((proxy)), (((GType) ((20) << (2))))))))
, ROW_REF_DATA_STRING"ctk-tree-row-refs");
2390
2391 if (refs == NULL((void*)0))
2392 {
2393 refs = g_new (RowRefList, 1)((RowRefList *) g_malloc_n ((1), sizeof (RowRefList)));
2394 refs->list = NULL((void*)0);
2395
2396 g_object_set_data_full (G_OBJECT (proxy)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((proxy)), (((GType) ((20) << (2))))))))
,
2397 I_(ROW_REF_DATA_STRING)g_intern_static_string ("ctk-tree-row-refs"),
2398 refs, release_row_references);
2399 }
2400
2401 refs->list = g_slist_prepend (refs->list, reference);
2402
2403 return reference;
2404}
2405
2406/**
2407 * ctk_tree_row_reference_get_path:
2408 * @reference: a #CtkTreeRowReference
2409 *
2410 * Returns a path that the row reference currently points to,
2411 * or %NULL if the path pointed to is no longer valid.
2412 *
2413 * Returns: (nullable) (transfer full): a current path, or %NULL
2414 */
2415CtkTreePath *
2416ctk_tree_row_reference_get_path (CtkTreeRowReference *reference)
2417{
2418 g_return_val_if_fail (reference != NULL, NULL)do { if ((reference != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "reference != NULL"); return
(((void*)0)); } } while (0)
;
2419
2420 if (reference->proxy == NULL((void*)0))
2421 return NULL((void*)0);
2422
2423 if (reference->path == NULL((void*)0))
2424 return NULL((void*)0);
2425
2426 return ctk_tree_path_copy (reference->path);
2427}
2428
2429/**
2430 * ctk_tree_row_reference_get_model:
2431 * @reference: a #CtkTreeRowReference
2432 *
2433 * Returns the model that the row reference is monitoring.
2434 *
2435 * Returns: (transfer none): the model
2436 *
2437 * Since: 2.8
2438 */
2439CtkTreeModel *
2440ctk_tree_row_reference_get_model (CtkTreeRowReference *reference)
2441{
2442 g_return_val_if_fail (reference != NULL, NULL)do { if ((reference != ((void*)0))) { } else { g_return_if_fail_warning
("Ctk", ((const char*) (__func__)), "reference != NULL"); return
(((void*)0)); } } while (0)
;
2443
2444 return reference->model;
2445}
2446
2447/**
2448 * ctk_tree_row_reference_valid:
2449 * @reference: (allow-none): a #CtkTreeRowReference, or %NULL
2450 *
2451 * Returns %TRUE if the @reference is non-%NULL and refers to
2452 * a current valid path.
2453 *
2454 * Returns: %TRUE if @reference points to a valid path
2455 */
2456gboolean
2457ctk_tree_row_reference_valid (CtkTreeRowReference *reference)
2458{
2459 if (reference == NULL((void*)0) || reference->path == NULL((void*)0))
2460 return FALSE(0);
2461
2462 return TRUE(!(0));
2463}
2464
2465
2466/**
2467 * ctk_tree_row_reference_copy:
2468 * @reference: a #CtkTreeRowReference
2469 *
2470 * Copies a #CtkTreeRowReference.
2471 *
2472 * Returns: a copy of @reference
2473 *
2474 * Since: 2.2
2475 */
2476CtkTreeRowReference *
2477ctk_tree_row_reference_copy (CtkTreeRowReference *reference)
2478{
2479 return ctk_tree_row_reference_new_proxy (reference->proxy,
2480 reference->model,
2481 reference->path);
2482}
2483
2484/**
2485 * ctk_tree_row_reference_free:
2486 * @reference: (allow-none): a #CtkTreeRowReference, or %NULL
2487 *
2488 * Free’s @reference. @reference may be %NULL
2489 */
2490void
2491ctk_tree_row_reference_free (CtkTreeRowReference *reference)
2492{
2493 RowRefList *refs;
2494
2495 if (reference == NULL((void*)0))
2496 return;
2497
2498 refs = g_object_get_data (G_OBJECT (reference->proxy)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((reference->proxy)), (((GType) ((20) << (2))))))
))
, ROW_REF_DATA_STRING"ctk-tree-row-refs");
2499
2500 if (refs == NULL((void*)0))
2501 {
2502 g_warning (G_STRLOC"ctktreemodel.c" ":" "2502"": bad row reference, proxy has no outstanding row references");
2503 return;
2504 }
2505
2506 refs->list = g_slist_remove (refs->list, reference);
2507
2508 if (refs->list == NULL((void*)0))
2509 {
2510 g_object_set_data (G_OBJECT (reference->proxy)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((reference->proxy)), (((GType) ((20) << (2))))))
))
,
2511 I_(ROW_REF_DATA_STRING)g_intern_static_string ("ctk-tree-row-refs"),
2512 NULL((void*)0));
2513 }
2514
2515 if (reference->path)
2516 {
2517 ctk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth);
2518 ctk_tree_path_free (reference->path);
2519 }
2520
2521 g_object_unref (reference->proxy);
2522 g_object_unref (reference->model);
2523 g_free (reference);
2524}
2525
2526/**
2527 * ctk_tree_row_reference_inserted:
2528 * @proxy: a #GObject
2529 * @path: the row position that was inserted
2530 *
2531 * Lets a set of row reference created by
2532 * ctk_tree_row_reference_new_proxy() know that the
2533 * model emitted the #CtkTreeModel::row-inserted signal.
2534 */
2535void
2536ctk_tree_row_reference_inserted (GObject *proxy,
2537 CtkTreePath *path)
2538{
2539 g_return_if_fail (G_IS_OBJECT (proxy))do { if (((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((proxy)), (((GType) ((20) << (2)))))))))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"G_IS_OBJECT (proxy)"); return; } } while (0)
;
2540
2541 ctk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING"ctk-tree-row-refs"), path, NULL((void*)0));
2542}
2543
2544/**
2545 * ctk_tree_row_reference_deleted:
2546 * @proxy: a #GObject
2547 * @path: the path position that was deleted
2548 *
2549 * Lets a set of row reference created by
2550 * ctk_tree_row_reference_new_proxy() know that the
2551 * model emitted the #CtkTreeModel::row-deleted signal.
2552 */
2553void
2554ctk_tree_row_reference_deleted (GObject *proxy,
2555 CtkTreePath *path)
2556{
2557 g_return_if_fail (G_IS_OBJECT (proxy))do { if (((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((proxy)), (((GType) ((20) << (2)))))))))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"G_IS_OBJECT (proxy)"); return; } } while (0)
;
2558
2559 ctk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING"ctk-tree-row-refs"), path);
2560}
2561
2562/**
2563 * ctk_tree_row_reference_reordered: (skip)
2564 * @proxy: a #GObject
2565 * @path: the parent path of the reordered signal
2566 * @iter: the iter pointing to the parent of the reordered
2567 * @new_order: (array): the new order of rows
2568 *
2569 * Lets a set of row reference created by
2570 * ctk_tree_row_reference_new_proxy() know that the
2571 * model emitted the #CtkTreeModel::rows-reordered signal.
2572 */
2573void
2574ctk_tree_row_reference_reordered (GObject *proxy,
2575 CtkTreePath *path,
2576 CtkTreeIter *iter,
2577 gint *new_order)
2578{
2579 g_return_if_fail (G_IS_OBJECT (proxy))do { if (((((g_type_check_instance_is_fundamentally_a ((GTypeInstance
*) ((proxy)), (((GType) ((20) << (2)))))))))) { } else {
g_return_if_fail_warning ("Ctk", ((const char*) (__func__)),
"G_IS_OBJECT (proxy)"); return; } } while (0)
;
2580
2581 ctk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING"ctk-tree-row-refs"), path, iter, new_order);
2582}