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