| File: | ctk/ctktreemodelsort.c |
| Warning: | line 933, column 4 This statement is never executed |
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) > 0 ? sizeof ( SortElt) : 1))); |
| 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; |
This statement is never executed | |
| 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 | } |