File: | ctk/ctktreemodelsort.c |
Warning: | line 2193, column 31 Using a fixed address is not portable because that address will probably not be valid in all environments or platforms |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* ctktreemodelsort.c | |||
2 | * Copyright (C) 2000,2001 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com> | |||
3 | * Copyright (C) 2001,2002 Kristian Rietveld <kris@gtk.org> | |||
4 | * | |||
5 | * This library is free software; you can redistribute it and/or | |||
6 | * modify it under the terms of the GNU Library General Public | |||
7 | * License as published by the Free Software Foundation; either | |||
8 | * version 2 of the License, or (at your option) any later version. | |||
9 | * | |||
10 | * This library is distributed in the hope that it will be useful, | |||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
13 | * Library General Public License for more details. | |||
14 | * | |||
15 | * You should have received a copy of the GNU Library General Public | |||
16 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
17 | */ | |||
18 | ||||
19 | #include "config.h" | |||
20 | #include <string.h> | |||
21 | ||||
22 | #include "ctktreemodelsort.h" | |||
23 | #include "ctktreesortable.h" | |||
24 | #include "ctktreestore.h" | |||
25 | #include "ctktreedatalist.h" | |||
26 | #include "ctkintl.h" | |||
27 | #include "ctkprivate.h" | |||
28 | #include "ctktreednd.h" | |||
29 | ||||
30 | ||||
31 | /** | |||
32 | * SECTION:ctktreemodelsort | |||
33 | * @Short_description: A CtkTreeModel which makes an underlying tree model sortable | |||
34 | * @Title: CtkTreeModelSort | |||
35 | * @See_also: #CtkTreeModel, #CtkListStore, #CtkTreeStore, #CtkTreeSortable, #CtkTreeModelFilter | |||
36 | * | |||
37 | * The #CtkTreeModelSort is a model which implements the #CtkTreeSortable | |||
38 | * interface. It does not hold any data itself, but rather is created with | |||
39 | * a child model and proxies its data. It has identical column types to | |||
40 | * this child model, and the changes in the child are propagated. The | |||
41 | * primary purpose of this model is to provide a way to sort a different | |||
42 | * model without modifying it. Note that the sort function used by | |||
43 | * #CtkTreeModelSort is not guaranteed to be stable. | |||
44 | * | |||
45 | * The use of this is best demonstrated through an example. In the | |||
46 | * following sample code we create two #CtkTreeView widgets each with a | |||
47 | * view of the same data. As the model is wrapped here by a | |||
48 | * #CtkTreeModelSort, the two #CtkTreeViews can each sort their | |||
49 | * view of the data without affecting the other. By contrast, if we | |||
50 | * simply put the same model in each widget, then sorting the first would | |||
51 | * sort the second. | |||
52 | * | |||
53 | * ## Using a #CtkTreeModelSort | |||
54 | * | |||
55 | * |[<!-- language="C" --> | |||
56 | * { | |||
57 | * CtkTreeView *tree_view1; | |||
58 | * CtkTreeView *tree_view2; | |||
59 | * CtkTreeModel *sort_model1; | |||
60 | * CtkTreeModel *sort_model2; | |||
61 | * CtkTreeModel *child_model; | |||
62 | * | |||
63 | * // get the child model | |||
64 | * child_model = get_my_model (); | |||
65 | * | |||
66 | * // Create the first tree | |||
67 | * sort_model1 = ctk_tree_model_sort_new_with_model (child_model); | |||
68 | * tree_view1 = ctk_tree_view_new_with_model (sort_model1); | |||
69 | * | |||
70 | * // Create the second tree | |||
71 | * sort_model2 = ctk_tree_model_sort_new_with_model (child_model); | |||
72 | * tree_view2 = ctk_tree_view_new_with_model (sort_model2); | |||
73 | * | |||
74 | * // Now we can sort the two models independently | |||
75 | * ctk_tree_sortable_set_sort_column_id (CTK_TREE_SORTABLE (sort_model1), | |||
76 | * COLUMN_1, CTK_SORT_ASCENDING); | |||
77 | * ctk_tree_sortable_set_sort_column_id (CTK_TREE_SORTABLE (sort_model2), | |||
78 | * COLUMN_1, CTK_SORT_DESCENDING); | |||
79 | * } | |||
80 | * ]| | |||
81 | * | |||
82 | * To demonstrate how to access the underlying child model from the sort | |||
83 | * model, the next example will be a callback for the #CtkTreeSelection | |||
84 | * #CtkTreeSelection::changed signal. In this callback, we get a string | |||
85 | * from COLUMN_1 of the model. We then modify the string, find the same | |||
86 | * selected row on the child model, and change the row there. | |||
87 | * | |||
88 | * ## Accessing the child model of in a selection changed callback | |||
89 | * | |||
90 | * |[<!-- language="C" --> | |||
91 | * void | |||
92 | * selection_changed (CtkTreeSelection *selection, gpointer data) | |||
93 | * { | |||
94 | * CtkTreeModel *sort_model = NULL; | |||
95 | * CtkTreeModel *child_model; | |||
96 | * CtkTreeIter sort_iter; | |||
97 | * CtkTreeIter child_iter; | |||
98 | * char *some_data = NULL; | |||
99 | * char *modified_data; | |||
100 | * | |||
101 | * // Get the current selected row and the model. | |||
102 | * if (! ctk_tree_selection_get_selected (selection, | |||
103 | * &sort_model, | |||
104 | * &sort_iter)) | |||
105 | * return; | |||
106 | * | |||
107 | * // Look up the current value on the selected row and get | |||
108 | * // a new value to change it to. | |||
109 | * ctk_tree_model_get (CTK_TREE_MODEL (sort_model), &sort_iter, | |||
110 | * COLUMN_1, &some_data, | |||
111 | * -1); | |||
112 | * | |||
113 | * modified_data = change_the_data (some_data); | |||
114 | * g_free (some_data); | |||
115 | * | |||
116 | * // Get an iterator on the child model, instead of the sort model. | |||
117 | * ctk_tree_model_sort_convert_iter_to_child_iter (CTK_TREE_MODEL_SORT (sort_model), | |||
118 | * &child_iter, | |||
119 | * &sort_iter); | |||
120 | * | |||
121 | * // Get the child model and change the value of the row. In this | |||
122 | * // example, the child model is a CtkListStore. It could be any other | |||
123 | * // type of model, though. | |||
124 | * child_model = ctk_tree_model_sort_get_model (CTK_TREE_MODEL_SORT (sort_model)); | |||
125 | * ctk_list_store_set (CTK_LIST_STORE (child_model), &child_iter, | |||
126 | * COLUMN_1, &modified_data, | |||
127 | * -1); | |||
128 | * g_free (modified_data); | |||
129 | * } | |||
130 | * ]| | |||
131 | */ | |||
132 | ||||
133 | ||||
134 | /* Notes on this implementation of CtkTreeModelSort | |||
135 | * ================================================ | |||
136 | * | |||
137 | * Warnings | |||
138 | * -------- | |||
139 | * | |||
140 | * In this code there is a potential for confusion as to whether an iter, | |||
141 | * path or value refers to the CtkTreeModelSort model, or to the child model | |||
142 | * that has been set. As a convention, variables referencing the child model | |||
143 | * will have an s_ prefix before them (ie. s_iter, s_value, s_path); | |||
144 | * Conversion of iterators and paths between CtkTreeModelSort and the child | |||
145 | * model is done through the various ctk_tree_model_sort_convert_* functions. | |||
146 | * | |||
147 | * Iterator format | |||
148 | * --------------- | |||
149 | * | |||
150 | * The iterator format of iterators handed out by CtkTreeModelSort is as | |||
151 | * follows: | |||
152 | * | |||
153 | * iter->stamp = tree_model_sort->stamp | |||
154 | * iter->user_data = SortLevel | |||
155 | * iter->user_data2 = SortElt | |||
156 | * | |||
157 | * Internal data structure | |||
158 | * ----------------------- | |||
159 | * | |||
160 | * Using SortLevel and SortElt, CtkTreeModelSort maintains a “cache” of | |||
161 | * the mapping from CtkTreeModelSort nodes to nodes in the child model. | |||
162 | * This is to avoid sorting a level each time an operation is requested | |||
163 | * on CtkTreeModelSort, such as get iter, get path, get value. | |||
164 | * | |||
165 | * A SortElt corresponds to a single node. A node and its siblings are | |||
166 | * stored in a SortLevel. The SortLevel keeps a reference to the parent | |||
167 | * SortElt and its SortLevel (if any). The SortElt can have a "children" | |||
168 | * pointer set, which points at a child level (a sub level). | |||
169 | * | |||
170 | * In a SortLevel, nodes are stored in a GSequence. The GSequence | |||
171 | * allows for fast additions and removals, and supports sorting | |||
172 | * the level of SortElt nodes. | |||
173 | * | |||
174 | * It is important to recognize the two different mappings that play | |||
175 | * a part in this code: | |||
176 | * I. The mapping from the client to this model. The order in which | |||
177 | * nodes are stored in the GSequence is the order in which the | |||
178 | * nodes are exposed to clients of the CtkTreeModelSort. | |||
179 | * II. The mapping from this model to its child model. Each SortElt | |||
180 | * contains an “offset” field which is the offset of the | |||
181 | * corresponding node in the child model. | |||
182 | * | |||
183 | * Reference counting | |||
184 | * ------------------ | |||
185 | * | |||
186 | * CtkTreeModelSort forwards all reference and unreference operations | |||
187 | * to the corresponding node in the child model. The reference count | |||
188 | * of each node is also maintained internally, in the “ref_count” | |||
189 | * fields in SortElt and SortLevel. For each ref and unref operation on | |||
190 | * a SortElt, the “ref_count” of the SortLevel is updated accordingly. | |||
191 | * In addition, if a SortLevel has a parent, a reference is taken on | |||
192 | * this parent. This happens in ctk_tree_model_sort_build_level() and | |||
193 | * the reference is released again in ctk_tree_model_sort_free_level(). | |||
194 | * This ensures that when CtkTreeModelSort takes a reference on a node | |||
195 | * (for example during sorting), all parent nodes are referenced | |||
196 | * according to reference counting rule 1, see the CtkTreeModel | |||
197 | * documentation. | |||
198 | * | |||
199 | * When a level has a reference count of zero, which means that | |||
200 | * none of the nodes in the level is referenced, the level has | |||
201 | * a “zero ref count” on all its parents. As soon as the level | |||
202 | * reaches a reference count of zero, the zero ref count value is | |||
203 | * incremented by one on all parents of this level. Similarly, as | |||
204 | * soon as the reference count of a level changes from zero, the | |||
205 | * zero ref count value is decremented by one on all parents. | |||
206 | * | |||
207 | * The zero ref count value is used to clear unused portions of | |||
208 | * the cache. If a SortElt has a zero ref count of one, then | |||
209 | * its child level is unused and can be removed from the cache. | |||
210 | * If the zero ref count value is higher than one, then the | |||
211 | * child level contains sublevels which are unused as well. | |||
212 | * ctk_tree_model_sort_clear_cache() uses this to not recurse | |||
213 | * into levels which have a zero ref count of zero. | |||
214 | */ | |||
215 | ||||
216 | typedef struct _SortElt SortElt; | |||
217 | typedef struct _SortLevel SortLevel; | |||
218 | typedef struct _SortData SortData; | |||
219 | ||||
220 | struct _SortElt | |||
221 | { | |||
222 | CtkTreeIter iter; | |||
223 | SortLevel *children; | |||
224 | gint offset; | |||
225 | gint ref_count; | |||
226 | gint zero_ref_count; | |||
227 | gint old_index; /* used while sorting */ | |||
228 | GSequenceIter *siter; /* iter into seq */ | |||
229 | }; | |||
230 | ||||
231 | struct _SortLevel | |||
232 | { | |||
233 | GSequence *seq; | |||
234 | gint ref_count; | |||
235 | SortElt *parent_elt; | |||
236 | SortLevel *parent_level; | |||
237 | }; | |||
238 | ||||
239 | struct _SortData | |||
240 | { | |||
241 | CtkTreeModelSort *tree_model_sort; | |||
242 | CtkTreeIterCompareFunc sort_func; | |||
243 | gpointer sort_data; | |||
244 | ||||
245 | CtkTreePath *parent_path; | |||
246 | gint *parent_path_indices; | |||
247 | gint parent_path_depth; | |||
248 | }; | |||
249 | ||||
250 | /* Properties */ | |||
251 | enum { | |||
252 | PROP_0, | |||
253 | /* Construct args */ | |||
254 | PROP_MODEL | |||
255 | }; | |||
256 | ||||
257 | ||||
258 | struct _CtkTreeModelSortPrivate | |||
259 | { | |||
260 | gpointer root; | |||
261 | gint stamp; | |||
262 | guint child_flags; | |||
263 | CtkTreeModel *child_model; | |||
264 | gint zero_ref_count; | |||
265 | ||||
266 | /* sort information */ | |||
267 | GList *sort_list; | |||
268 | gint sort_column_id; | |||
269 | CtkSortType order; | |||
270 | ||||
271 | /* default sort */ | |||
272 | CtkTreeIterCompareFunc default_sort_func; | |||
273 | gpointer default_sort_data; | |||
274 | GDestroyNotify default_sort_destroy; | |||
275 | ||||
276 | /* signal ids */ | |||
277 | gulong changed_id; | |||
278 | gulong inserted_id; | |||
279 | gulong has_child_toggled_id; | |||
280 | gulong deleted_id; | |||
281 | gulong reordered_id; | |||
282 | }; | |||
283 | ||||
284 | /* Set this to 0 to disable caching of child iterators. This | |||
285 | * allows for more stringent testing. It is recommended to set this | |||
286 | * to one when refactoring this code and running the unit tests to | |||
287 | * catch more errors. | |||
288 | */ | |||
289 | #if 1 | |||
290 | # define CTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort)(((CtkTreeModelSort *)tree_model_sort)->priv->child_flags &CTK_TREE_MODEL_ITERS_PERSIST) \ | |||
291 | (((CtkTreeModelSort *)tree_model_sort)->priv->child_flags&CTK_TREE_MODEL_ITERS_PERSIST) | |||
292 | #else | |||
293 | # define CTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort)(((CtkTreeModelSort *)tree_model_sort)->priv->child_flags &CTK_TREE_MODEL_ITERS_PERSIST) (FALSE(0)) | |||
294 | #endif | |||
295 | ||||
296 | #define SORT_ELT(sort_elt)((SortElt *)sort_elt) ((SortElt *)sort_elt) | |||
297 | #define SORT_LEVEL(sort_level)((SortLevel *)sort_level) ((SortLevel *)sort_level) | |||
298 | #define GET_ELT(siter)((SortElt *) (siter ? g_sequence_get (siter) : ((void*)0))) ((SortElt *) (siter ? g_sequence_get (siter) : NULL((void*)0))) | |||
299 | ||||
300 | ||||
301 | #define GET_CHILD_ITER(tree_model_sort,ch_iter,so_iter)ctk_tree_model_sort_convert_iter_to_child_iter((CtkTreeModelSort *)(tree_model_sort), (ch_iter), (so_iter)); ctk_tree_model_sort_convert_iter_to_child_iter((CtkTreeModelSort*)(tree_model_sort), (ch_iter), (so_iter)); | |||
302 | ||||
303 | #define NO_SORT_FUNC((CtkTreeIterCompareFunc) 0x1) ((CtkTreeIterCompareFunc) 0x1) | |||
304 | ||||
305 | #define VALID_ITER(iter, tree_model_sort)((iter) != ((void*)0) && (iter)->user_data != ((void *)0) && (iter)->user_data2 != ((void*)0) && (tree_model_sort)->priv->stamp == (iter)->stamp) ((iter) != NULL((void*)0) && (iter)->user_data != NULL((void*)0) && (iter)->user_data2 != NULL((void*)0) && (tree_model_sort)->priv->stamp == (iter)->stamp) | |||
306 | ||||
307 | /* general (object/interface init, etc) */ | |||
308 | static void ctk_tree_model_sort_tree_model_init (CtkTreeModelIface *iface); | |||
309 | static void ctk_tree_model_sort_tree_sortable_init (CtkTreeSortableIface *iface); | |||
310 | static void ctk_tree_model_sort_drag_source_init (CtkTreeDragSourceIface*iface); | |||
311 | static void ctk_tree_model_sort_finalize (GObject *object); | |||
312 | static void ctk_tree_model_sort_set_property (GObject *object, | |||
313 | guint prop_id, | |||
314 | const GValue *value, | |||
315 | GParamSpec *pspec); | |||
316 | static void ctk_tree_model_sort_get_property (GObject *object, | |||
317 | guint prop_id, | |||
318 | GValue *value, | |||
319 | GParamSpec *pspec); | |||
320 | ||||
321 | /* our signal handlers */ | |||
322 | static void ctk_tree_model_sort_row_changed (CtkTreeModel *model, | |||
323 | CtkTreePath *start_path, | |||
324 | CtkTreeIter *start_iter, | |||
325 | gpointer data); | |||
326 | static void ctk_tree_model_sort_row_inserted (CtkTreeModel *model, | |||
327 | CtkTreePath *path, | |||
328 | CtkTreeIter *iter, | |||
329 | gpointer data); | |||
330 | static void ctk_tree_model_sort_row_has_child_toggled (CtkTreeModel *model, | |||
331 | CtkTreePath *path, | |||
332 | CtkTreeIter *iter, | |||
333 | gpointer data); | |||
334 | static void ctk_tree_model_sort_row_deleted (CtkTreeModel *model, | |||
335 | CtkTreePath *path, | |||
336 | gpointer data); | |||
337 | static void ctk_tree_model_sort_rows_reordered (CtkTreeModel *s_model, | |||
338 | CtkTreePath *s_path, | |||
339 | CtkTreeIter *s_iter, | |||
340 | gint *new_order, | |||
341 | gpointer data); | |||
342 | ||||
343 | /* TreeModel interface */ | |||
344 | static CtkTreeModelFlags ctk_tree_model_sort_get_flags (CtkTreeModel *tree_model); | |||
345 | static gint ctk_tree_model_sort_get_n_columns (CtkTreeModel *tree_model); | |||
346 | static GType ctk_tree_model_sort_get_column_type (CtkTreeModel *tree_model, | |||
347 | gint index); | |||
348 | static gboolean ctk_tree_model_sort_get_iter (CtkTreeModel *tree_model, | |||
349 | CtkTreeIter *iter, | |||
350 | CtkTreePath *path); | |||
351 | static CtkTreePath *ctk_tree_model_sort_get_path (CtkTreeModel *tree_model, | |||
352 | CtkTreeIter *iter); | |||
353 | static void ctk_tree_model_sort_get_value (CtkTreeModel *tree_model, | |||
354 | CtkTreeIter *iter, | |||
355 | gint column, | |||
356 | GValue *value); | |||
357 | static gboolean ctk_tree_model_sort_iter_next (CtkTreeModel *tree_model, | |||
358 | CtkTreeIter *iter); | |||
359 | static gboolean ctk_tree_model_sort_iter_previous (CtkTreeModel *tree_model, | |||
360 | CtkTreeIter *iter); | |||
361 | static gboolean ctk_tree_model_sort_iter_children (CtkTreeModel *tree_model, | |||
362 | CtkTreeIter *iter, | |||
363 | CtkTreeIter *parent); | |||
364 | static gboolean ctk_tree_model_sort_iter_has_child (CtkTreeModel *tree_model, | |||
365 | CtkTreeIter *iter); | |||
366 | static gint ctk_tree_model_sort_iter_n_children (CtkTreeModel *tree_model, | |||
367 | CtkTreeIter *iter); | |||
368 | static gboolean ctk_tree_model_sort_iter_nth_child (CtkTreeModel *tree_model, | |||
369 | CtkTreeIter *iter, | |||
370 | CtkTreeIter *parent, | |||
371 | gint n); | |||
372 | static gboolean ctk_tree_model_sort_iter_parent (CtkTreeModel *tree_model, | |||
373 | CtkTreeIter *iter, | |||
374 | CtkTreeIter *child); | |||
375 | static void ctk_tree_model_sort_ref_node (CtkTreeModel *tree_model, | |||
376 | CtkTreeIter *iter); | |||
377 | static void ctk_tree_model_sort_real_unref_node (CtkTreeModel *tree_model, | |||
378 | CtkTreeIter *iter, | |||
379 | gboolean propagate_unref); | |||
380 | static void ctk_tree_model_sort_unref_node (CtkTreeModel *tree_model, | |||
381 | CtkTreeIter *iter); | |||
382 | ||||
383 | /* TreeDragSource interface */ | |||
384 | static gboolean ctk_tree_model_sort_row_draggable (CtkTreeDragSource *drag_source, | |||
385 | CtkTreePath *path); | |||
386 | static gboolean ctk_tree_model_sort_drag_data_get (CtkTreeDragSource *drag_source, | |||
387 | CtkTreePath *path, | |||
388 | CtkSelectionData *selection_data); | |||
389 | static gboolean ctk_tree_model_sort_drag_data_delete (CtkTreeDragSource *drag_source, | |||
390 | CtkTreePath *path); | |||
391 | ||||
392 | /* TreeSortable interface */ | |||
393 | static gboolean ctk_tree_model_sort_get_sort_column_id (CtkTreeSortable *sortable, | |||
394 | gint *sort_column_id, | |||
395 | CtkSortType *order); | |||
396 | static void ctk_tree_model_sort_set_sort_column_id (CtkTreeSortable *sortable, | |||
397 | gint sort_column_id, | |||
398 | CtkSortType order); | |||
399 | static void ctk_tree_model_sort_set_sort_func (CtkTreeSortable *sortable, | |||
400 | gint sort_column_id, | |||
401 | CtkTreeIterCompareFunc func, | |||
402 | gpointer data, | |||
403 | GDestroyNotify destroy); | |||
404 | static void ctk_tree_model_sort_set_default_sort_func (CtkTreeSortable *sortable, | |||
405 | CtkTreeIterCompareFunc func, | |||
406 | gpointer data, | |||
407 | GDestroyNotify destroy); | |||
408 | static gboolean ctk_tree_model_sort_has_default_sort_func (CtkTreeSortable *sortable); | |||
409 | ||||
410 | /* Private functions (sort funcs, level handling and other utils) */ | |||
411 | static void ctk_tree_model_sort_build_level (CtkTreeModelSort *tree_model_sort, | |||
412 | SortLevel *parent_level, | |||
413 | SortElt *parent_elt); | |||
414 | static void ctk_tree_model_sort_free_level (CtkTreeModelSort *tree_model_sort, | |||
415 | SortLevel *sort_level, | |||
416 | gboolean unref); | |||
417 | static void ctk_tree_model_sort_increment_stamp (CtkTreeModelSort *tree_model_sort); | |||
418 | static void ctk_tree_model_sort_sort_level (CtkTreeModelSort *tree_model_sort, | |||
419 | SortLevel *level, | |||
420 | gboolean recurse, | |||
421 | gboolean emit_reordered); | |||
422 | static void ctk_tree_model_sort_sort (CtkTreeModelSort *tree_model_sort); | |||
423 | static gboolean ctk_tree_model_sort_insert_value (CtkTreeModelSort *tree_model_sort, | |||
424 | SortLevel *level, | |||
425 | CtkTreePath *s_path, | |||
426 | CtkTreeIter *s_iter); | |||
427 | static CtkTreePath *ctk_tree_model_sort_elt_get_path (SortLevel *level, | |||
428 | SortElt *elt); | |||
429 | static void ctk_tree_model_sort_set_model (CtkTreeModelSort *tree_model_sort, | |||
430 | CtkTreeModel *child_model); | |||
431 | static CtkTreePath *ctk_real_tree_model_sort_convert_child_path_to_path (CtkTreeModelSort *tree_model_sort, | |||
432 | CtkTreePath *child_path, | |||
433 | gboolean build_levels); | |||
434 | ||||
435 | static gint ctk_tree_model_sort_compare_func (gconstpointer a, | |||
436 | gconstpointer b, | |||
437 | gpointer user_data); | |||
438 | static gint ctk_tree_model_sort_offset_compare_func (gconstpointer a, | |||
439 | gconstpointer b, | |||
440 | gpointer user_data); | |||
441 | static void ctk_tree_model_sort_clear_cache_helper (CtkTreeModelSort *tree_model_sort, | |||
442 | SortLevel *level); | |||
443 | ||||
444 | ||||
445 | G_DEFINE_TYPE_WITH_CODE (CtkTreeModelSort, ctk_tree_model_sort, G_TYPE_OBJECT,static void ctk_tree_model_sort_init (CtkTreeModelSort *self) ; static void ctk_tree_model_sort_class_init (CtkTreeModelSortClass *klass); static GType ctk_tree_model_sort_get_type_once (void ); static gpointer ctk_tree_model_sort_parent_class = ((void* )0); static gint CtkTreeModelSort_private_offset; static void ctk_tree_model_sort_class_intern_init (gpointer klass) { ctk_tree_model_sort_parent_class = g_type_class_peek_parent (klass); if (CtkTreeModelSort_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeModelSort_private_offset ); ctk_tree_model_sort_class_init ((CtkTreeModelSortClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_model_sort_get_instance_private (CtkTreeModelSort *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkTreeModelSort_private_offset)))); } GType ctk_tree_model_sort_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_model_sort_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_model_sort_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkTreeModelSort" ), sizeof (CtkTreeModelSortClass), (GClassInitFunc)(void (*)( void)) ctk_tree_model_sort_class_intern_init, sizeof (CtkTreeModelSort ), (GInstanceInitFunc)(void (*)(void)) ctk_tree_model_sort_init , (GTypeFlags) 0); { {{ CtkTreeModelSort_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeModelSortPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_model_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_model_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_sortable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_sortable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_drag_source_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_drag_source_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
446 | G_ADD_PRIVATE (CtkTreeModelSort)static void ctk_tree_model_sort_init (CtkTreeModelSort *self) ; static void ctk_tree_model_sort_class_init (CtkTreeModelSortClass *klass); static GType ctk_tree_model_sort_get_type_once (void ); static gpointer ctk_tree_model_sort_parent_class = ((void* )0); static gint CtkTreeModelSort_private_offset; static void ctk_tree_model_sort_class_intern_init (gpointer klass) { ctk_tree_model_sort_parent_class = g_type_class_peek_parent (klass); if (CtkTreeModelSort_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeModelSort_private_offset ); ctk_tree_model_sort_class_init ((CtkTreeModelSortClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_model_sort_get_instance_private (CtkTreeModelSort *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkTreeModelSort_private_offset)))); } GType ctk_tree_model_sort_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_model_sort_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_model_sort_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkTreeModelSort" ), sizeof (CtkTreeModelSortClass), (GClassInitFunc)(void (*)( void)) ctk_tree_model_sort_class_intern_init, sizeof (CtkTreeModelSort ), (GInstanceInitFunc)(void (*)(void)) ctk_tree_model_sort_init , (GTypeFlags) 0); { {{ CtkTreeModelSort_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeModelSortPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_model_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_model_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_sortable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_sortable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_drag_source_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_drag_source_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
447 | G_IMPLEMENT_INTERFACE (CTK_TYPE_TREE_MODEL,static void ctk_tree_model_sort_init (CtkTreeModelSort *self) ; static void ctk_tree_model_sort_class_init (CtkTreeModelSortClass *klass); static GType ctk_tree_model_sort_get_type_once (void ); static gpointer ctk_tree_model_sort_parent_class = ((void* )0); static gint CtkTreeModelSort_private_offset; static void ctk_tree_model_sort_class_intern_init (gpointer klass) { ctk_tree_model_sort_parent_class = g_type_class_peek_parent (klass); if (CtkTreeModelSort_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeModelSort_private_offset ); ctk_tree_model_sort_class_init ((CtkTreeModelSortClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_model_sort_get_instance_private (CtkTreeModelSort *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkTreeModelSort_private_offset)))); } GType ctk_tree_model_sort_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_model_sort_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_model_sort_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkTreeModelSort" ), sizeof (CtkTreeModelSortClass), (GClassInitFunc)(void (*)( void)) ctk_tree_model_sort_class_intern_init, sizeof (CtkTreeModelSort ), (GInstanceInitFunc)(void (*)(void)) ctk_tree_model_sort_init , (GTypeFlags) 0); { {{ CtkTreeModelSort_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeModelSortPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_model_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_model_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_sortable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_sortable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_drag_source_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_drag_source_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
448 | ctk_tree_model_sort_tree_model_init)static void ctk_tree_model_sort_init (CtkTreeModelSort *self) ; static void ctk_tree_model_sort_class_init (CtkTreeModelSortClass *klass); static GType ctk_tree_model_sort_get_type_once (void ); static gpointer ctk_tree_model_sort_parent_class = ((void* )0); static gint CtkTreeModelSort_private_offset; static void ctk_tree_model_sort_class_intern_init (gpointer klass) { ctk_tree_model_sort_parent_class = g_type_class_peek_parent (klass); if (CtkTreeModelSort_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeModelSort_private_offset ); ctk_tree_model_sort_class_init ((CtkTreeModelSortClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_model_sort_get_instance_private (CtkTreeModelSort *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkTreeModelSort_private_offset)))); } GType ctk_tree_model_sort_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_model_sort_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_model_sort_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkTreeModelSort" ), sizeof (CtkTreeModelSortClass), (GClassInitFunc)(void (*)( void)) ctk_tree_model_sort_class_intern_init, sizeof (CtkTreeModelSort ), (GInstanceInitFunc)(void (*)(void)) ctk_tree_model_sort_init , (GTypeFlags) 0); { {{ CtkTreeModelSort_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeModelSortPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_model_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_model_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_sortable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_sortable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_drag_source_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_drag_source_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
449 | G_IMPLEMENT_INTERFACE (CTK_TYPE_TREE_SORTABLE,static void ctk_tree_model_sort_init (CtkTreeModelSort *self) ; static void ctk_tree_model_sort_class_init (CtkTreeModelSortClass *klass); static GType ctk_tree_model_sort_get_type_once (void ); static gpointer ctk_tree_model_sort_parent_class = ((void* )0); static gint CtkTreeModelSort_private_offset; static void ctk_tree_model_sort_class_intern_init (gpointer klass) { ctk_tree_model_sort_parent_class = g_type_class_peek_parent (klass); if (CtkTreeModelSort_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeModelSort_private_offset ); ctk_tree_model_sort_class_init ((CtkTreeModelSortClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_model_sort_get_instance_private (CtkTreeModelSort *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkTreeModelSort_private_offset)))); } GType ctk_tree_model_sort_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_model_sort_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_model_sort_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkTreeModelSort" ), sizeof (CtkTreeModelSortClass), (GClassInitFunc)(void (*)( void)) ctk_tree_model_sort_class_intern_init, sizeof (CtkTreeModelSort ), (GInstanceInitFunc)(void (*)(void)) ctk_tree_model_sort_init , (GTypeFlags) 0); { {{ CtkTreeModelSort_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeModelSortPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_model_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_model_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_sortable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_sortable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_drag_source_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_drag_source_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
450 | ctk_tree_model_sort_tree_sortable_init)static void ctk_tree_model_sort_init (CtkTreeModelSort *self) ; static void ctk_tree_model_sort_class_init (CtkTreeModelSortClass *klass); static GType ctk_tree_model_sort_get_type_once (void ); static gpointer ctk_tree_model_sort_parent_class = ((void* )0); static gint CtkTreeModelSort_private_offset; static void ctk_tree_model_sort_class_intern_init (gpointer klass) { ctk_tree_model_sort_parent_class = g_type_class_peek_parent (klass); if (CtkTreeModelSort_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeModelSort_private_offset ); ctk_tree_model_sort_class_init ((CtkTreeModelSortClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_model_sort_get_instance_private (CtkTreeModelSort *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkTreeModelSort_private_offset)))); } GType ctk_tree_model_sort_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_model_sort_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_model_sort_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkTreeModelSort" ), sizeof (CtkTreeModelSortClass), (GClassInitFunc)(void (*)( void)) ctk_tree_model_sort_class_intern_init, sizeof (CtkTreeModelSort ), (GInstanceInitFunc)(void (*)(void)) ctk_tree_model_sort_init , (GTypeFlags) 0); { {{ CtkTreeModelSort_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeModelSortPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_model_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_model_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_sortable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_sortable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_drag_source_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_drag_source_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
451 | G_IMPLEMENT_INTERFACE (CTK_TYPE_TREE_DRAG_SOURCE,static void ctk_tree_model_sort_init (CtkTreeModelSort *self) ; static void ctk_tree_model_sort_class_init (CtkTreeModelSortClass *klass); static GType ctk_tree_model_sort_get_type_once (void ); static gpointer ctk_tree_model_sort_parent_class = ((void* )0); static gint CtkTreeModelSort_private_offset; static void ctk_tree_model_sort_class_intern_init (gpointer klass) { ctk_tree_model_sort_parent_class = g_type_class_peek_parent (klass); if (CtkTreeModelSort_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeModelSort_private_offset ); ctk_tree_model_sort_class_init ((CtkTreeModelSortClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_model_sort_get_instance_private (CtkTreeModelSort *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkTreeModelSort_private_offset)))); } GType ctk_tree_model_sort_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_model_sort_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_model_sort_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkTreeModelSort" ), sizeof (CtkTreeModelSortClass), (GClassInitFunc)(void (*)( void)) ctk_tree_model_sort_class_intern_init, sizeof (CtkTreeModelSort ), (GInstanceInitFunc)(void (*)(void)) ctk_tree_model_sort_init , (GTypeFlags) 0); { {{ CtkTreeModelSort_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeModelSortPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_model_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_model_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_sortable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_sortable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_drag_source_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_drag_source_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
452 | ctk_tree_model_sort_drag_source_init))static void ctk_tree_model_sort_init (CtkTreeModelSort *self) ; static void ctk_tree_model_sort_class_init (CtkTreeModelSortClass *klass); static GType ctk_tree_model_sort_get_type_once (void ); static gpointer ctk_tree_model_sort_parent_class = ((void* )0); static gint CtkTreeModelSort_private_offset; static void ctk_tree_model_sort_class_intern_init (gpointer klass) { ctk_tree_model_sort_parent_class = g_type_class_peek_parent (klass); if (CtkTreeModelSort_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeModelSort_private_offset ); ctk_tree_model_sort_class_init ((CtkTreeModelSortClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_model_sort_get_instance_private (CtkTreeModelSort *self) { return (((gpointer) ((guint8*) (self ) + (glong) (CtkTreeModelSort_private_offset)))); } GType ctk_tree_model_sort_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_model_sort_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_model_sort_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CtkTreeModelSort" ), sizeof (CtkTreeModelSortClass), (GClassInitFunc)(void (*)( void)) ctk_tree_model_sort_class_intern_init, sizeof (CtkTreeModelSort ), (GInstanceInitFunc)(void (*)(void)) ctk_tree_model_sort_init , (GTypeFlags) 0); { {{ CtkTreeModelSort_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeModelSortPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_model_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_model_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_tree_sortable_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_sortable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_model_sort_drag_source_init, ((void *)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_tree_drag_source_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
453 | ||||
454 | static void | |||
455 | ctk_tree_model_sort_init (CtkTreeModelSort *tree_model_sort) | |||
456 | { | |||
457 | CtkTreeModelSortPrivate *priv; | |||
458 | ||||
459 | tree_model_sort->priv = priv = | |||
460 | ctk_tree_model_sort_get_instance_private (tree_model_sort); | |||
461 | priv->sort_column_id = CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1); | |||
462 | priv->stamp = 0; | |||
463 | priv->zero_ref_count = 0; | |||
464 | priv->root = NULL((void*)0); | |||
465 | priv->sort_list = NULL((void*)0); | |||
466 | } | |||
467 | ||||
468 | static void | |||
469 | ctk_tree_model_sort_class_init (CtkTreeModelSortClass *class) | |||
470 | { | |||
471 | GObjectClass *object_class; | |||
472 | ||||
473 | object_class = (GObjectClass *) class; | |||
474 | ||||
475 | object_class->set_property = ctk_tree_model_sort_set_property; | |||
476 | object_class->get_property = ctk_tree_model_sort_get_property; | |||
477 | ||||
478 | object_class->finalize = ctk_tree_model_sort_finalize; | |||
479 | ||||
480 | /* Properties */ | |||
481 | g_object_class_install_property (object_class, | |||
482 | PROP_MODEL, | |||
483 | g_param_spec_object ("model", | |||
484 | P_("TreeModelSort Model")g_dgettext("ctk30" "-properties","TreeModelSort Model"), | |||
485 | P_("The model for the TreeModelSort to sort")g_dgettext("ctk30" "-properties","The model for the TreeModelSort to sort" ), | |||
486 | CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()), | |||
487 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY)); | |||
488 | } | |||
489 | ||||
490 | static void | |||
491 | ctk_tree_model_sort_tree_model_init (CtkTreeModelIface *iface) | |||
492 | { | |||
493 | iface->get_flags = ctk_tree_model_sort_get_flags; | |||
494 | iface->get_n_columns = ctk_tree_model_sort_get_n_columns; | |||
495 | iface->get_column_type = ctk_tree_model_sort_get_column_type; | |||
496 | iface->get_iter = ctk_tree_model_sort_get_iter; | |||
497 | iface->get_path = ctk_tree_model_sort_get_path; | |||
498 | iface->get_value = ctk_tree_model_sort_get_value; | |||
499 | iface->iter_next = ctk_tree_model_sort_iter_next; | |||
500 | iface->iter_previous = ctk_tree_model_sort_iter_previous; | |||
501 | iface->iter_children = ctk_tree_model_sort_iter_children; | |||
502 | iface->iter_has_child = ctk_tree_model_sort_iter_has_child; | |||
503 | iface->iter_n_children = ctk_tree_model_sort_iter_n_children; | |||
504 | iface->iter_nth_child = ctk_tree_model_sort_iter_nth_child; | |||
505 | iface->iter_parent = ctk_tree_model_sort_iter_parent; | |||
506 | iface->ref_node = ctk_tree_model_sort_ref_node; | |||
507 | iface->unref_node = ctk_tree_model_sort_unref_node; | |||
508 | } | |||
509 | ||||
510 | static void | |||
511 | ctk_tree_model_sort_tree_sortable_init (CtkTreeSortableIface *iface) | |||
512 | { | |||
513 | iface->get_sort_column_id = ctk_tree_model_sort_get_sort_column_id; | |||
514 | iface->set_sort_column_id = ctk_tree_model_sort_set_sort_column_id; | |||
515 | iface->set_sort_func = ctk_tree_model_sort_set_sort_func; | |||
516 | iface->set_default_sort_func = ctk_tree_model_sort_set_default_sort_func; | |||
517 | iface->has_default_sort_func = ctk_tree_model_sort_has_default_sort_func; | |||
518 | } | |||
519 | ||||
520 | static void | |||
521 | ctk_tree_model_sort_drag_source_init (CtkTreeDragSourceIface *iface) | |||
522 | { | |||
523 | iface->row_draggable = ctk_tree_model_sort_row_draggable; | |||
524 | iface->drag_data_delete = ctk_tree_model_sort_drag_data_delete; | |||
525 | iface->drag_data_get = ctk_tree_model_sort_drag_data_get; | |||
526 | } | |||
527 | ||||
528 | /** | |||
529 | * ctk_tree_model_sort_new_with_model: (constructor) | |||
530 | * @child_model: A #CtkTreeModel | |||
531 | * | |||
532 | * Creates a new #CtkTreeModelSort, with @child_model as the child model. | |||
533 | * | |||
534 | * Returns: (transfer full) (type Ctk.TreeModelSort): A new #CtkTreeModelSort. | |||
535 | */ | |||
536 | CtkTreeModel * | |||
537 | ctk_tree_model_sort_new_with_model (CtkTreeModel *child_model) | |||
538 | { | |||
539 | CtkTreeModel *retval; | |||
540 | ||||
541 | g_return_val_if_fail (CTK_IS_TREE_MODEL (child_model), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((child_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 (child_model)"); return (((void*)0)); } } while (0); | |||
542 | ||||
543 | retval = g_object_new (ctk_tree_model_sort_get_type (), NULL((void*)0)); | |||
544 | ||||
545 | ctk_tree_model_sort_set_model (CTK_TREE_MODEL_SORT (retval)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((retval)), ((ctk_tree_model_sort_get_type () )))))), child_model); | |||
546 | ||||
547 | return retval; | |||
548 | } | |||
549 | ||||
550 | /* GObject callbacks */ | |||
551 | static void | |||
552 | ctk_tree_model_sort_finalize (GObject *object) | |||
553 | { | |||
554 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) object; | |||
555 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
556 | ||||
557 | ctk_tree_model_sort_set_model (tree_model_sort, NULL((void*)0)); | |||
558 | ||||
559 | if (priv->root) | |||
560 | ctk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE(!(0))); | |||
561 | ||||
562 | if (priv->sort_list) | |||
563 | { | |||
564 | _ctk_tree_data_list_header_free (priv->sort_list); | |||
565 | priv->sort_list = NULL((void*)0); | |||
566 | } | |||
567 | ||||
568 | if (priv->default_sort_destroy) | |||
569 | { | |||
570 | priv->default_sort_destroy (priv->default_sort_data); | |||
571 | priv->default_sort_destroy = NULL((void*)0); | |||
572 | priv->default_sort_data = NULL((void*)0); | |||
573 | } | |||
574 | ||||
575 | ||||
576 | /* must chain up */ | |||
577 | G_OBJECT_CLASS (ctk_tree_model_sort_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_model_sort_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); | |||
578 | } | |||
579 | ||||
580 | static void | |||
581 | ctk_tree_model_sort_set_property (GObject *object, | |||
582 | guint prop_id, | |||
583 | const GValue *value, | |||
584 | GParamSpec *pspec) | |||
585 | { | |||
586 | CtkTreeModelSort *tree_model_sort = CTK_TREE_MODEL_SORT (object)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((object)), ((ctk_tree_model_sort_get_type () )))))); | |||
587 | ||||
588 | switch (prop_id) | |||
| ||||
589 | { | |||
590 | case PROP_MODEL: | |||
591 | ctk_tree_model_sort_set_model (tree_model_sort, g_value_get_object (value)); | |||
592 | break; | |||
593 | default: | |||
594 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctktreemodelsort.c", 594, ("property"), _glib__property_id , _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance *) (_glib__pspec))->g_class))->g_type)))), (g_type_name ((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
595 | break; | |||
596 | } | |||
597 | } | |||
598 | ||||
599 | static void | |||
600 | ctk_tree_model_sort_get_property (GObject *object, | |||
601 | guint prop_id, | |||
602 | GValue *value, | |||
603 | GParamSpec *pspec) | |||
604 | { | |||
605 | CtkTreeModelSort *tree_model_sort = CTK_TREE_MODEL_SORT (object)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((object)), ((ctk_tree_model_sort_get_type () )))))); | |||
606 | ||||
607 | switch (prop_id) | |||
608 | { | |||
609 | case PROP_MODEL: | |||
610 | g_value_set_object (value, ctk_tree_model_sort_get_model (tree_model_sort)); | |||
611 | break; | |||
612 | default: | |||
613 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctktreemodelsort.c", 613, ("property"), _glib__property_id , _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance *) (_glib__pspec))->g_class))->g_type)))), (g_type_name ((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
614 | break; | |||
615 | } | |||
616 | } | |||
617 | ||||
618 | /* helpers */ | |||
619 | static SortElt * | |||
620 | sort_elt_new (void) | |||
621 | { | |||
622 | return g_slice_new (SortElt)((SortElt*) g_slice_alloc (sizeof (SortElt))); | |||
623 | } | |||
624 | ||||
625 | static void | |||
626 | sort_elt_free (gpointer elt) | |||
627 | { | |||
628 | g_slice_free (SortElt, elt)do { if (1) g_slice_free1 (sizeof (SortElt), (elt)); else (void ) ((SortElt*) 0 == (elt)); } while (0); | |||
629 | } | |||
630 | ||||
631 | static void | |||
632 | increase_offset_iter (gpointer data, | |||
633 | gpointer user_data) | |||
634 | { | |||
635 | SortElt *elt = data; | |||
636 | gint offset = GPOINTER_TO_INT (user_data)((gint) (glong) (user_data)); | |||
637 | ||||
638 | if (elt->offset >= offset) | |||
639 | elt->offset++; | |||
640 | } | |||
641 | ||||
642 | static void | |||
643 | decrease_offset_iter (gpointer data, | |||
644 | gpointer user_data) | |||
645 | { | |||
646 | SortElt *elt = data; | |||
647 | gint offset = GPOINTER_TO_INT (user_data)((gint) (glong) (user_data)); | |||
648 | ||||
649 | if (elt->offset > offset) | |||
650 | elt->offset--; | |||
651 | } | |||
652 | ||||
653 | static void | |||
654 | fill_sort_data (SortData *data, | |||
655 | CtkTreeModelSort *tree_model_sort, | |||
656 | SortLevel *level) | |||
657 | { | |||
658 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
659 | ||||
660 | data->tree_model_sort = tree_model_sort; | |||
661 | ||||
662 | if (priv->sort_column_id != CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1)) | |||
663 | { | |||
664 | CtkTreeDataSortHeader *header; | |||
665 | ||||
666 | header = _ctk_tree_data_list_get_header (priv->sort_list, | |||
667 | priv->sort_column_id); | |||
668 | ||||
669 | g_return_if_fail (header != NULL)do { if ((header != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "header != NULL"); return ; } } while (0); | |||
670 | g_return_if_fail (header->func != NULL)do { if ((header->func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "header->func != NULL" ); return; } } while (0); | |||
671 | ||||
672 | data->sort_func = header->func; | |||
673 | data->sort_data = header->data; | |||
674 | } | |||
675 | else | |||
676 | { | |||
677 | /* absolutely SHOULD NOT happen: */ | |||
678 | g_return_if_fail (priv->default_sort_func != NULL)do { if ((priv->default_sort_func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "priv->default_sort_func != NULL"); return; } } while ( 0); | |||
679 | ||||
680 | data->sort_func = priv->default_sort_func; | |||
681 | data->sort_data = priv->default_sort_data; | |||
682 | } | |||
683 | ||||
684 | if (level->parent_elt) | |||
685 | { | |||
686 | data->parent_path = ctk_tree_model_sort_elt_get_path (level->parent_level, | |||
687 | level->parent_elt); | |||
688 | ctk_tree_path_append_index (data->parent_path, 0); | |||
689 | } | |||
690 | else | |||
691 | { | |||
692 | data->parent_path = ctk_tree_path_new_first (); | |||
693 | } | |||
694 | data->parent_path_depth = ctk_tree_path_get_depth (data->parent_path); | |||
695 | data->parent_path_indices = ctk_tree_path_get_indices (data->parent_path); | |||
696 | } | |||
697 | ||||
698 | static void | |||
699 | free_sort_data (SortData *data) | |||
700 | { | |||
701 | ctk_tree_path_free (data->parent_path); | |||
702 | } | |||
703 | ||||
704 | static SortElt * | |||
705 | lookup_elt_with_offset (CtkTreeModelSort *tree_model_sort G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
706 | SortLevel *level, | |||
707 | gint offset, | |||
708 | GSequenceIter **ret_siter) | |||
709 | { | |||
710 | GSequenceIter *siter, *end_siter; | |||
711 | ||||
712 | /* FIXME: We have to do a search like this, because the sequence is not | |||
713 | * (always) sorted on offset order. Perhaps we should introduce a | |||
714 | * second sequence which is sorted on offset order. | |||
715 | */ | |||
716 | end_siter = g_sequence_get_end_iter (level->seq); | |||
717 | for (siter = g_sequence_get_begin_iter (level->seq); | |||
718 | siter != end_siter; | |||
719 | siter = g_sequence_iter_next (siter)) | |||
720 | { | |||
721 | SortElt *elt = g_sequence_get (siter); | |||
722 | ||||
723 | if (elt->offset == offset) | |||
724 | break; | |||
725 | } | |||
726 | ||||
727 | if (ret_siter) | |||
728 | *ret_siter = siter; | |||
729 | ||||
730 | return GET_ELT (siter)((SortElt *) (siter ? g_sequence_get (siter) : ((void*)0))); | |||
731 | } | |||
732 | ||||
733 | ||||
734 | static void | |||
735 | ctk_tree_model_sort_row_changed (CtkTreeModel *s_model, | |||
736 | CtkTreePath *start_s_path, | |||
737 | CtkTreeIter *start_s_iter, | |||
738 | gpointer data) | |||
739 | { | |||
740 | CtkTreeModelSort *tree_model_sort = CTK_TREE_MODEL_SORT (data)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((data)), ((ctk_tree_model_sort_get_type ())) )))); | |||
741 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
742 | CtkTreePath *path = NULL((void*)0); | |||
743 | CtkTreeIter iter; | |||
744 | CtkTreeIter tmpiter; | |||
745 | ||||
746 | SortElt *elt; | |||
747 | SortLevel *level; | |||
748 | SortData sort_data; | |||
749 | ||||
750 | gboolean free_s_path = FALSE(0); | |||
751 | ||||
752 | gint index = 0, old_index; | |||
753 | ||||
754 | g_return_if_fail (start_s_path != NULL || start_s_iter != NULL)do { if ((start_s_path != ((void*)0) || start_s_iter != ((void *)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "start_s_path != NULL || start_s_iter != NULL" ); return; } } while (0); | |||
755 | ||||
756 | if (!start_s_path) | |||
757 | { | |||
758 | free_s_path = TRUE(!(0)); | |||
759 | start_s_path = ctk_tree_model_get_path (s_model, start_s_iter); | |||
760 | } | |||
761 | ||||
762 | path = ctk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, | |||
763 | start_s_path, | |||
764 | FALSE(0)); | |||
765 | if (!path) | |||
766 | { | |||
767 | if (free_s_path) | |||
768 | ctk_tree_path_free (start_s_path); | |||
769 | return; | |||
770 | } | |||
771 | ||||
772 | ctk_tree_model_get_iter (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter, path); | |||
773 | ctk_tree_model_sort_ref_node (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter); | |||
774 | ||||
775 | level = iter.user_data; | |||
776 | elt = iter.user_data2; | |||
777 | ||||
778 | if (g_sequence_get_length (level->seq) < 2 || | |||
779 | (priv->sort_column_id == CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1) && | |||
780 | priv->default_sort_func == NO_SORT_FUNC((CtkTreeIterCompareFunc) 0x1))) | |||
781 | { | |||
782 | if (free_s_path) | |||
783 | ctk_tree_path_free (start_s_path); | |||
784 | ||||
785 | ctk_tree_model_row_changed (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), path, &iter); | |||
786 | ctk_tree_model_sort_unref_node (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter); | |||
787 | ||||
788 | ctk_tree_path_free (path); | |||
789 | ||||
790 | return; | |||
791 | } | |||
792 | ||||
793 | if (CTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort)(((CtkTreeModelSort *)tree_model_sort)->priv->child_flags &CTK_TREE_MODEL_ITERS_PERSIST)) | |||
794 | tmpiter = elt->iter; | |||
795 | else | |||
796 | ctk_tree_model_get_iter (priv->child_model, | |||
797 | &tmpiter, start_s_path); | |||
798 | ||||
799 | old_index = g_sequence_iter_get_position (elt->siter); | |||
800 | ||||
801 | fill_sort_data (&sort_data, tree_model_sort, level); | |||
802 | g_sequence_sort_changed (elt->siter, | |||
803 | ctk_tree_model_sort_compare_func, | |||
804 | &sort_data); | |||
805 | free_sort_data (&sort_data); | |||
806 | ||||
807 | index = g_sequence_iter_get_position (elt->siter); | |||
808 | ||||
809 | /* Prepare the path for signal emission */ | |||
810 | ctk_tree_path_up (path); | |||
811 | ctk_tree_path_append_index (path, index); | |||
812 | ||||
813 | ctk_tree_model_sort_increment_stamp (tree_model_sort); | |||
814 | ||||
815 | /* if the item moved, then emit rows_reordered */ | |||
816 | if (old_index != index) | |||
817 | { | |||
818 | gint *new_order; | |||
819 | gint j; | |||
820 | ||||
821 | CtkTreePath *tmppath; | |||
822 | ||||
823 | new_order = g_new (gint, g_sequence_get_length (level->seq))((gint *) g_malloc_n ((g_sequence_get_length (level->seq)) , sizeof (gint))); | |||
824 | ||||
825 | for (j = 0; j < g_sequence_get_length (level->seq); j++) | |||
826 | { | |||
827 | if (index > old_index) | |||
828 | { | |||
829 | if (j == index) | |||
830 | new_order[j] = old_index; | |||
831 | else if (j >= old_index && j < index) | |||
832 | new_order[j] = j + 1; | |||
833 | else | |||
834 | new_order[j] = j; | |||
835 | } | |||
836 | else if (index < old_index) | |||
837 | { | |||
838 | if (j == index) | |||
839 | new_order[j] = old_index; | |||
840 | else if (j > index && j <= old_index) | |||
841 | new_order[j] = j - 1; | |||
842 | else | |||
843 | new_order[j] = j; | |||
844 | } | |||
845 | /* else? shouldn't really happen */ | |||
846 | } | |||
847 | ||||
848 | if (level->parent_elt) | |||
849 | { | |||
850 | iter.stamp = priv->stamp; | |||
851 | iter.user_data = level->parent_level; | |||
852 | iter.user_data2 = level->parent_elt; | |||
853 | ||||
854 | tmppath = ctk_tree_model_get_path (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), &iter); | |||
855 | ||||
856 | ctk_tree_model_rows_reordered (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), | |||
857 | tmppath, &iter, new_order); | |||
858 | } | |||
859 | else | |||
860 | { | |||
861 | /* toplevel */ | |||
862 | tmppath = ctk_tree_path_new (); | |||
863 | ||||
864 | ctk_tree_model_rows_reordered (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), tmppath, | |||
865 | NULL((void*)0), new_order); | |||
866 | } | |||
867 | ||||
868 | ctk_tree_path_free (tmppath); | |||
869 | g_free (new_order); | |||
870 | } | |||
871 | ||||
872 | /* emit row_changed signal (at new location) */ | |||
873 | ctk_tree_model_get_iter (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter, path); | |||
874 | ctk_tree_model_row_changed (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), path, &iter); | |||
875 | ctk_tree_model_sort_unref_node (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter); | |||
876 | ||||
877 | ctk_tree_path_free (path); | |||
878 | if (free_s_path) | |||
879 | ctk_tree_path_free (start_s_path); | |||
880 | } | |||
881 | ||||
882 | static void | |||
883 | ctk_tree_model_sort_row_inserted (CtkTreeModel *s_model, | |||
884 | CtkTreePath *s_path, | |||
885 | CtkTreeIter *s_iter, | |||
886 | gpointer data) | |||
887 | { | |||
888 | CtkTreeModelSort *tree_model_sort = CTK_TREE_MODEL_SORT (data)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((data)), ((ctk_tree_model_sort_get_type ())) )))); | |||
889 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
890 | CtkTreePath *path; | |||
891 | CtkTreeIter iter; | |||
892 | CtkTreeIter real_s_iter; | |||
893 | ||||
894 | gint i = 0; | |||
895 | ||||
896 | gboolean free_s_path = FALSE(0); | |||
897 | ||||
898 | SortElt *elt; | |||
899 | SortLevel *level; | |||
900 | SortLevel *parent_level = NULL((void*)0); | |||
901 | ||||
902 | parent_level = level = SORT_LEVEL (priv->root)((SortLevel *)priv->root); | |||
903 | ||||
904 | g_return_if_fail (s_path != NULL || s_iter != NULL)do { if ((s_path != ((void*)0) || s_iter != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "s_path != NULL || s_iter != NULL"); return; } } while (0); | |||
905 | ||||
906 | if (!s_path) | |||
907 | { | |||
908 | s_path = ctk_tree_model_get_path (s_model, s_iter); | |||
909 | free_s_path = TRUE(!(0)); | |||
910 | } | |||
911 | ||||
912 | if (!s_iter) | |||
913 | ctk_tree_model_get_iter (s_model, &real_s_iter, s_path); | |||
914 | else | |||
915 | real_s_iter = *s_iter; | |||
916 | ||||
917 | if (!priv->root) | |||
918 | { | |||
919 | ctk_tree_model_sort_build_level (tree_model_sort, NULL((void*)0), NULL((void*)0)); | |||
920 | ||||
921 | /* the build level already put the inserted iter in the level, | |||
922 | so no need to handle this signal anymore */ | |||
923 | ||||
924 | goto done_and_submit; | |||
925 | } | |||
926 | ||||
927 | /* find the parent level */ | |||
928 | while (i < ctk_tree_path_get_depth (s_path) - 1) | |||
929 | { | |||
930 | if (!level) | |||
931 | { | |||
932 | /* level not yet build, we won't cover this signal */ | |||
933 | goto done; | |||
934 | } | |||
935 | ||||
936 | if (g_sequence_get_length (level->seq) < ctk_tree_path_get_indices (s_path)[i]) | |||
937 | { | |||
938 | g_warning ("%s: A node was inserted with a parent that's not in the tree.\n" | |||
939 | "This possibly means that a CtkTreeModel inserted a child node\n" | |||
940 | "before the parent was inserted.", | |||
941 | G_STRLOC"ctktreemodelsort.c" ":" "941"); | |||
942 | goto done; | |||
943 | } | |||
944 | ||||
945 | elt = lookup_elt_with_offset (tree_model_sort, level, | |||
946 | ctk_tree_path_get_indices (s_path)[i], | |||
947 | NULL((void*)0)); | |||
948 | ||||
949 | g_return_if_fail (elt != NULL)do { if ((elt != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "elt != NULL"); return; } } while (0); | |||
950 | ||||
951 | if (!elt->children) | |||
952 | { | |||
953 | /* not covering this signal */ | |||
954 | goto done; | |||
955 | } | |||
956 | ||||
957 | level = elt->children; | |||
958 | parent_level = level; | |||
959 | i++; | |||
960 | } | |||
961 | ||||
962 | if (!parent_level) | |||
963 | goto done; | |||
964 | ||||
965 | if (level->ref_count == 0 && level != priv->root) | |||
966 | { | |||
967 | ctk_tree_model_sort_free_level (tree_model_sort, level, TRUE(!(0))); | |||
968 | goto done; | |||
969 | } | |||
970 | ||||
971 | if (!ctk_tree_model_sort_insert_value (tree_model_sort, | |||
972 | parent_level, | |||
973 | s_path, | |||
974 | &real_s_iter)) | |||
975 | goto done; | |||
976 | ||||
977 | done_and_submit: | |||
978 | path = ctk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, | |||
979 | s_path, | |||
980 | FALSE(0)); | |||
981 | ||||
982 | if (!path) | |||
983 | return; | |||
984 | ||||
985 | ctk_tree_model_sort_increment_stamp (tree_model_sort); | |||
986 | ||||
987 | ctk_tree_model_get_iter (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter, path); | |||
988 | ctk_tree_model_row_inserted (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), path, &iter); | |||
989 | ctk_tree_path_free (path); | |||
990 | ||||
991 | done: | |||
992 | if (free_s_path) | |||
993 | ctk_tree_path_free (s_path); | |||
994 | ||||
995 | return; | |||
996 | } | |||
997 | ||||
998 | static void | |||
999 | ctk_tree_model_sort_row_has_child_toggled (CtkTreeModel *s_model G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1000 | CtkTreePath *s_path, | |||
1001 | CtkTreeIter *s_iter, | |||
1002 | gpointer data) | |||
1003 | { | |||
1004 | CtkTreeModelSort *tree_model_sort = CTK_TREE_MODEL_SORT (data)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((data)), ((ctk_tree_model_sort_get_type ())) )))); | |||
1005 | CtkTreePath *path; | |||
1006 | CtkTreeIter iter; | |||
1007 | ||||
1008 | g_return_if_fail (s_path != NULL && s_iter != NULL)do { if ((s_path != ((void*)0) && s_iter != ((void*)0 ))) { } else { g_return_if_fail_warning ("Ctk", ((const char* ) (__func__)), "s_path != NULL && s_iter != NULL"); return ; } } while (0); | |||
1009 | ||||
1010 | path = ctk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE(0)); | |||
1011 | if (path == NULL((void*)0)) | |||
1012 | return; | |||
1013 | ||||
1014 | ctk_tree_model_get_iter (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter, path); | |||
1015 | ctk_tree_model_row_has_child_toggled (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), path, &iter); | |||
1016 | ||||
1017 | ctk_tree_path_free (path); | |||
1018 | } | |||
1019 | ||||
1020 | static void | |||
1021 | ctk_tree_model_sort_row_deleted (CtkTreeModel *s_model G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1022 | CtkTreePath *s_path, | |||
1023 | gpointer data) | |||
1024 | { | |||
1025 | CtkTreeModelSort *tree_model_sort = CTK_TREE_MODEL_SORT (data)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((data)), ((ctk_tree_model_sort_get_type ())) )))); | |||
1026 | CtkTreePath *path = NULL((void*)0); | |||
1027 | SortElt *elt; | |||
1028 | SortLevel *level; | |||
1029 | CtkTreeIter iter; | |||
1030 | gint offset; | |||
1031 | ||||
1032 | g_return_if_fail (s_path != NULL)do { if ((s_path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "s_path != NULL"); return ; } } while (0); | |||
1033 | ||||
1034 | path = ctk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE(0)); | |||
1035 | if (path == NULL((void*)0)) | |||
1036 | return; | |||
1037 | ||||
1038 | ctk_tree_model_get_iter (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter, path); | |||
1039 | ||||
1040 | level = SORT_LEVEL (iter.user_data)((SortLevel *)iter.user_data); | |||
1041 | elt = SORT_ELT (iter.user_data2)((SortElt *)iter.user_data2); | |||
1042 | offset = elt->offset; | |||
1043 | ||||
1044 | ctk_tree_model_get_iter (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter, path); | |||
1045 | ||||
1046 | while (elt->ref_count > 0) | |||
1047 | ctk_tree_model_sort_real_unref_node (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter, FALSE(0)); | |||
1048 | ||||
1049 | /* If this node has children, we free the level (recursively) here | |||
1050 | * and specify that unref may not be used, because parent and its | |||
1051 | * children have been removed by now. | |||
1052 | */ | |||
1053 | if (elt->children) | |||
1054 | ctk_tree_model_sort_free_level (tree_model_sort, | |||
1055 | elt->children, FALSE(0)); | |||
1056 | ||||
1057 | if (level->ref_count == 0 && g_sequence_get_length (level->seq) == 1) | |||
1058 | { | |||
1059 | ctk_tree_model_sort_increment_stamp (tree_model_sort); | |||
1060 | ctk_tree_model_row_deleted (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), path); | |||
1061 | ctk_tree_path_free (path); | |||
1062 | ||||
1063 | if (level == tree_model_sort->priv->root) | |||
1064 | { | |||
1065 | ctk_tree_model_sort_free_level (tree_model_sort, | |||
1066 | tree_model_sort->priv->root, | |||
1067 | TRUE(!(0))); | |||
1068 | tree_model_sort->priv->root = NULL((void*)0); | |||
1069 | } | |||
1070 | return; | |||
1071 | } | |||
1072 | ||||
1073 | g_sequence_remove (elt->siter); | |||
1074 | elt = NULL((void*)0); | |||
1075 | ||||
1076 | /* The sequence is not ordered on offset, so we traverse the entire | |||
1077 | * sequence. | |||
1078 | */ | |||
1079 | g_sequence_foreach (level->seq, decrease_offset_iter, | |||
1080 | GINT_TO_POINTER (offset)((gpointer) (glong) (offset))); | |||
1081 | ||||
1082 | ctk_tree_model_sort_increment_stamp (tree_model_sort); | |||
1083 | ctk_tree_model_row_deleted (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), path); | |||
1084 | ||||
1085 | ctk_tree_path_free (path); | |||
1086 | } | |||
1087 | ||||
1088 | static void | |||
1089 | ctk_tree_model_sort_rows_reordered (CtkTreeModel *s_model G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1090 | CtkTreePath *s_path, | |||
1091 | CtkTreeIter *s_iter G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1092 | gint *new_order, | |||
1093 | gpointer data) | |||
1094 | { | |||
1095 | SortLevel *level; | |||
1096 | CtkTreeIter iter; | |||
1097 | CtkTreePath *path; | |||
1098 | gint *tmp_array; | |||
1099 | int i, length; | |||
1100 | GSequenceIter *siter, *end_siter; | |||
1101 | CtkTreeModelSort *tree_model_sort = CTK_TREE_MODEL_SORT (data)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((data)), ((ctk_tree_model_sort_get_type ())) )))); | |||
1102 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1103 | ||||
1104 | 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); | |||
1105 | ||||
1106 | if (s_path == NULL((void*)0) || ctk_tree_path_get_depth (s_path) == 0) | |||
1107 | { | |||
1108 | if (priv->root == NULL((void*)0)) | |||
1109 | return; | |||
1110 | path = ctk_tree_path_new (); | |||
1111 | level = SORT_LEVEL (priv->root)((SortLevel *)priv->root); | |||
1112 | } | |||
1113 | else | |||
1114 | { | |||
1115 | SortElt *elt; | |||
1116 | ||||
1117 | path = ctk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE(0)); | |||
1118 | if (path == NULL((void*)0)) | |||
1119 | return; | |||
1120 | ctk_tree_model_get_iter (CTK_TREE_MODEL (data)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_model_get_type ())))))), &iter, path); | |||
1121 | ||||
1122 | elt = SORT_ELT (iter.user_data2)((SortElt *)iter.user_data2); | |||
1123 | ||||
1124 | if (!elt->children) | |||
1125 | { | |||
1126 | ctk_tree_path_free (path); | |||
1127 | return; | |||
1128 | } | |||
1129 | ||||
1130 | level = elt->children; | |||
1131 | } | |||
1132 | ||||
1133 | length = g_sequence_get_length (level->seq); | |||
1134 | if (length < 2) | |||
1135 | { | |||
1136 | ctk_tree_path_free (path); | |||
1137 | return; | |||
1138 | } | |||
1139 | ||||
1140 | tmp_array = g_new (int, length)((int *) g_malloc_n ((length), sizeof (int))); | |||
1141 | ||||
1142 | /* FIXME: I need to think about whether this can be done in a more | |||
1143 | * efficient way? | |||
1144 | */ | |||
1145 | i = 0; | |||
1146 | end_siter = g_sequence_get_end_iter (level->seq); | |||
1147 | for (siter = g_sequence_get_begin_iter (level->seq); | |||
1148 | siter != end_siter; | |||
1149 | siter = g_sequence_iter_next (siter)) | |||
1150 | { | |||
1151 | gint j; | |||
1152 | SortElt *elt = g_sequence_get (siter); | |||
1153 | ||||
1154 | for (j = 0; j < length; j++) | |||
1155 | { | |||
1156 | if (elt->offset == new_order[j]) | |||
1157 | tmp_array[i] = j; | |||
1158 | } | |||
1159 | ||||
1160 | i++; | |||
1161 | } | |||
1162 | ||||
1163 | /* This loop cannot be merged with the above loop nest, because that | |||
1164 | * would introduce duplicate offsets. | |||
1165 | */ | |||
1166 | i = 0; | |||
1167 | end_siter = g_sequence_get_end_iter (level->seq); | |||
1168 | for (siter = g_sequence_get_begin_iter (level->seq); | |||
1169 | siter != end_siter; | |||
1170 | siter = g_sequence_iter_next (siter)) | |||
1171 | { | |||
1172 | SortElt *elt = g_sequence_get (siter); | |||
1173 | ||||
1174 | elt->offset = tmp_array[i]; | |||
1175 | i++; | |||
1176 | } | |||
1177 | g_free (tmp_array); | |||
1178 | ||||
1179 | if (priv->sort_column_id == CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1) && | |||
1180 | priv->default_sort_func == NO_SORT_FUNC((CtkTreeIterCompareFunc) 0x1)) | |||
1181 | { | |||
1182 | ctk_tree_model_sort_sort_level (tree_model_sort, level, | |||
1183 | FALSE(0), FALSE(0)); | |||
1184 | ctk_tree_model_sort_increment_stamp (tree_model_sort); | |||
1185 | ||||
1186 | if (ctk_tree_path_get_depth (path)) | |||
1187 | { | |||
1188 | ctk_tree_model_get_iter (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), | |||
1189 | &iter, | |||
1190 | path); | |||
1191 | ctk_tree_model_rows_reordered (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), | |||
1192 | path, &iter, new_order); | |||
1193 | } | |||
1194 | else | |||
1195 | { | |||
1196 | ctk_tree_model_rows_reordered (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), | |||
1197 | path, NULL((void*)0), new_order); | |||
1198 | } | |||
1199 | } | |||
1200 | ||||
1201 | ctk_tree_path_free (path); | |||
1202 | } | |||
1203 | ||||
1204 | /* Fulfill our model requirements */ | |||
1205 | static CtkTreeModelFlags | |||
1206 | ctk_tree_model_sort_get_flags (CtkTreeModel *tree_model) | |||
1207 | { | |||
1208 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1209 | CtkTreeModelFlags flags; | |||
1210 | ||||
1211 | g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, 0)do { if ((tree_model_sort->priv->child_model != ((void* )0))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "tree_model_sort->priv->child_model != NULL" ); return (0); } } while (0); | |||
1212 | ||||
1213 | flags = ctk_tree_model_get_flags (tree_model_sort->priv->child_model); | |||
1214 | ||||
1215 | if ((flags & CTK_TREE_MODEL_LIST_ONLY) == CTK_TREE_MODEL_LIST_ONLY) | |||
1216 | return CTK_TREE_MODEL_LIST_ONLY; | |||
1217 | ||||
1218 | return 0; | |||
1219 | } | |||
1220 | ||||
1221 | static gint | |||
1222 | ctk_tree_model_sort_get_n_columns (CtkTreeModel *tree_model) | |||
1223 | { | |||
1224 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1225 | ||||
1226 | if (tree_model_sort->priv->child_model == 0) | |||
1227 | return 0; | |||
1228 | ||||
1229 | return ctk_tree_model_get_n_columns (tree_model_sort->priv->child_model); | |||
1230 | } | |||
1231 | ||||
1232 | static GType | |||
1233 | ctk_tree_model_sort_get_column_type (CtkTreeModel *tree_model, | |||
1234 | gint index) | |||
1235 | { | |||
1236 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1237 | ||||
1238 | g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, G_TYPE_INVALID)do { if ((tree_model_sort->priv->child_model != ((void* )0))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "tree_model_sort->priv->child_model != NULL" ); return (((GType) ((0) << (2)))); } } while (0); | |||
1239 | ||||
1240 | return ctk_tree_model_get_column_type (tree_model_sort->priv->child_model, index); | |||
1241 | } | |||
1242 | ||||
1243 | static gboolean | |||
1244 | ctk_tree_model_sort_get_iter (CtkTreeModel *tree_model, | |||
1245 | CtkTreeIter *iter, | |||
1246 | CtkTreePath *path) | |||
1247 | { | |||
1248 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1249 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1250 | gint *indices; | |||
1251 | SortElt *elt; | |||
1252 | SortLevel *level; | |||
1253 | gint depth, i; | |||
1254 | GSequenceIter *siter; | |||
1255 | ||||
1256 | g_return_val_if_fail (priv->child_model != NULL, FALSE)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return ((0)); } } while (0); | |||
1257 | ||||
1258 | indices = ctk_tree_path_get_indices (path); | |||
1259 | ||||
1260 | if (priv->root == NULL((void*)0)) | |||
1261 | ctk_tree_model_sort_build_level (tree_model_sort, NULL((void*)0), NULL((void*)0)); | |||
1262 | level = SORT_LEVEL (priv->root)((SortLevel *)priv->root); | |||
1263 | ||||
1264 | depth = ctk_tree_path_get_depth (path); | |||
1265 | if (depth == 0) | |||
1266 | { | |||
1267 | iter->stamp = 0; | |||
1268 | return FALSE(0); | |||
1269 | } | |||
1270 | ||||
1271 | for (i = 0; i < depth - 1; i++) | |||
1272 | { | |||
1273 | if ((level == NULL((void*)0)) || | |||
1274 | (indices[i] >= g_sequence_get_length (level->seq))) | |||
1275 | { | |||
1276 | iter->stamp = 0; | |||
1277 | return FALSE(0); | |||
1278 | } | |||
1279 | ||||
1280 | siter = g_sequence_get_iter_at_pos (level->seq, indices[i]); | |||
1281 | if (g_sequence_iter_is_end (siter)) | |||
1282 | { | |||
1283 | iter->stamp = 0; | |||
1284 | return FALSE(0); | |||
1285 | } | |||
1286 | ||||
1287 | elt = GET_ELT (siter)((SortElt *) (siter ? g_sequence_get (siter) : ((void*)0))); | |||
1288 | if (elt->children == NULL((void*)0)) | |||
1289 | ctk_tree_model_sort_build_level (tree_model_sort, level, elt); | |||
1290 | ||||
1291 | level = elt->children; | |||
1292 | } | |||
1293 | ||||
1294 | if (!level || indices[i] >= g_sequence_get_length (level->seq)) | |||
1295 | { | |||
1296 | iter->stamp = 0; | |||
1297 | return FALSE(0); | |||
1298 | } | |||
1299 | ||||
1300 | iter->stamp = priv->stamp; | |||
1301 | iter->user_data = level; | |||
1302 | ||||
1303 | siter = g_sequence_get_iter_at_pos (level->seq, indices[depth - 1]); | |||
1304 | if (g_sequence_iter_is_end (siter)) | |||
1305 | { | |||
1306 | iter->stamp = 0; | |||
1307 | return FALSE(0); | |||
1308 | } | |||
1309 | iter->user_data2 = GET_ELT (siter)((SortElt *) (siter ? g_sequence_get (siter) : ((void*)0))); | |||
1310 | ||||
1311 | return TRUE(!(0)); | |||
1312 | } | |||
1313 | ||||
1314 | static CtkTreePath * | |||
1315 | ctk_tree_model_sort_get_path (CtkTreeModel *tree_model, | |||
1316 | CtkTreeIter *iter) | |||
1317 | { | |||
1318 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1319 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1320 | CtkTreePath *retval; | |||
1321 | SortLevel *level; | |||
1322 | SortElt *elt; | |||
1323 | ||||
1324 | g_return_val_if_fail (priv->child_model != NULL, NULL)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return (((void*)0)); } } while (0); | |||
1325 | g_return_val_if_fail (priv->stamp == iter->stamp, NULL)do { if ((priv->stamp == iter->stamp)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->stamp == iter->stamp" ); return (((void*)0)); } } while (0); | |||
1326 | ||||
1327 | retval = ctk_tree_path_new (); | |||
1328 | ||||
1329 | level = SORT_LEVEL (iter->user_data)((SortLevel *)iter->user_data); | |||
1330 | elt = SORT_ELT (iter->user_data2)((SortElt *)iter->user_data2); | |||
1331 | ||||
1332 | while (level) | |||
1333 | { | |||
1334 | gint index; | |||
1335 | ||||
1336 | index = g_sequence_iter_get_position (elt->siter); | |||
1337 | ctk_tree_path_prepend_index (retval, index); | |||
1338 | ||||
1339 | elt = level->parent_elt; | |||
1340 | level = level->parent_level; | |||
1341 | } | |||
1342 | ||||
1343 | return retval; | |||
1344 | } | |||
1345 | ||||
1346 | static void | |||
1347 | ctk_tree_model_sort_get_value (CtkTreeModel *tree_model, | |||
1348 | CtkTreeIter *iter, | |||
1349 | gint column, | |||
1350 | GValue *value) | |||
1351 | { | |||
1352 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1353 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1354 | CtkTreeIter child_iter; | |||
1355 | ||||
1356 | g_return_if_fail (priv->child_model != NULL)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return; } } while (0); | |||
1357 | g_return_if_fail (VALID_ITER (iter, tree_model_sort))do { if ((((iter) != ((void*)0) && (iter)->user_data != ((void*)0) && (iter)->user_data2 != ((void*)0) && (tree_model_sort)->priv->stamp == (iter)-> stamp))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "VALID_ITER (iter, tree_model_sort)"); return ; } } while (0); | |||
1358 | ||||
1359 | GET_CHILD_ITER (tree_model_sort, &child_iter, iter)ctk_tree_model_sort_convert_iter_to_child_iter((CtkTreeModelSort *)(tree_model_sort), (&child_iter), (iter));; | |||
1360 | ctk_tree_model_get_value (priv->child_model, | |||
1361 | &child_iter, column, value); | |||
1362 | } | |||
1363 | ||||
1364 | static gboolean | |||
1365 | ctk_tree_model_sort_iter_next (CtkTreeModel *tree_model, | |||
1366 | CtkTreeIter *iter) | |||
1367 | { | |||
1368 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1369 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1370 | SortElt *elt; | |||
1371 | GSequenceIter *siter; | |||
1372 | ||||
1373 | g_return_val_if_fail (priv->child_model != NULL, FALSE)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return ((0)); } } while (0); | |||
1374 | g_return_val_if_fail (priv->stamp == iter->stamp, FALSE)do { if ((priv->stamp == iter->stamp)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->stamp == iter->stamp" ); return ((0)); } } while (0); | |||
1375 | ||||
1376 | elt = iter->user_data2; | |||
1377 | ||||
1378 | siter = g_sequence_iter_next (elt->siter); | |||
1379 | if (g_sequence_iter_is_end (siter)) | |||
1380 | { | |||
1381 | iter->stamp = 0; | |||
1382 | return FALSE(0); | |||
1383 | } | |||
1384 | iter->user_data2 = GET_ELT (siter)((SortElt *) (siter ? g_sequence_get (siter) : ((void*)0))); | |||
1385 | ||||
1386 | return TRUE(!(0)); | |||
1387 | } | |||
1388 | ||||
1389 | static gboolean | |||
1390 | ctk_tree_model_sort_iter_previous (CtkTreeModel *tree_model, | |||
1391 | CtkTreeIter *iter) | |||
1392 | { | |||
1393 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1394 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1395 | SortElt *elt; | |||
1396 | GSequenceIter *siter; | |||
1397 | ||||
1398 | g_return_val_if_fail (priv->child_model != NULL, FALSE)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return ((0)); } } while (0); | |||
1399 | g_return_val_if_fail (priv->stamp == iter->stamp, FALSE)do { if ((priv->stamp == iter->stamp)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->stamp == iter->stamp" ); return ((0)); } } while (0); | |||
1400 | ||||
1401 | elt = iter->user_data2; | |||
1402 | ||||
1403 | if (g_sequence_iter_is_begin (elt->siter)) | |||
1404 | { | |||
1405 | iter->stamp = 0; | |||
1406 | return FALSE(0); | |||
1407 | } | |||
1408 | ||||
1409 | siter = g_sequence_iter_prev (elt->siter); | |||
1410 | iter->user_data2 = GET_ELT (siter)((SortElt *) (siter ? g_sequence_get (siter) : ((void*)0))); | |||
1411 | ||||
1412 | return TRUE(!(0)); | |||
1413 | } | |||
1414 | ||||
1415 | static gboolean | |||
1416 | ctk_tree_model_sort_iter_children (CtkTreeModel *tree_model, | |||
1417 | CtkTreeIter *iter, | |||
1418 | CtkTreeIter *parent) | |||
1419 | { | |||
1420 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1421 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1422 | SortLevel *level; | |||
1423 | ||||
1424 | iter->stamp = 0; | |||
1425 | g_return_val_if_fail (priv->child_model != NULL, FALSE)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return ((0)); } } while (0); | |||
1426 | if (parent) | |||
1427 | g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE)do { if ((((parent) != ((void*)0) && (parent)->user_data != ((void*)0) && (parent)->user_data2 != ((void*) 0) && (tree_model_sort)->priv->stamp == (parent )->stamp))) { } else { g_return_if_fail_warning ("Ctk", (( const char*) (__func__)), "VALID_ITER (parent, tree_model_sort)" ); return ((0)); } } while (0); | |||
1428 | ||||
1429 | if (parent == NULL((void*)0)) | |||
1430 | { | |||
1431 | if (priv->root == NULL((void*)0)) | |||
1432 | ctk_tree_model_sort_build_level (tree_model_sort, NULL((void*)0), NULL((void*)0)); | |||
1433 | if (priv->root == NULL((void*)0)) | |||
1434 | return FALSE(0); | |||
1435 | ||||
1436 | level = priv->root; | |||
1437 | iter->stamp = priv->stamp; | |||
1438 | iter->user_data = level; | |||
1439 | iter->user_data2 = g_sequence_get (g_sequence_get_begin_iter (level->seq)); | |||
1440 | } | |||
1441 | else | |||
1442 | { | |||
1443 | SortElt *elt; | |||
1444 | ||||
1445 | level = SORT_LEVEL (parent->user_data)((SortLevel *)parent->user_data); | |||
1446 | elt = SORT_ELT (parent->user_data2)((SortElt *)parent->user_data2); | |||
1447 | ||||
1448 | if (elt->children == NULL((void*)0)) | |||
1449 | ctk_tree_model_sort_build_level (tree_model_sort, level, elt); | |||
1450 | ||||
1451 | if (elt->children == NULL((void*)0)) | |||
1452 | return FALSE(0); | |||
1453 | ||||
1454 | iter->stamp = priv->stamp; | |||
1455 | iter->user_data = elt->children; | |||
1456 | iter->user_data2 = g_sequence_get (g_sequence_get_begin_iter (elt->children->seq)); | |||
1457 | } | |||
1458 | ||||
1459 | return TRUE(!(0)); | |||
1460 | } | |||
1461 | ||||
1462 | static gboolean | |||
1463 | ctk_tree_model_sort_iter_has_child (CtkTreeModel *tree_model, | |||
1464 | CtkTreeIter *iter) | |||
1465 | { | |||
1466 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1467 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1468 | CtkTreeIter child_iter; | |||
1469 | ||||
1470 | g_return_val_if_fail (priv->child_model != NULL, FALSE)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return ((0)); } } while (0); | |||
1471 | g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), FALSE)do { if ((((iter) != ((void*)0) && (iter)->user_data != ((void*)0) && (iter)->user_data2 != ((void*)0) && (tree_model_sort)->priv->stamp == (iter)-> stamp))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "VALID_ITER (iter, tree_model_sort)"); return ((0)); } } while (0); | |||
1472 | ||||
1473 | GET_CHILD_ITER (tree_model_sort, &child_iter, iter)ctk_tree_model_sort_convert_iter_to_child_iter((CtkTreeModelSort *)(tree_model_sort), (&child_iter), (iter));; | |||
1474 | ||||
1475 | return ctk_tree_model_iter_has_child (priv->child_model, &child_iter); | |||
1476 | } | |||
1477 | ||||
1478 | static gint | |||
1479 | ctk_tree_model_sort_iter_n_children (CtkTreeModel *tree_model, | |||
1480 | CtkTreeIter *iter) | |||
1481 | { | |||
1482 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1483 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1484 | CtkTreeIter child_iter; | |||
1485 | ||||
1486 | g_return_val_if_fail (priv->child_model != NULL, 0)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return (0); } } while (0); | |||
1487 | if (iter) | |||
1488 | g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), 0)do { if ((((iter) != ((void*)0) && (iter)->user_data != ((void*)0) && (iter)->user_data2 != ((void*)0) && (tree_model_sort)->priv->stamp == (iter)-> stamp))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "VALID_ITER (iter, tree_model_sort)"); return (0); } } while (0); | |||
1489 | ||||
1490 | if (iter == NULL((void*)0)) | |||
1491 | return ctk_tree_model_iter_n_children (priv->child_model, NULL((void*)0)); | |||
1492 | ||||
1493 | GET_CHILD_ITER (tree_model_sort, &child_iter, iter)ctk_tree_model_sort_convert_iter_to_child_iter((CtkTreeModelSort *)(tree_model_sort), (&child_iter), (iter));; | |||
1494 | ||||
1495 | return ctk_tree_model_iter_n_children (priv->child_model, &child_iter); | |||
1496 | } | |||
1497 | ||||
1498 | static gboolean | |||
1499 | ctk_tree_model_sort_iter_nth_child (CtkTreeModel *tree_model, | |||
1500 | CtkTreeIter *iter, | |||
1501 | CtkTreeIter *parent, | |||
1502 | gint n) | |||
1503 | { | |||
1504 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1505 | SortLevel *level; | |||
1506 | /* We have this for the iter == parent case */ | |||
1507 | CtkTreeIter children; | |||
1508 | ||||
1509 | if (parent) | |||
1510 | g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE)do { if ((((parent) != ((void*)0) && (parent)->user_data != ((void*)0) && (parent)->user_data2 != ((void*) 0) && (tree_model_sort)->priv->stamp == (parent )->stamp))) { } else { g_return_if_fail_warning ("Ctk", (( const char*) (__func__)), "VALID_ITER (parent, tree_model_sort)" ); return ((0)); } } while (0); | |||
1511 | ||||
1512 | /* Use this instead of has_child to force us to build the level, if needed */ | |||
1513 | if (ctk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE(0)) | |||
1514 | { | |||
1515 | iter->stamp = 0; | |||
1516 | return FALSE(0); | |||
1517 | } | |||
1518 | ||||
1519 | level = children.user_data; | |||
1520 | if (n >= g_sequence_get_length (level->seq)) | |||
1521 | { | |||
1522 | iter->stamp = 0; | |||
1523 | return FALSE(0); | |||
1524 | } | |||
1525 | ||||
1526 | iter->stamp = tree_model_sort->priv->stamp; | |||
1527 | iter->user_data = level; | |||
1528 | iter->user_data2 = g_sequence_get (g_sequence_get_iter_at_pos (level->seq, n)); | |||
1529 | ||||
1530 | return TRUE(!(0)); | |||
1531 | } | |||
1532 | ||||
1533 | static gboolean | |||
1534 | ctk_tree_model_sort_iter_parent (CtkTreeModel *tree_model, | |||
1535 | CtkTreeIter *iter, | |||
1536 | CtkTreeIter *child) | |||
1537 | { | |||
1538 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1539 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1540 | SortLevel *level; | |||
1541 | ||||
1542 | iter->stamp = 0; | |||
1543 | g_return_val_if_fail (priv->child_model != NULL, FALSE)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return ((0)); } } while (0); | |||
1544 | g_return_val_if_fail (VALID_ITER (child, tree_model_sort), FALSE)do { if ((((child) != ((void*)0) && (child)->user_data != ((void*)0) && (child)->user_data2 != ((void*)0 ) && (tree_model_sort)->priv->stamp == (child)-> stamp))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "VALID_ITER (child, tree_model_sort)"); return ((0)); } } while (0); | |||
1545 | ||||
1546 | level = child->user_data; | |||
1547 | ||||
1548 | if (level->parent_level) | |||
1549 | { | |||
1550 | iter->stamp = priv->stamp; | |||
1551 | iter->user_data = level->parent_level; | |||
1552 | iter->user_data2 = level->parent_elt; | |||
1553 | ||||
1554 | return TRUE(!(0)); | |||
1555 | } | |||
1556 | return FALSE(0); | |||
1557 | } | |||
1558 | ||||
1559 | static void | |||
1560 | ctk_tree_model_sort_ref_node (CtkTreeModel *tree_model, | |||
1561 | CtkTreeIter *iter) | |||
1562 | { | |||
1563 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1564 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1565 | CtkTreeIter child_iter; | |||
1566 | SortLevel *level; | |||
1567 | SortElt *elt; | |||
1568 | ||||
1569 | g_return_if_fail (priv->child_model != NULL)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return; } } while (0); | |||
1570 | g_return_if_fail (VALID_ITER (iter, tree_model_sort))do { if ((((iter) != ((void*)0) && (iter)->user_data != ((void*)0) && (iter)->user_data2 != ((void*)0) && (tree_model_sort)->priv->stamp == (iter)-> stamp))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "VALID_ITER (iter, tree_model_sort)"); return ; } } while (0); | |||
1571 | ||||
1572 | GET_CHILD_ITER (tree_model_sort, &child_iter, iter)ctk_tree_model_sort_convert_iter_to_child_iter((CtkTreeModelSort *)(tree_model_sort), (&child_iter), (iter));; | |||
1573 | ||||
1574 | /* Reference the node in the child model */ | |||
1575 | ctk_tree_model_ref_node (priv->child_model, &child_iter); | |||
1576 | ||||
1577 | /* Increase the reference count of this element and its level */ | |||
1578 | level = iter->user_data; | |||
1579 | elt = iter->user_data2; | |||
1580 | ||||
1581 | elt->ref_count++; | |||
1582 | level->ref_count++; | |||
1583 | ||||
1584 | if (level->ref_count == 1) | |||
1585 | { | |||
1586 | SortLevel *parent_level = level->parent_level; | |||
1587 | SortElt *parent_elt = level->parent_elt; | |||
1588 | ||||
1589 | /* We were at zero -- time to decrement the zero_ref_count val */ | |||
1590 | while (parent_level) | |||
1591 | { | |||
1592 | parent_elt->zero_ref_count--; | |||
1593 | ||||
1594 | parent_elt = parent_level->parent_elt; | |||
1595 | parent_level = parent_level->parent_level; | |||
1596 | } | |||
1597 | ||||
1598 | if (priv->root != level) | |||
1599 | priv->zero_ref_count--; | |||
1600 | } | |||
1601 | } | |||
1602 | ||||
1603 | static void | |||
1604 | ctk_tree_model_sort_real_unref_node (CtkTreeModel *tree_model, | |||
1605 | CtkTreeIter *iter, | |||
1606 | gboolean propagate_unref) | |||
1607 | { | |||
1608 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) tree_model; | |||
1609 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1610 | SortLevel *level; | |||
1611 | SortElt *elt; | |||
1612 | ||||
1613 | g_return_if_fail (priv->child_model != NULL)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return; } } while (0); | |||
1614 | g_return_if_fail (VALID_ITER (iter, tree_model_sort))do { if ((((iter) != ((void*)0) && (iter)->user_data != ((void*)0) && (iter)->user_data2 != ((void*)0) && (tree_model_sort)->priv->stamp == (iter)-> stamp))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "VALID_ITER (iter, tree_model_sort)"); return ; } } while (0); | |||
1615 | ||||
1616 | if (propagate_unref) | |||
1617 | { | |||
1618 | CtkTreeIter child_iter; | |||
1619 | ||||
1620 | GET_CHILD_ITER (tree_model_sort, &child_iter, iter)ctk_tree_model_sort_convert_iter_to_child_iter((CtkTreeModelSort *)(tree_model_sort), (&child_iter), (iter));; | |||
1621 | ctk_tree_model_unref_node (priv->child_model, &child_iter); | |||
1622 | } | |||
1623 | ||||
1624 | level = iter->user_data; | |||
1625 | elt = iter->user_data2; | |||
1626 | ||||
1627 | g_return_if_fail (elt->ref_count > 0)do { if ((elt->ref_count > 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "elt->ref_count > 0" ); return; } } while (0); | |||
1628 | ||||
1629 | elt->ref_count--; | |||
1630 | level->ref_count--; | |||
1631 | ||||
1632 | if (level->ref_count == 0) | |||
1633 | { | |||
1634 | SortLevel *parent_level = level->parent_level; | |||
1635 | SortElt *parent_elt = level->parent_elt; | |||
1636 | ||||
1637 | /* We are at zero -- time to increment the zero_ref_count val */ | |||
1638 | while (parent_level) | |||
1639 | { | |||
1640 | parent_elt->zero_ref_count++; | |||
1641 | ||||
1642 | parent_elt = parent_level->parent_elt; | |||
1643 | parent_level = parent_level->parent_level; | |||
1644 | } | |||
1645 | ||||
1646 | if (priv->root != level) | |||
1647 | priv->zero_ref_count++; | |||
1648 | } | |||
1649 | } | |||
1650 | ||||
1651 | static void | |||
1652 | ctk_tree_model_sort_unref_node (CtkTreeModel *tree_model, | |||
1653 | CtkTreeIter *iter) | |||
1654 | { | |||
1655 | ctk_tree_model_sort_real_unref_node (tree_model, iter, TRUE(!(0))); | |||
1656 | } | |||
1657 | ||||
1658 | /* Sortable interface */ | |||
1659 | static gboolean | |||
1660 | ctk_tree_model_sort_get_sort_column_id (CtkTreeSortable *sortable, | |||
1661 | gint *sort_column_id, | |||
1662 | CtkSortType *order) | |||
1663 | { | |||
1664 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *)sortable; | |||
1665 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1666 | ||||
1667 | if (sort_column_id) | |||
1668 | *sort_column_id = priv->sort_column_id; | |||
1669 | if (order) | |||
1670 | *order = priv->order; | |||
1671 | ||||
1672 | if (priv->sort_column_id == CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1) || | |||
1673 | priv->sort_column_id == CTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID(-2)) | |||
1674 | return FALSE(0); | |||
1675 | ||||
1676 | return TRUE(!(0)); | |||
1677 | } | |||
1678 | ||||
1679 | static void | |||
1680 | ctk_tree_model_sort_set_sort_column_id (CtkTreeSortable *sortable, | |||
1681 | gint sort_column_id, | |||
1682 | CtkSortType order) | |||
1683 | { | |||
1684 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *)sortable; | |||
1685 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1686 | ||||
1687 | if (priv->sort_column_id == sort_column_id && priv->order == order) | |||
1688 | return; | |||
1689 | ||||
1690 | if (sort_column_id != CTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID(-2)) | |||
1691 | { | |||
1692 | if (sort_column_id != CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1)) | |||
1693 | { | |||
1694 | CtkTreeDataSortHeader *header = NULL((void*)0); | |||
1695 | ||||
1696 | header = _ctk_tree_data_list_get_header (priv->sort_list, | |||
1697 | sort_column_id); | |||
1698 | ||||
1699 | /* we want to make sure that we have a function */ | |||
1700 | g_return_if_fail (header != NULL)do { if ((header != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "header != NULL"); return ; } } while (0); | |||
1701 | g_return_if_fail (header->func != NULL)do { if ((header->func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "header->func != NULL" ); return; } } while (0); | |||
1702 | } | |||
1703 | else | |||
1704 | g_return_if_fail (priv->default_sort_func != NULL)do { if ((priv->default_sort_func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "priv->default_sort_func != NULL"); return; } } while ( 0); | |||
1705 | } | |||
1706 | ||||
1707 | priv->sort_column_id = sort_column_id; | |||
1708 | priv->order = order; | |||
1709 | ||||
1710 | ctk_tree_sortable_sort_column_changed (sortable); | |||
1711 | ||||
1712 | ctk_tree_model_sort_sort (tree_model_sort); | |||
1713 | } | |||
1714 | ||||
1715 | static void | |||
1716 | ctk_tree_model_sort_set_sort_func (CtkTreeSortable *sortable, | |||
1717 | gint sort_column_id, | |||
1718 | CtkTreeIterCompareFunc func, | |||
1719 | gpointer data, | |||
1720 | GDestroyNotify destroy) | |||
1721 | { | |||
1722 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *) sortable; | |||
1723 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1724 | ||||
1725 | priv->sort_list = _ctk_tree_data_list_set_header (priv->sort_list, | |||
1726 | sort_column_id, | |||
1727 | func, data, destroy); | |||
1728 | ||||
1729 | if (priv->sort_column_id == sort_column_id) | |||
1730 | ctk_tree_model_sort_sort (tree_model_sort); | |||
1731 | } | |||
1732 | ||||
1733 | static void | |||
1734 | ctk_tree_model_sort_set_default_sort_func (CtkTreeSortable *sortable, | |||
1735 | CtkTreeIterCompareFunc func, | |||
1736 | gpointer data, | |||
1737 | GDestroyNotify destroy) | |||
1738 | { | |||
1739 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *)sortable; | |||
1740 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1741 | ||||
1742 | if (priv->default_sort_destroy) | |||
1743 | { | |||
1744 | GDestroyNotify d = priv->default_sort_destroy; | |||
1745 | ||||
1746 | priv->default_sort_destroy = NULL((void*)0); | |||
1747 | d (priv->default_sort_data); | |||
1748 | } | |||
1749 | ||||
1750 | priv->default_sort_func = func; | |||
1751 | priv->default_sort_data = data; | |||
1752 | priv->default_sort_destroy = destroy; | |||
1753 | ||||
1754 | if (priv->sort_column_id == CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1)) | |||
1755 | ctk_tree_model_sort_sort (tree_model_sort); | |||
1756 | } | |||
1757 | ||||
1758 | static gboolean | |||
1759 | ctk_tree_model_sort_has_default_sort_func (CtkTreeSortable *sortable) | |||
1760 | { | |||
1761 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *)sortable; | |||
1762 | ||||
1763 | return (tree_model_sort->priv->default_sort_func != NO_SORT_FUNC((CtkTreeIterCompareFunc) 0x1)); | |||
1764 | } | |||
1765 | ||||
1766 | /* DragSource interface */ | |||
1767 | static gboolean | |||
1768 | ctk_tree_model_sort_row_draggable (CtkTreeDragSource *drag_source, | |||
1769 | CtkTreePath *path) | |||
1770 | { | |||
1771 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *)drag_source; | |||
1772 | CtkTreePath *child_path; | |||
1773 | gboolean draggable; | |||
1774 | ||||
1775 | child_path = ctk_tree_model_sort_convert_path_to_child_path (tree_model_sort, | |||
1776 | path); | |||
1777 | draggable = ctk_tree_drag_source_row_draggable (CTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model)((((CtkTreeDragSource*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tree_model_sort->priv->child_model)) , ((ctk_tree_drag_source_get_type ())))))), child_path); | |||
1778 | ctk_tree_path_free (child_path); | |||
1779 | ||||
1780 | return draggable; | |||
1781 | } | |||
1782 | ||||
1783 | static gboolean | |||
1784 | ctk_tree_model_sort_drag_data_get (CtkTreeDragSource *drag_source, | |||
1785 | CtkTreePath *path, | |||
1786 | CtkSelectionData *selection_data) | |||
1787 | { | |||
1788 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *)drag_source; | |||
1789 | CtkTreePath *child_path; | |||
1790 | gboolean gotten; | |||
1791 | ||||
1792 | child_path = ctk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path); | |||
1793 | gotten = ctk_tree_drag_source_drag_data_get (CTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model)((((CtkTreeDragSource*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tree_model_sort->priv->child_model)) , ((ctk_tree_drag_source_get_type ())))))), child_path, selection_data); | |||
1794 | ctk_tree_path_free (child_path); | |||
1795 | ||||
1796 | return gotten; | |||
1797 | } | |||
1798 | ||||
1799 | static gboolean | |||
1800 | ctk_tree_model_sort_drag_data_delete (CtkTreeDragSource *drag_source, | |||
1801 | CtkTreePath *path) | |||
1802 | { | |||
1803 | CtkTreeModelSort *tree_model_sort = (CtkTreeModelSort *)drag_source; | |||
1804 | CtkTreePath *child_path; | |||
1805 | gboolean deleted; | |||
1806 | ||||
1807 | child_path = ctk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path); | |||
1808 | deleted = ctk_tree_drag_source_drag_data_delete (CTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model)((((CtkTreeDragSource*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tree_model_sort->priv->child_model)) , ((ctk_tree_drag_source_get_type ())))))), child_path); | |||
1809 | ctk_tree_path_free (child_path); | |||
1810 | ||||
1811 | return deleted; | |||
1812 | } | |||
1813 | ||||
1814 | /* sorting code - private */ | |||
1815 | static gint | |||
1816 | ctk_tree_model_sort_compare_func (gconstpointer a, | |||
1817 | gconstpointer b, | |||
1818 | gpointer user_data) | |||
1819 | { | |||
1820 | SortData *data = (SortData *)user_data; | |||
1821 | CtkTreeModelSort *tree_model_sort = data->tree_model_sort; | |||
1822 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1823 | const SortElt *sa = a; | |||
1824 | const SortElt *sb = b; | |||
1825 | ||||
1826 | CtkTreeIter iter_a, iter_b; | |||
1827 | gint retval; | |||
1828 | ||||
1829 | if (CTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort)(((CtkTreeModelSort *)tree_model_sort)->priv->child_flags &CTK_TREE_MODEL_ITERS_PERSIST)) | |||
1830 | { | |||
1831 | iter_a = sa->iter; | |||
1832 | iter_b = sb->iter; | |||
1833 | } | |||
1834 | else | |||
1835 | { | |||
1836 | data->parent_path_indices [data->parent_path_depth-1] = sa->offset; | |||
1837 | ctk_tree_model_get_iter (CTK_TREE_MODEL (priv->child_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->child_model)), ((ctk_tree_model_get_type ())))) )), &iter_a, data->parent_path); | |||
1838 | data->parent_path_indices [data->parent_path_depth-1] = sb->offset; | |||
1839 | ctk_tree_model_get_iter (CTK_TREE_MODEL (priv->child_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->child_model)), ((ctk_tree_model_get_type ())))) )), &iter_b, data->parent_path); | |||
1840 | } | |||
1841 | ||||
1842 | retval = (* data->sort_func) (CTK_TREE_MODEL (priv->child_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((priv->child_model)), ((ctk_tree_model_get_type ())))) )), | |||
1843 | &iter_a, &iter_b, | |||
1844 | data->sort_data); | |||
1845 | ||||
1846 | if (priv->order == CTK_SORT_DESCENDING) | |||
1847 | { | |||
1848 | if (retval > 0) | |||
1849 | retval = -1; | |||
1850 | else if (retval < 0) | |||
1851 | retval = 1; | |||
1852 | } | |||
1853 | ||||
1854 | return retval; | |||
1855 | } | |||
1856 | ||||
1857 | static gint | |||
1858 | ctk_tree_model_sort_offset_compare_func (gconstpointer a, | |||
1859 | gconstpointer b, | |||
1860 | gpointer user_data) | |||
1861 | { | |||
1862 | gint retval; | |||
1863 | ||||
1864 | const SortElt *sa = (SortElt *)a; | |||
1865 | const SortElt *sb = (SortElt *)b; | |||
1866 | ||||
1867 | SortData *data = (SortData *)user_data; | |||
1868 | ||||
1869 | if (sa->offset < sb->offset) | |||
1870 | retval = -1; | |||
1871 | else if (sa->offset > sb->offset) | |||
1872 | retval = 1; | |||
1873 | else | |||
1874 | retval = 0; | |||
1875 | ||||
1876 | if (data->tree_model_sort->priv->order == CTK_SORT_DESCENDING) | |||
1877 | { | |||
1878 | if (retval > 0) | |||
1879 | retval = -1; | |||
1880 | else if (retval < 0) | |||
1881 | retval = 1; | |||
1882 | } | |||
1883 | ||||
1884 | return retval; | |||
1885 | } | |||
1886 | ||||
1887 | static void | |||
1888 | ctk_tree_model_sort_sort_level (CtkTreeModelSort *tree_model_sort, | |||
1889 | SortLevel *level, | |||
1890 | gboolean recurse, | |||
1891 | gboolean emit_reordered) | |||
1892 | { | |||
1893 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
1894 | gint i; | |||
1895 | GSequenceIter *begin_siter, *end_siter, *siter; | |||
1896 | SortElt *begin_elt; | |||
1897 | gint *new_order; | |||
1898 | ||||
1899 | CtkTreeIter iter; | |||
1900 | ||||
1901 | SortData data; | |||
1902 | ||||
1903 | g_return_if_fail (level != NULL)do { if ((level != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "level != NULL"); return ; } } while (0); | |||
1904 | ||||
1905 | begin_siter = g_sequence_get_begin_iter (level->seq); | |||
1906 | begin_elt = g_sequence_get (begin_siter); | |||
1907 | ||||
1908 | if (g_sequence_get_length (level->seq) < 1 && !begin_elt->children) | |||
1909 | return; | |||
1910 | ||||
1911 | iter.stamp = priv->stamp; | |||
1912 | iter.user_data = level; | |||
1913 | iter.user_data2 = begin_elt; | |||
1914 | ||||
1915 | ctk_tree_model_sort_ref_node (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), &iter); | |||
1916 | ||||
1917 | i = 0; | |||
1918 | end_siter = g_sequence_get_end_iter (level->seq); | |||
1919 | for (siter = g_sequence_get_begin_iter (level->seq); | |||
1920 | siter != end_siter; | |||
1921 | siter = g_sequence_iter_next (siter)) | |||
1922 | { | |||
1923 | SortElt *elt = g_sequence_get (siter); | |||
1924 | ||||
1925 | elt->old_index = i; | |||
1926 | i++; | |||
1927 | } | |||
1928 | ||||
1929 | fill_sort_data (&data, tree_model_sort, level); | |||
1930 | ||||
1931 | if (data.sort_func == NO_SORT_FUNC((CtkTreeIterCompareFunc) 0x1)) | |||
1932 | g_sequence_sort (level->seq, ctk_tree_model_sort_offset_compare_func, | |||
1933 | &data); | |||
1934 | else | |||
1935 | g_sequence_sort (level->seq, ctk_tree_model_sort_compare_func, &data); | |||
1936 | ||||
1937 | free_sort_data (&data); | |||
1938 | ||||
1939 | new_order = g_new (gint, g_sequence_get_length (level->seq))((gint *) g_malloc_n ((g_sequence_get_length (level->seq)) , sizeof (gint))); | |||
1940 | ||||
1941 | i = 0; | |||
1942 | end_siter = g_sequence_get_end_iter (level->seq); | |||
1943 | for (siter = g_sequence_get_begin_iter (level->seq); | |||
1944 | siter != end_siter; | |||
1945 | siter = g_sequence_iter_next (siter)) | |||
1946 | { | |||
1947 | SortElt *elt = g_sequence_get (siter); | |||
1948 | ||||
1949 | new_order[i++] = elt->old_index; | |||
1950 | } | |||
1951 | ||||
1952 | if (emit_reordered) | |||
1953 | { | |||
1954 | CtkTreePath *path; | |||
1955 | ||||
1956 | ctk_tree_model_sort_increment_stamp (tree_model_sort); | |||
1957 | ||||
1958 | if (level->parent_elt) | |||
1959 | { | |||
1960 | iter.stamp = priv->stamp; | |||
1961 | iter.user_data = level->parent_level; | |||
1962 | iter.user_data2 = level->parent_elt; | |||
1963 | ||||
1964 | path = ctk_tree_model_get_path (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), | |||
1965 | &iter); | |||
1966 | ||||
1967 | ctk_tree_model_rows_reordered (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), path, | |||
1968 | &iter, new_order); | |||
1969 | } | |||
1970 | else | |||
1971 | { | |||
1972 | /* toplevel list */ | |||
1973 | path = ctk_tree_path_new (); | |||
1974 | ctk_tree_model_rows_reordered (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), path, | |||
1975 | NULL((void*)0), new_order); | |||
1976 | } | |||
1977 | ||||
1978 | ctk_tree_path_free (path); | |||
1979 | } | |||
1980 | ||||
1981 | /* recurse, if possible */ | |||
1982 | if (recurse) | |||
1983 | { | |||
1984 | end_siter = g_sequence_get_end_iter (level->seq); | |||
1985 | for (siter = g_sequence_get_begin_iter (level->seq); | |||
1986 | siter != end_siter; | |||
1987 | siter = g_sequence_iter_next (siter)) | |||
1988 | { | |||
1989 | SortElt *elt = g_sequence_get (siter); | |||
1990 | ||||
1991 | if (elt->children) | |||
1992 | ctk_tree_model_sort_sort_level (tree_model_sort, | |||
1993 | elt->children, | |||
1994 | TRUE(!(0)), emit_reordered); | |||
1995 | } | |||
1996 | } | |||
1997 | ||||
1998 | g_free (new_order); | |||
1999 | ||||
2000 | /* get the iter we referenced at the beginning of this function and | |||
2001 | * unref it again | |||
2002 | */ | |||
2003 | iter.stamp = priv->stamp; | |||
2004 | iter.user_data = level; | |||
2005 | iter.user_data2 = begin_elt; | |||
2006 | ||||
2007 | ctk_tree_model_sort_unref_node (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), &iter); | |||
2008 | } | |||
2009 | ||||
2010 | static void | |||
2011 | ctk_tree_model_sort_sort (CtkTreeModelSort *tree_model_sort) | |||
2012 | { | |||
2013 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2014 | ||||
2015 | if (priv->sort_column_id == CTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID(-2)) | |||
2016 | return; | |||
2017 | ||||
2018 | if (!priv->root) | |||
2019 | return; | |||
2020 | ||||
2021 | if (priv->sort_column_id != CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1)) | |||
2022 | { | |||
2023 | CtkTreeDataSortHeader *header = NULL((void*)0); | |||
2024 | ||||
2025 | header = _ctk_tree_data_list_get_header (priv->sort_list, | |||
2026 | priv->sort_column_id); | |||
2027 | ||||
2028 | /* we want to make sure that we have a function */ | |||
2029 | g_return_if_fail (header != NULL)do { if ((header != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "header != NULL"); return ; } } while (0); | |||
2030 | g_return_if_fail (header->func != NULL)do { if ((header->func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "header->func != NULL" ); return; } } while (0); | |||
2031 | } | |||
2032 | else | |||
2033 | g_return_if_fail (priv->default_sort_func != NULL)do { if ((priv->default_sort_func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "priv->default_sort_func != NULL"); return; } } while ( 0); | |||
2034 | ||||
2035 | ctk_tree_model_sort_sort_level (tree_model_sort, priv->root, | |||
2036 | TRUE(!(0)), TRUE(!(0))); | |||
2037 | } | |||
2038 | ||||
2039 | /* signal helpers */ | |||
2040 | static gboolean | |||
2041 | ctk_tree_model_sort_insert_value (CtkTreeModelSort *tree_model_sort, | |||
2042 | SortLevel *level, | |||
2043 | CtkTreePath *s_path, | |||
2044 | CtkTreeIter *s_iter) | |||
2045 | { | |||
2046 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2047 | SortElt *elt; | |||
2048 | SortData data; | |||
2049 | gint offset; | |||
2050 | ||||
2051 | elt = sort_elt_new (); | |||
2052 | ||||
2053 | offset = ctk_tree_path_get_indices (s_path)[ctk_tree_path_get_depth (s_path) - 1]; | |||
2054 | ||||
2055 | if (CTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort)(((CtkTreeModelSort *)tree_model_sort)->priv->child_flags &CTK_TREE_MODEL_ITERS_PERSIST)) | |||
2056 | elt->iter = *s_iter; | |||
2057 | elt->offset = offset; | |||
2058 | elt->zero_ref_count = 0; | |||
2059 | elt->ref_count = 0; | |||
2060 | elt->children = NULL((void*)0); | |||
2061 | ||||
2062 | /* update all larger offsets */ | |||
2063 | g_sequence_foreach (level->seq, increase_offset_iter, GINT_TO_POINTER (offset)((gpointer) (glong) (offset))); | |||
2064 | ||||
2065 | fill_sort_data (&data, tree_model_sort, level); | |||
2066 | ||||
2067 | if (priv->sort_column_id == CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1) && | |||
2068 | priv->default_sort_func == NO_SORT_FUNC((CtkTreeIterCompareFunc) 0x1)) | |||
2069 | { | |||
2070 | elt->siter = g_sequence_insert_sorted (level->seq, elt, | |||
2071 | ctk_tree_model_sort_offset_compare_func, | |||
2072 | &data); | |||
2073 | } | |||
2074 | else | |||
2075 | { | |||
2076 | elt->siter = g_sequence_insert_sorted (level->seq, elt, | |||
2077 | ctk_tree_model_sort_compare_func, | |||
2078 | &data); | |||
2079 | } | |||
2080 | ||||
2081 | free_sort_data (&data); | |||
2082 | ||||
2083 | return TRUE(!(0)); | |||
2084 | } | |||
2085 | ||||
2086 | /* sort elt stuff */ | |||
2087 | static CtkTreePath * | |||
2088 | ctk_tree_model_sort_elt_get_path (SortLevel *level, | |||
2089 | SortElt *elt) | |||
2090 | { | |||
2091 | SortLevel *walker = level; | |||
2092 | SortElt *walker2 = elt; | |||
2093 | CtkTreePath *path; | |||
2094 | ||||
2095 | g_return_val_if_fail (level != NULL, NULL)do { if ((level != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "level != NULL"); return (((void*)0)); } } while (0); | |||
2096 | g_return_val_if_fail (elt != NULL, NULL)do { if ((elt != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "elt != NULL"); return ( ((void*)0)); } } while (0); | |||
2097 | ||||
2098 | path = ctk_tree_path_new (); | |||
2099 | ||||
2100 | while (walker) | |||
2101 | { | |||
2102 | ctk_tree_path_prepend_index (path, walker2->offset); | |||
2103 | ||||
2104 | if (!walker->parent_level) | |||
2105 | break; | |||
2106 | ||||
2107 | walker2 = walker->parent_elt; | |||
2108 | walker = walker->parent_level; | |||
2109 | } | |||
2110 | ||||
2111 | return path; | |||
2112 | } | |||
2113 | ||||
2114 | /** | |||
2115 | * ctk_tree_model_sort_set_model: | |||
2116 | * @tree_model_sort: The #CtkTreeModelSort. | |||
2117 | * @child_model: (allow-none): A #CtkTreeModel, or %NULL. | |||
2118 | * | |||
2119 | * Sets the model of @tree_model_sort to be @model. If @model is %NULL, | |||
2120 | * then the old model is unset. The sort function is unset as a result | |||
2121 | * of this call. The model will be in an unsorted state until a sort | |||
2122 | * function is set. | |||
2123 | **/ | |||
2124 | static void | |||
2125 | ctk_tree_model_sort_set_model (CtkTreeModelSort *tree_model_sort, | |||
2126 | CtkTreeModel *child_model) | |||
2127 | { | |||
2128 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2129 | ||||
2130 | if (child_model) | |||
2131 | g_object_ref (child_model)((__typeof__ (child_model)) (g_object_ref) (child_model)); | |||
2132 | ||||
2133 | if (priv->child_model) | |||
2134 | { | |||
2135 | g_signal_handler_disconnect (priv->child_model, | |||
2136 | priv->changed_id); | |||
2137 | g_signal_handler_disconnect (priv->child_model, | |||
2138 | priv->inserted_id); | |||
2139 | g_signal_handler_disconnect (priv->child_model, | |||
2140 | priv->has_child_toggled_id); | |||
2141 | g_signal_handler_disconnect (priv->child_model, | |||
2142 | priv->deleted_id); | |||
2143 | g_signal_handler_disconnect (priv->child_model, | |||
2144 | priv->reordered_id); | |||
2145 | ||||
2146 | /* reset our state */ | |||
2147 | if (priv->root) | |||
2148 | ctk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE(!(0))); | |||
2149 | priv->root = NULL((void*)0); | |||
2150 | _ctk_tree_data_list_header_free (priv->sort_list); | |||
2151 | priv->sort_list = NULL((void*)0); | |||
2152 | g_object_unref (priv->child_model); | |||
2153 | } | |||
2154 | ||||
2155 | priv->child_model = child_model; | |||
2156 | ||||
2157 | if (child_model
| |||
2158 | { | |||
2159 | GType *types; | |||
2160 | gint i, n_columns; | |||
2161 | ||||
2162 | priv->changed_id = | |||
2163 | g_signal_connect (child_model, "row-changed",g_signal_connect_data ((child_model), ("row-changed"), (((GCallback ) (ctk_tree_model_sort_row_changed))), (tree_model_sort), ((void *)0), (GConnectFlags) 0) | |||
2164 | G_CALLBACK (ctk_tree_model_sort_row_changed),g_signal_connect_data ((child_model), ("row-changed"), (((GCallback ) (ctk_tree_model_sort_row_changed))), (tree_model_sort), ((void *)0), (GConnectFlags) 0) | |||
2165 | tree_model_sort)g_signal_connect_data ((child_model), ("row-changed"), (((GCallback ) (ctk_tree_model_sort_row_changed))), (tree_model_sort), ((void *)0), (GConnectFlags) 0); | |||
2166 | priv->inserted_id = | |||
2167 | g_signal_connect (child_model, "row-inserted",g_signal_connect_data ((child_model), ("row-inserted"), (((GCallback ) (ctk_tree_model_sort_row_inserted))), (tree_model_sort), (( void*)0), (GConnectFlags) 0) | |||
2168 | G_CALLBACK (ctk_tree_model_sort_row_inserted),g_signal_connect_data ((child_model), ("row-inserted"), (((GCallback ) (ctk_tree_model_sort_row_inserted))), (tree_model_sort), (( void*)0), (GConnectFlags) 0) | |||
2169 | tree_model_sort)g_signal_connect_data ((child_model), ("row-inserted"), (((GCallback ) (ctk_tree_model_sort_row_inserted))), (tree_model_sort), (( void*)0), (GConnectFlags) 0); | |||
2170 | priv->has_child_toggled_id = | |||
2171 | g_signal_connect (child_model, "row-has-child-toggled",g_signal_connect_data ((child_model), ("row-has-child-toggled" ), (((GCallback) (ctk_tree_model_sort_row_has_child_toggled)) ), (tree_model_sort), ((void*)0), (GConnectFlags) 0) | |||
2172 | G_CALLBACK (ctk_tree_model_sort_row_has_child_toggled),g_signal_connect_data ((child_model), ("row-has-child-toggled" ), (((GCallback) (ctk_tree_model_sort_row_has_child_toggled)) ), (tree_model_sort), ((void*)0), (GConnectFlags) 0) | |||
2173 | tree_model_sort)g_signal_connect_data ((child_model), ("row-has-child-toggled" ), (((GCallback) (ctk_tree_model_sort_row_has_child_toggled)) ), (tree_model_sort), ((void*)0), (GConnectFlags) 0); | |||
2174 | priv->deleted_id = | |||
2175 | g_signal_connect (child_model, "row-deleted",g_signal_connect_data ((child_model), ("row-deleted"), (((GCallback ) (ctk_tree_model_sort_row_deleted))), (tree_model_sort), ((void *)0), (GConnectFlags) 0) | |||
2176 | G_CALLBACK (ctk_tree_model_sort_row_deleted),g_signal_connect_data ((child_model), ("row-deleted"), (((GCallback ) (ctk_tree_model_sort_row_deleted))), (tree_model_sort), ((void *)0), (GConnectFlags) 0) | |||
2177 | tree_model_sort)g_signal_connect_data ((child_model), ("row-deleted"), (((GCallback ) (ctk_tree_model_sort_row_deleted))), (tree_model_sort), ((void *)0), (GConnectFlags) 0); | |||
2178 | priv->reordered_id = | |||
2179 | g_signal_connect (child_model, "rows-reordered",g_signal_connect_data ((child_model), ("rows-reordered"), ((( GCallback) (ctk_tree_model_sort_rows_reordered))), (tree_model_sort ), ((void*)0), (GConnectFlags) 0) | |||
2180 | G_CALLBACK (ctk_tree_model_sort_rows_reordered),g_signal_connect_data ((child_model), ("rows-reordered"), ((( GCallback) (ctk_tree_model_sort_rows_reordered))), (tree_model_sort ), ((void*)0), (GConnectFlags) 0) | |||
2181 | tree_model_sort)g_signal_connect_data ((child_model), ("rows-reordered"), ((( GCallback) (ctk_tree_model_sort_rows_reordered))), (tree_model_sort ), ((void*)0), (GConnectFlags) 0); | |||
2182 | ||||
2183 | priv->child_flags = ctk_tree_model_get_flags (child_model); | |||
2184 | n_columns = ctk_tree_model_get_n_columns (child_model); | |||
2185 | ||||
2186 | types = g_new (GType, n_columns)((GType *) g_malloc_n ((n_columns), sizeof (GType))); | |||
2187 | for (i = 0; i < n_columns; i++) | |||
2188 | types[i] = ctk_tree_model_get_column_type (child_model, i); | |||
2189 | ||||
2190 | priv->sort_list = _ctk_tree_data_list_header_new (n_columns, types); | |||
2191 | g_free (types); | |||
2192 | ||||
2193 | priv->default_sort_func = NO_SORT_FUNC((CtkTreeIterCompareFunc) 0x1); | |||
| ||||
2194 | priv->stamp = g_random_int (); | |||
2195 | } | |||
2196 | } | |||
2197 | ||||
2198 | /** | |||
2199 | * ctk_tree_model_sort_get_model: | |||
2200 | * @tree_model: a #CtkTreeModelSort | |||
2201 | * | |||
2202 | * Returns the model the #CtkTreeModelSort is sorting. | |||
2203 | * | |||
2204 | * Returns: (transfer none): the "child model" being sorted | |||
2205 | **/ | |||
2206 | CtkTreeModel * | |||
2207 | ctk_tree_model_sort_get_model (CtkTreeModelSort *tree_model) | |||
2208 | { | |||
2209 | g_return_val_if_fail (CTK_IS_TREE_MODEL_SORT (tree_model), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_model)); GType __t = ((ctk_tree_model_sort_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_SORT (tree_model)"); return (((void*)0)); } } while (0); | |||
2210 | ||||
2211 | return tree_model->priv->child_model; | |||
2212 | } | |||
2213 | ||||
2214 | ||||
2215 | static CtkTreePath * | |||
2216 | ctk_real_tree_model_sort_convert_child_path_to_path (CtkTreeModelSort *tree_model_sort, | |||
2217 | CtkTreePath *child_path, | |||
2218 | gboolean build_levels) | |||
2219 | { | |||
2220 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2221 | gint *child_indices; | |||
2222 | CtkTreePath *retval; | |||
2223 | SortLevel *level; | |||
2224 | gint i; | |||
2225 | ||||
2226 | g_return_val_if_fail (priv->child_model != NULL, NULL)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return (((void*)0)); } } while (0); | |||
2227 | g_return_val_if_fail (child_path != NULL, NULL)do { if ((child_path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "child_path != NULL"); return (((void*)0)); } } while (0); | |||
2228 | ||||
2229 | retval = ctk_tree_path_new (); | |||
2230 | child_indices = ctk_tree_path_get_indices (child_path); | |||
2231 | ||||
2232 | if (priv->root == NULL((void*)0) && build_levels) | |||
2233 | ctk_tree_model_sort_build_level (tree_model_sort, NULL((void*)0), NULL((void*)0)); | |||
2234 | level = SORT_LEVEL (priv->root)((SortLevel *)priv->root); | |||
2235 | ||||
2236 | for (i = 0; i < ctk_tree_path_get_depth (child_path); i++) | |||
2237 | { | |||
2238 | SortElt *tmp; | |||
2239 | GSequenceIter *siter; | |||
2240 | gboolean found_child = FALSE(0); | |||
2241 | ||||
2242 | if (!level) | |||
2243 | { | |||
2244 | ctk_tree_path_free (retval); | |||
2245 | return NULL((void*)0); | |||
2246 | } | |||
2247 | ||||
2248 | if (child_indices[i] >= g_sequence_get_length (level->seq)) | |||
2249 | { | |||
2250 | ctk_tree_path_free (retval); | |||
2251 | return NULL((void*)0); | |||
2252 | } | |||
2253 | tmp = lookup_elt_with_offset (tree_model_sort, level, | |||
2254 | child_indices[i], &siter); | |||
2255 | if (tmp) | |||
2256 | { | |||
2257 | ctk_tree_path_append_index (retval, g_sequence_iter_get_position (siter)); | |||
2258 | if (tmp->children == NULL((void*)0) && build_levels) | |||
2259 | ctk_tree_model_sort_build_level (tree_model_sort, level, tmp); | |||
2260 | ||||
2261 | level = tmp->children; | |||
2262 | found_child = TRUE(!(0)); | |||
2263 | } | |||
2264 | ||||
2265 | if (! found_child) | |||
2266 | { | |||
2267 | ctk_tree_path_free (retval); | |||
2268 | return NULL((void*)0); | |||
2269 | } | |||
2270 | } | |||
2271 | ||||
2272 | return retval; | |||
2273 | } | |||
2274 | ||||
2275 | ||||
2276 | /** | |||
2277 | * ctk_tree_model_sort_convert_child_path_to_path: | |||
2278 | * @tree_model_sort: A #CtkTreeModelSort | |||
2279 | * @child_path: A #CtkTreePath to convert | |||
2280 | * | |||
2281 | * Converts @child_path to a path relative to @tree_model_sort. That is, | |||
2282 | * @child_path points to a path in the child model. The returned path will | |||
2283 | * point to the same row in the sorted model. If @child_path isn’t a valid | |||
2284 | * path on the child model, then %NULL is returned. | |||
2285 | * | |||
2286 | * Returns: (nullable) (transfer full): A newly allocated #CtkTreePath, or %NULL | |||
2287 | **/ | |||
2288 | CtkTreePath * | |||
2289 | ctk_tree_model_sort_convert_child_path_to_path (CtkTreeModelSort *tree_model_sort, | |||
2290 | CtkTreePath *child_path) | |||
2291 | { | |||
2292 | g_return_val_if_fail (CTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_model_sort)); GType __t = ((ctk_tree_model_sort_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_SORT (tree_model_sort)" ); return (((void*)0)); } } while (0); | |||
2293 | g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, NULL)do { if ((tree_model_sort->priv->child_model != ((void* )0))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "tree_model_sort->priv->child_model != NULL" ); return (((void*)0)); } } while (0); | |||
2294 | g_return_val_if_fail (child_path != NULL, NULL)do { if ((child_path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "child_path != NULL"); return (((void*)0)); } } while (0); | |||
2295 | ||||
2296 | return ctk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE(!(0))); | |||
2297 | } | |||
2298 | ||||
2299 | /** | |||
2300 | * ctk_tree_model_sort_convert_child_iter_to_iter: | |||
2301 | * @tree_model_sort: A #CtkTreeModelSort | |||
2302 | * @sort_iter: (out): An uninitialized #CtkTreeIter. | |||
2303 | * @child_iter: A valid #CtkTreeIter pointing to a row on the child model | |||
2304 | * | |||
2305 | * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to | |||
2306 | * the row pointed at by @child_iter. If @sort_iter was not set, %FALSE | |||
2307 | * is returned. Note: a boolean is only returned since 2.14. | |||
2308 | * | |||
2309 | * Returns: %TRUE, if @sort_iter was set, i.e. if @sort_iter is a | |||
2310 | * valid iterator pointer to a visible row in the child model. | |||
2311 | **/ | |||
2312 | gboolean | |||
2313 | ctk_tree_model_sort_convert_child_iter_to_iter (CtkTreeModelSort *tree_model_sort, | |||
2314 | CtkTreeIter *sort_iter, | |||
2315 | CtkTreeIter *child_iter) | |||
2316 | { | |||
2317 | gboolean ret; | |||
2318 | CtkTreePath *child_path, *path; | |||
2319 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2320 | ||||
2321 | g_return_val_if_fail (CTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_model_sort)); GType __t = ((ctk_tree_model_sort_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_SORT (tree_model_sort)" ); return ((0)); } } while (0); | |||
2322 | g_return_val_if_fail (priv->child_model != NULL, FALSE)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return ((0)); } } while (0); | |||
2323 | g_return_val_if_fail (sort_iter != NULL, FALSE)do { if ((sort_iter != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "sort_iter != NULL"); return ((0)); } } while (0); | |||
2324 | g_return_val_if_fail (child_iter != NULL, FALSE)do { if ((child_iter != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "child_iter != NULL"); return ((0)); } } while (0); | |||
2325 | g_return_val_if_fail (sort_iter != child_iter, FALSE)do { if ((sort_iter != child_iter)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "sort_iter != child_iter" ); return ((0)); } } while (0); | |||
2326 | ||||
2327 | sort_iter->stamp = 0; | |||
2328 | ||||
2329 | child_path = ctk_tree_model_get_path (priv->child_model, child_iter); | |||
2330 | g_return_val_if_fail (child_path != NULL, FALSE)do { if ((child_path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "child_path != NULL"); return ((0)); } } while (0); | |||
2331 | ||||
2332 | path = ctk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path); | |||
2333 | ctk_tree_path_free (child_path); | |||
2334 | ||||
2335 | if (!path) | |||
2336 | { | |||
2337 | g_warning ("%s: The conversion of the child path to a CtkTreeModel sort path failed", G_STRLOC"ctktreemodelsort.c" ":" "2337"); | |||
2338 | return FALSE(0); | |||
2339 | } | |||
2340 | ||||
2341 | ret = ctk_tree_model_get_iter (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), | |||
2342 | sort_iter, path); | |||
2343 | ctk_tree_path_free (path); | |||
2344 | ||||
2345 | return ret; | |||
2346 | } | |||
2347 | ||||
2348 | /** | |||
2349 | * ctk_tree_model_sort_convert_path_to_child_path: | |||
2350 | * @tree_model_sort: A #CtkTreeModelSort | |||
2351 | * @sorted_path: A #CtkTreePath to convert | |||
2352 | * | |||
2353 | * Converts @sorted_path to a path on the child model of @tree_model_sort. | |||
2354 | * That is, @sorted_path points to a location in @tree_model_sort. The | |||
2355 | * returned path will point to the same location in the model not being | |||
2356 | * sorted. If @sorted_path does not point to a location in the child model, | |||
2357 | * %NULL is returned. | |||
2358 | * | |||
2359 | * Returns: (nullable) (transfer full): A newly allocated #CtkTreePath, or %NULL | |||
2360 | **/ | |||
2361 | CtkTreePath * | |||
2362 | ctk_tree_model_sort_convert_path_to_child_path (CtkTreeModelSort *tree_model_sort, | |||
2363 | CtkTreePath *sorted_path) | |||
2364 | { | |||
2365 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2366 | gint *sorted_indices; | |||
2367 | CtkTreePath *retval; | |||
2368 | SortLevel *level; | |||
2369 | gint i; | |||
2370 | ||||
2371 | g_return_val_if_fail (CTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_model_sort)); GType __t = ((ctk_tree_model_sort_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_SORT (tree_model_sort)" ); return (((void*)0)); } } while (0); | |||
2372 | g_return_val_if_fail (priv->child_model != NULL, NULL)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return (((void*)0)); } } while (0); | |||
2373 | g_return_val_if_fail (sorted_path != NULL, NULL)do { if ((sorted_path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "sorted_path != NULL"); return (((void*)0)); } } while (0); | |||
2374 | ||||
2375 | retval = ctk_tree_path_new (); | |||
2376 | sorted_indices = ctk_tree_path_get_indices (sorted_path); | |||
2377 | if (priv->root == NULL((void*)0)) | |||
2378 | ctk_tree_model_sort_build_level (tree_model_sort, NULL((void*)0), NULL((void*)0)); | |||
2379 | level = SORT_LEVEL (priv->root)((SortLevel *)priv->root); | |||
2380 | ||||
2381 | for (i = 0; i < ctk_tree_path_get_depth (sorted_path); i++) | |||
2382 | { | |||
2383 | SortElt *elt = NULL((void*)0); | |||
2384 | GSequenceIter *siter; | |||
2385 | ||||
2386 | if ((level == NULL((void*)0)) || | |||
2387 | (g_sequence_get_length (level->seq) <= sorted_indices[i])) | |||
2388 | { | |||
2389 | ctk_tree_path_free (retval); | |||
2390 | return NULL((void*)0); | |||
2391 | } | |||
2392 | ||||
2393 | siter = g_sequence_get_iter_at_pos (level->seq, sorted_indices[i]); | |||
2394 | if (g_sequence_iter_is_end (siter)) | |||
2395 | { | |||
2396 | ctk_tree_path_free (retval); | |||
2397 | return NULL((void*)0); | |||
2398 | } | |||
2399 | ||||
2400 | elt = GET_ELT (siter)((SortElt *) (siter ? g_sequence_get (siter) : ((void*)0))); | |||
2401 | if (elt->children == NULL((void*)0)) | |||
2402 | ctk_tree_model_sort_build_level (tree_model_sort, level, elt); | |||
2403 | ||||
2404 | if (level == NULL((void*)0)) | |||
2405 | { | |||
2406 | ctk_tree_path_free (retval); | |||
2407 | break; | |||
2408 | } | |||
2409 | ||||
2410 | ctk_tree_path_append_index (retval, elt->offset); | |||
2411 | level = elt->children; | |||
2412 | } | |||
2413 | ||||
2414 | return retval; | |||
2415 | } | |||
2416 | ||||
2417 | /** | |||
2418 | * ctk_tree_model_sort_convert_iter_to_child_iter: | |||
2419 | * @tree_model_sort: A #CtkTreeModelSort | |||
2420 | * @child_iter: (out): An uninitialized #CtkTreeIter | |||
2421 | * @sorted_iter: A valid #CtkTreeIter pointing to a row on @tree_model_sort. | |||
2422 | * | |||
2423 | * Sets @child_iter to point to the row pointed to by @sorted_iter. | |||
2424 | **/ | |||
2425 | void | |||
2426 | ctk_tree_model_sort_convert_iter_to_child_iter (CtkTreeModelSort *tree_model_sort, | |||
2427 | CtkTreeIter *child_iter, | |||
2428 | CtkTreeIter *sorted_iter) | |||
2429 | { | |||
2430 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2431 | g_return_if_fail (CTK_IS_TREE_MODEL_SORT (tree_model_sort))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_model_sort)); GType __t = ((ctk_tree_model_sort_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_SORT (tree_model_sort)" ); return; } } while (0); | |||
2432 | g_return_if_fail (priv->child_model != NULL)do { if ((priv->child_model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "priv->child_model != NULL" ); return; } } while (0); | |||
2433 | g_return_if_fail (child_iter != NULL)do { if ((child_iter != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "child_iter != NULL"); return ; } } while (0); | |||
2434 | g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort))do { if ((((sorted_iter) != ((void*)0) && (sorted_iter )->user_data != ((void*)0) && (sorted_iter)->user_data2 != ((void*)0) && (tree_model_sort)->priv->stamp == (sorted_iter)->stamp))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "VALID_ITER (sorted_iter, tree_model_sort)" ); return; } } while (0); | |||
2435 | g_return_if_fail (sorted_iter != child_iter)do { if ((sorted_iter != child_iter)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "sorted_iter != child_iter" ); return; } } while (0); | |||
2436 | ||||
2437 | if (CTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort)(((CtkTreeModelSort *)tree_model_sort)->priv->child_flags &CTK_TREE_MODEL_ITERS_PERSIST)) | |||
2438 | { | |||
2439 | *child_iter = SORT_ELT (sorted_iter->user_data2)((SortElt *)sorted_iter->user_data2)->iter; | |||
2440 | } | |||
2441 | else | |||
2442 | { | |||
2443 | CtkTreePath *path; | |||
2444 | gboolean valid = FALSE(0); | |||
2445 | ||||
2446 | path = ctk_tree_model_sort_elt_get_path (sorted_iter->user_data, | |||
2447 | sorted_iter->user_data2); | |||
2448 | valid = ctk_tree_model_get_iter (priv->child_model, child_iter, path); | |||
2449 | ctk_tree_path_free (path); | |||
2450 | ||||
2451 | g_return_if_fail (valid == TRUE)do { if ((valid == (!(0)))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "valid == TRUE"); return ; } } while (0); | |||
2452 | } | |||
2453 | } | |||
2454 | ||||
2455 | static void | |||
2456 | ctk_tree_model_sort_build_level (CtkTreeModelSort *tree_model_sort, | |||
2457 | SortLevel *parent_level, | |||
2458 | SortElt *parent_elt) | |||
2459 | { | |||
2460 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2461 | CtkTreeIter iter; | |||
2462 | SortLevel *new_level; | |||
2463 | gint length = 0; | |||
2464 | gint i; | |||
2465 | ||||
2466 | g_assert (priv->child_model != NULL)do { if (priv->child_model != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctktreemodelsort.c", 2466, ((const char*) (__func__ )), "priv->child_model != NULL"); } while (0); | |||
2467 | ||||
2468 | if (parent_level == NULL((void*)0)) | |||
2469 | { | |||
2470 | if (ctk_tree_model_get_iter_first (priv->child_model, &iter) == FALSE(0)) | |||
2471 | return; | |||
2472 | length = ctk_tree_model_iter_n_children (priv->child_model, NULL((void*)0)); | |||
2473 | } | |||
2474 | else | |||
2475 | { | |||
2476 | CtkTreeIter parent_iter; | |||
2477 | CtkTreeIter child_parent_iter; | |||
2478 | ||||
2479 | parent_iter.stamp = priv->stamp; | |||
2480 | parent_iter.user_data = parent_level; | |||
2481 | parent_iter.user_data2 = parent_elt; | |||
2482 | ||||
2483 | ctk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort, | |||
2484 | &child_parent_iter, | |||
2485 | &parent_iter); | |||
2486 | if (ctk_tree_model_iter_children (priv->child_model, | |||
2487 | &iter, | |||
2488 | &child_parent_iter) == FALSE(0)) | |||
2489 | return; | |||
2490 | ||||
2491 | /* stamp may have changed */ | |||
2492 | ctk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort, | |||
2493 | &child_parent_iter, | |||
2494 | &parent_iter); | |||
2495 | ||||
2496 | length = ctk_tree_model_iter_n_children (priv->child_model, &child_parent_iter); | |||
2497 | ||||
2498 | ctk_tree_model_sort_ref_node (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), | |||
2499 | &parent_iter); | |||
2500 | } | |||
2501 | ||||
2502 | g_return_if_fail (length > 0)do { if ((length > 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "length > 0"); return ; } } while (0); | |||
2503 | ||||
2504 | new_level = g_new (SortLevel, 1)((SortLevel *) g_malloc_n ((1), sizeof (SortLevel))); | |||
2505 | new_level->seq = g_sequence_new (sort_elt_free); | |||
2506 | new_level->ref_count = 0; | |||
2507 | new_level->parent_level = parent_level; | |||
2508 | new_level->parent_elt = parent_elt; | |||
2509 | ||||
2510 | if (parent_elt) | |||
2511 | parent_elt->children = new_level; | |||
2512 | else | |||
2513 | priv->root = new_level; | |||
2514 | ||||
2515 | /* increase the count of zero ref_counts.*/ | |||
2516 | while (parent_level) | |||
2517 | { | |||
2518 | parent_elt->zero_ref_count++; | |||
2519 | ||||
2520 | parent_elt = parent_level->parent_elt; | |||
2521 | parent_level = parent_level->parent_level; | |||
2522 | } | |||
2523 | ||||
2524 | if (new_level != priv->root) | |||
2525 | priv->zero_ref_count++; | |||
2526 | ||||
2527 | for (i = 0; i < length; i++) | |||
2528 | { | |||
2529 | SortElt *sort_elt; | |||
2530 | ||||
2531 | sort_elt = sort_elt_new (); | |||
2532 | sort_elt->offset = i; | |||
2533 | sort_elt->zero_ref_count = 0; | |||
2534 | sort_elt->ref_count = 0; | |||
2535 | sort_elt->children = NULL((void*)0); | |||
2536 | ||||
2537 | if (CTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort)(((CtkTreeModelSort *)tree_model_sort)->priv->child_flags &CTK_TREE_MODEL_ITERS_PERSIST)) | |||
2538 | { | |||
2539 | sort_elt->iter = iter; | |||
2540 | if (ctk_tree_model_iter_next (priv->child_model, &iter) == FALSE(0) && | |||
2541 | i < length - 1) | |||
2542 | { | |||
2543 | if (parent_level) | |||
2544 | { | |||
2545 | CtkTreePath *level; | |||
2546 | gchar *str; | |||
2547 | ||||
2548 | level = ctk_tree_model_sort_elt_get_path (parent_level, | |||
2549 | parent_elt); | |||
2550 | str = ctk_tree_path_to_string (level); | |||
2551 | ctk_tree_path_free (level); | |||
2552 | ||||
2553 | g_warning ("%s: There is a discrepancy between the sort model " | |||
2554 | "and the child model. The child model is " | |||
2555 | "advertising a wrong length for level %s:.", | |||
2556 | G_STRLOC"ctktreemodelsort.c" ":" "2556", str); | |||
2557 | g_free (str); | |||
2558 | } | |||
2559 | else | |||
2560 | { | |||
2561 | g_warning ("%s: There is a discrepancy between the sort model " | |||
2562 | "and the child model. The child model is " | |||
2563 | "advertising a wrong length for the root level.", | |||
2564 | G_STRLOC"ctktreemodelsort.c" ":" "2564"); | |||
2565 | } | |||
2566 | ||||
2567 | return; | |||
2568 | } | |||
2569 | } | |||
2570 | ||||
2571 | sort_elt->siter = g_sequence_append (new_level->seq, sort_elt); | |||
2572 | } | |||
2573 | ||||
2574 | /* sort level */ | |||
2575 | ctk_tree_model_sort_sort_level (tree_model_sort, new_level, | |||
2576 | FALSE(0), FALSE(0)); | |||
2577 | } | |||
2578 | ||||
2579 | static void | |||
2580 | ctk_tree_model_sort_free_level (CtkTreeModelSort *tree_model_sort, | |||
2581 | SortLevel *sort_level, | |||
2582 | gboolean unref) | |||
2583 | { | |||
2584 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2585 | GSequenceIter *siter; | |||
2586 | GSequenceIter *end_siter; | |||
2587 | ||||
2588 | g_assert (sort_level)do { if (sort_level) ; else g_assertion_message_expr ("Ctk", "ctktreemodelsort.c" , 2588, ((const char*) (__func__)), "sort_level"); } while (0 ); | |||
2589 | ||||
2590 | end_siter = g_sequence_get_end_iter (sort_level->seq); | |||
2591 | for (siter = g_sequence_get_begin_iter (sort_level->seq); | |||
2592 | siter != end_siter; | |||
2593 | siter = g_sequence_iter_next (siter)) | |||
2594 | { | |||
2595 | SortElt *elt = g_sequence_get (siter); | |||
2596 | ||||
2597 | if (elt->children) | |||
2598 | ctk_tree_model_sort_free_level (tree_model_sort, | |||
2599 | elt->children, unref); | |||
2600 | } | |||
2601 | ||||
2602 | if (sort_level->ref_count == 0) | |||
2603 | { | |||
2604 | SortLevel *parent_level = sort_level->parent_level; | |||
2605 | SortElt *parent_elt = sort_level->parent_elt; | |||
2606 | ||||
2607 | while (parent_level) | |||
2608 | { | |||
2609 | parent_elt->zero_ref_count--; | |||
2610 | ||||
2611 | parent_elt = parent_level->parent_elt; | |||
2612 | parent_level = parent_level->parent_level; | |||
2613 | } | |||
2614 | ||||
2615 | if (sort_level != priv->root) | |||
2616 | priv->zero_ref_count--; | |||
2617 | } | |||
2618 | ||||
2619 | if (sort_level->parent_elt) | |||
2620 | { | |||
2621 | if (unref) | |||
2622 | { | |||
2623 | CtkTreeIter parent_iter; | |||
2624 | ||||
2625 | parent_iter.stamp = tree_model_sort->priv->stamp; | |||
2626 | parent_iter.user_data = sort_level->parent_level; | |||
2627 | parent_iter.user_data2 = sort_level->parent_elt; | |||
2628 | ||||
2629 | ctk_tree_model_sort_unref_node (CTK_TREE_MODEL (tree_model_sort)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_model_sort)), ((ctk_tree_model_get_type ())))))), | |||
2630 | &parent_iter); | |||
2631 | } | |||
2632 | ||||
2633 | sort_level->parent_elt->children = NULL((void*)0); | |||
2634 | } | |||
2635 | else | |||
2636 | priv->root = NULL((void*)0); | |||
2637 | ||||
2638 | g_sequence_free (sort_level->seq); | |||
2639 | sort_level->seq = NULL((void*)0); | |||
2640 | ||||
2641 | g_free (sort_level); | |||
2642 | sort_level = NULL((void*)0); | |||
2643 | } | |||
2644 | ||||
2645 | static void | |||
2646 | ctk_tree_model_sort_increment_stamp (CtkTreeModelSort *tree_model_sort) | |||
2647 | { | |||
2648 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2649 | ||||
2650 | do | |||
2651 | { | |||
2652 | priv->stamp++; | |||
2653 | } | |||
2654 | while (priv->stamp == 0); | |||
2655 | ||||
2656 | ctk_tree_model_sort_clear_cache (tree_model_sort); | |||
2657 | } | |||
2658 | ||||
2659 | static void | |||
2660 | ctk_tree_model_sort_clear_cache_helper_iter (gpointer data, | |||
2661 | gpointer user_data) | |||
2662 | { | |||
2663 | CtkTreeModelSort *tree_model_sort = user_data; | |||
2664 | SortElt *elt = data; | |||
2665 | ||||
2666 | if (elt->zero_ref_count > 0) | |||
2667 | ctk_tree_model_sort_clear_cache_helper (tree_model_sort, elt->children); | |||
2668 | } | |||
2669 | ||||
2670 | static void | |||
2671 | ctk_tree_model_sort_clear_cache_helper (CtkTreeModelSort *tree_model_sort, | |||
2672 | SortLevel *level) | |||
2673 | { | |||
2674 | g_assert (level != NULL)do { if (level != ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctktreemodelsort.c", 2674, ((const char*) (__func__ )), "level != NULL"); } while (0); | |||
2675 | ||||
2676 | g_sequence_foreach (level->seq, ctk_tree_model_sort_clear_cache_helper_iter, | |||
2677 | tree_model_sort); | |||
2678 | ||||
2679 | if (level->ref_count == 0 && level != tree_model_sort->priv->root) | |||
2680 | ctk_tree_model_sort_free_level (tree_model_sort, level, TRUE(!(0))); | |||
2681 | } | |||
2682 | ||||
2683 | /** | |||
2684 | * ctk_tree_model_sort_reset_default_sort_func: | |||
2685 | * @tree_model_sort: A #CtkTreeModelSort | |||
2686 | * | |||
2687 | * This resets the default sort function to be in the “unsorted” state. That | |||
2688 | * is, it is in the same order as the child model. It will re-sort the model | |||
2689 | * to be in the same order as the child model only if the #CtkTreeModelSort | |||
2690 | * is in “unsorted” state. | |||
2691 | **/ | |||
2692 | void | |||
2693 | ctk_tree_model_sort_reset_default_sort_func (CtkTreeModelSort *tree_model_sort) | |||
2694 | { | |||
2695 | CtkTreeModelSortPrivate *priv = tree_model_sort->priv; | |||
2696 | ||||
2697 | g_return_if_fail (CTK_IS_TREE_MODEL_SORT (tree_model_sort))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_model_sort)); GType __t = ((ctk_tree_model_sort_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_SORT (tree_model_sort)" ); return; } } while (0); | |||
2698 | ||||
2699 | if (priv->default_sort_destroy) | |||
2700 | { | |||
2701 | GDestroyNotify d = priv->default_sort_destroy; | |||
2702 | ||||
2703 | priv->default_sort_destroy = NULL((void*)0); | |||
2704 | d (priv->default_sort_data); | |||
2705 | } | |||
2706 | ||||
2707 | priv->default_sort_func = NO_SORT_FUNC((CtkTreeIterCompareFunc) 0x1); | |||
2708 | priv->default_sort_data = NULL((void*)0); | |||
2709 | priv->default_sort_destroy = NULL((void*)0); | |||
2710 | ||||
2711 | if (priv->sort_column_id == CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1)) | |||
2712 | ctk_tree_model_sort_sort (tree_model_sort); | |||
2713 | priv->sort_column_id = CTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID(-1); | |||
2714 | } | |||
2715 | ||||
2716 | /** | |||
2717 | * ctk_tree_model_sort_clear_cache: | |||
2718 | * @tree_model_sort: A #CtkTreeModelSort | |||
2719 | * | |||
2720 | * This function should almost never be called. It clears the @tree_model_sort | |||
2721 | * of any cached iterators that haven’t been reffed with | |||
2722 | * ctk_tree_model_ref_node(). This might be useful if the child model being | |||
2723 | * sorted is static (and doesn’t change often) and there has been a lot of | |||
2724 | * unreffed access to nodes. As a side effect of this function, all unreffed | |||
2725 | * iters will be invalid. | |||
2726 | **/ | |||
2727 | void | |||
2728 | ctk_tree_model_sort_clear_cache (CtkTreeModelSort *tree_model_sort) | |||
2729 | { | |||
2730 | g_return_if_fail (CTK_IS_TREE_MODEL_SORT (tree_model_sort))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_model_sort)); GType __t = ((ctk_tree_model_sort_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_SORT (tree_model_sort)" ); return; } } while (0); | |||
2731 | ||||
2732 | if (tree_model_sort->priv->zero_ref_count > 0) | |||
2733 | ctk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->priv->root); | |||
2734 | } | |||
2735 | ||||
2736 | static gboolean | |||
2737 | ctk_tree_model_sort_iter_is_valid_helper (CtkTreeIter *iter, | |||
2738 | SortLevel *level) | |||
2739 | { | |||
2740 | GSequenceIter *siter; | |||
2741 | GSequenceIter *end_siter; | |||
2742 | ||||
2743 | end_siter = g_sequence_get_end_iter (level->seq); | |||
2744 | for (siter = g_sequence_get_begin_iter (level->seq); | |||
2745 | siter != end_siter; siter = g_sequence_iter_next (siter)) | |||
2746 | { | |||
2747 | SortElt *elt = g_sequence_get (siter); | |||
2748 | ||||
2749 | if (iter->user_data == level && iter->user_data2 == elt) | |||
2750 | return TRUE(!(0)); | |||
2751 | ||||
2752 | if (elt->children) | |||
2753 | if (ctk_tree_model_sort_iter_is_valid_helper (iter, elt->children)) | |||
2754 | return TRUE(!(0)); | |||
2755 | } | |||
2756 | ||||
2757 | return FALSE(0); | |||
2758 | } | |||
2759 | ||||
2760 | /** | |||
2761 | * ctk_tree_model_sort_iter_is_valid: | |||
2762 | * @tree_model_sort: A #CtkTreeModelSort. | |||
2763 | * @iter: A #CtkTreeIter. | |||
2764 | * | |||
2765 | * > This function is slow. Only use it for debugging and/or testing | |||
2766 | * > purposes. | |||
2767 | * | |||
2768 | * Checks if the given iter is a valid iter for this #CtkTreeModelSort. | |||
2769 | * | |||
2770 | * Returns: %TRUE if the iter is valid, %FALSE if the iter is invalid. | |||
2771 | * | |||
2772 | * Since: 2.2 | |||
2773 | **/ | |||
2774 | gboolean | |||
2775 | ctk_tree_model_sort_iter_is_valid (CtkTreeModelSort *tree_model_sort, | |||
2776 | CtkTreeIter *iter) | |||
2777 | { | |||
2778 | g_return_val_if_fail (CTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_model_sort)); GType __t = ((ctk_tree_model_sort_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_SORT (tree_model_sort)" ); return ((0)); } } while (0); | |||
2779 | 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); | |||
2780 | ||||
2781 | if (!VALID_ITER (iter, tree_model_sort)((iter) != ((void*)0) && (iter)->user_data != ((void *)0) && (iter)->user_data2 != ((void*)0) && (tree_model_sort)->priv->stamp == (iter)->stamp)) | |||
2782 | return FALSE(0); | |||
2783 | ||||
2784 | return ctk_tree_model_sort_iter_is_valid_helper (iter, | |||
2785 | tree_model_sort->priv->root); | |||
2786 | } |