1 /* gtktreestore.c
2 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include "gtktreemodelcssnode.h"
21 #include "gtk/gtkcsstransientnodeprivate.h"
22
23 struct _GtkTreeModelCssNodePrivate
24 {
25 GtkTreeModelCssNodeGetFunc get_func;
26 gint n_columns;
27 GType *column_types;
28
29 GtkCssNode *root;
30 };
31
32 static void gtk_tree_model_css_node_connect_node (GtkTreeModelCssNode *model,
33 GtkCssNode *node,
34 gboolean emit_signal);
35
36 static void gtk_tree_model_css_node_disconnect_node (GtkTreeModelCssNode *model,
37 GtkCssNode *node,
38 gboolean emit_signal,
39 GtkCssNode *parent,
40 GtkCssNode *previous);
41
42 static void gtk_tree_model_css_node_tree_model_init (GtkTreeModelIface *iface);
43
G_DEFINE_TYPE_WITH_CODE(GtkTreeModelCssNode,gtk_tree_model_css_node,G_TYPE_OBJECT,G_ADD_PRIVATE (GtkTreeModelCssNode)G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,gtk_tree_model_css_node_tree_model_init))44 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelCssNode, gtk_tree_model_css_node, G_TYPE_OBJECT,
45 G_ADD_PRIVATE (GtkTreeModelCssNode)
46 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
47 gtk_tree_model_css_node_tree_model_init))
48
49 static GtkCssNode *
50 get_nth_child (GtkCssNode *node,
51 gint i)
52 {
53 for (node = gtk_css_node_get_first_child (node);
54 node != NULL && i > 0;
55 node = gtk_css_node_get_next_sibling (node))
56 i--;
57
58 return node;
59 }
60
61 static int
get_node_index(GtkCssNode * node)62 get_node_index (GtkCssNode *node)
63 {
64 int result = 0;
65
66 while ((node = gtk_css_node_get_previous_sibling (node)))
67 result++;
68
69 return result;
70 }
71
72 static GtkTreeModelFlags
gtk_tree_model_css_node_get_flags(GtkTreeModel * tree_model)73 gtk_tree_model_css_node_get_flags (GtkTreeModel *tree_model)
74 {
75 return GTK_TREE_MODEL_ITERS_PERSIST;
76 }
77
78 static gint
gtk_tree_model_css_node_get_n_columns(GtkTreeModel * tree_model)79 gtk_tree_model_css_node_get_n_columns (GtkTreeModel *tree_model)
80 {
81 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
82 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
83
84 return priv->n_columns;
85 }
86
87 static GType
gtk_tree_model_css_node_get_column_type(GtkTreeModel * tree_model,gint column)88 gtk_tree_model_css_node_get_column_type (GtkTreeModel *tree_model,
89 gint column)
90 {
91 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
92 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
93
94 g_return_val_if_fail (column < priv->n_columns, G_TYPE_INVALID);
95
96 return priv->column_types[column];
97 }
98
99 static gboolean
gtk_tree_model_css_node_get_iter(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreePath * path)100 gtk_tree_model_css_node_get_iter (GtkTreeModel *tree_model,
101 GtkTreeIter *iter,
102 GtkTreePath *path)
103 {
104 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
105 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
106 GtkCssNode *node;
107 int *indices;
108 int depth, i;
109
110 if (priv->root == NULL)
111 return FALSE;
112
113 indices = gtk_tree_path_get_indices (path);
114 depth = gtk_tree_path_get_depth (path);
115
116 if (depth < 1 || indices[0] != 0)
117 return FALSE;
118
119 node = priv->root;
120 for (i = 1; i < depth; i++)
121 {
122 node = get_nth_child (node, indices[i]);
123 if (node == NULL)
124 return FALSE;
125 }
126
127 gtk_tree_model_css_node_get_iter_from_node (nodemodel, iter, node);
128 return TRUE;
129 }
130
131 static GtkTreePath *
gtk_tree_model_css_node_get_path(GtkTreeModel * tree_model,GtkTreeIter * iter)132 gtk_tree_model_css_node_get_path (GtkTreeModel *tree_model,
133 GtkTreeIter *iter)
134 {
135 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
136 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
137 GtkCssNode *node;
138 GtkTreePath *path;
139
140 g_return_val_if_fail (priv->root != NULL, NULL);
141
142 path = gtk_tree_path_new ();
143 node = gtk_tree_model_css_node_get_node_from_iter (nodemodel, iter);
144
145 while (node != priv->root)
146 {
147 gtk_tree_path_prepend_index (path, get_node_index (node));
148 node = gtk_css_node_get_parent (node);
149 }
150
151 gtk_tree_path_prepend_index (path, 0);
152
153 return path;
154 }
155
156 static void
gtk_tree_model_css_node_get_value(GtkTreeModel * tree_model,GtkTreeIter * iter,gint column,GValue * value)157 gtk_tree_model_css_node_get_value (GtkTreeModel *tree_model,
158 GtkTreeIter *iter,
159 gint column,
160 GValue *value)
161 {
162 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
163 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
164
165 g_value_init (value, priv->column_types[column]);
166 priv->get_func (nodemodel,
167 gtk_tree_model_css_node_get_node_from_iter (nodemodel, iter),
168 column,
169 value);
170 }
171
172 static gboolean
gtk_tree_model_css_node_iter_next(GtkTreeModel * tree_model,GtkTreeIter * iter)173 gtk_tree_model_css_node_iter_next (GtkTreeModel *tree_model,
174 GtkTreeIter *iter)
175 {
176 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
177 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
178 GtkCssNode *node;
179
180 node = gtk_tree_model_css_node_get_node_from_iter (nodemodel, iter);
181 if (node == priv->root)
182 return FALSE;
183
184 node = gtk_css_node_get_next_sibling (node);
185 if (node == NULL)
186 return FALSE;
187
188 gtk_tree_model_css_node_get_iter_from_node (nodemodel, iter, node);
189 return TRUE;
190 }
191
192 static gboolean
gtk_tree_model_css_node_iter_previous(GtkTreeModel * tree_model,GtkTreeIter * iter)193 gtk_tree_model_css_node_iter_previous (GtkTreeModel *tree_model,
194 GtkTreeIter *iter)
195 {
196 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
197 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
198 GtkCssNode *node;
199
200 node = gtk_tree_model_css_node_get_node_from_iter (nodemodel, iter);
201 if (node == priv->root)
202 return FALSE;
203
204 node = gtk_css_node_get_previous_sibling (node);
205 if (node == NULL)
206 return FALSE;
207
208 gtk_tree_model_css_node_get_iter_from_node (nodemodel, iter, node);
209 return TRUE;
210 }
211
212 static gboolean
gtk_tree_model_css_node_iter_children(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * parent)213 gtk_tree_model_css_node_iter_children (GtkTreeModel *tree_model,
214 GtkTreeIter *iter,
215 GtkTreeIter *parent)
216 {
217 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
218 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
219 GtkCssNode *node;
220
221 if (parent == NULL)
222 {
223 node = priv->root;
224 }
225 else
226 {
227 node = gtk_tree_model_css_node_get_node_from_iter (nodemodel, parent);
228 node = gtk_css_node_get_first_child (node);
229 }
230 if (node == NULL)
231 return FALSE;
232
233 gtk_tree_model_css_node_get_iter_from_node (nodemodel, iter, node);
234 return TRUE;
235 }
236
237 static gboolean
gtk_tree_model_css_node_iter_has_child(GtkTreeModel * tree_model,GtkTreeIter * iter)238 gtk_tree_model_css_node_iter_has_child (GtkTreeModel *tree_model,
239 GtkTreeIter *iter)
240 {
241 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
242 GtkCssNode *node;
243
244 node = gtk_tree_model_css_node_get_node_from_iter (nodemodel, iter);
245
246 return gtk_css_node_get_first_child (node) != NULL;
247 }
248
249 static gint
gtk_tree_model_css_node_iter_n_children(GtkTreeModel * tree_model,GtkTreeIter * iter)250 gtk_tree_model_css_node_iter_n_children (GtkTreeModel *tree_model,
251 GtkTreeIter *iter)
252 {
253 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
254 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
255 GtkCssNode *node;
256
257 if (iter == NULL)
258 return priv->root ? 1 : 0;
259
260 node = gtk_tree_model_css_node_get_node_from_iter (nodemodel, iter);
261
262 node = gtk_css_node_get_last_child (node);
263 if (node == NULL)
264 return 0;
265
266 return get_node_index (node) + 1;
267 }
268
269 static gboolean
gtk_tree_model_css_node_iter_nth_child(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * parent,gint n)270 gtk_tree_model_css_node_iter_nth_child (GtkTreeModel *tree_model,
271 GtkTreeIter *iter,
272 GtkTreeIter *parent,
273 gint n)
274 {
275 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
276 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
277 GtkCssNode *node;
278
279 if (parent == NULL)
280 {
281 if (n > 0)
282 return FALSE;
283
284 node = priv->root;
285 }
286 else
287 {
288 node = gtk_tree_model_css_node_get_node_from_iter (nodemodel, parent);
289 node = get_nth_child (node, n);
290 }
291
292 if (node == NULL)
293 return FALSE;
294
295 gtk_tree_model_css_node_get_iter_from_node (nodemodel, iter, node);
296 return TRUE;
297 }
298
299 static gboolean
gtk_tree_model_css_node_iter_parent(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * child)300 gtk_tree_model_css_node_iter_parent (GtkTreeModel *tree_model,
301 GtkTreeIter *iter,
302 GtkTreeIter *child)
303 {
304 GtkTreeModelCssNode *nodemodel = GTK_TREE_MODEL_CSS_NODE (tree_model);
305 GtkTreeModelCssNodePrivate *priv = nodemodel->priv;
306 GtkCssNode *node;
307
308 node = gtk_tree_model_css_node_get_node_from_iter (nodemodel, child);
309 if (node == priv->root)
310 return FALSE;
311
312 node = gtk_css_node_get_parent (node);
313
314 gtk_tree_model_css_node_get_iter_from_node (nodemodel, iter, node);
315 return TRUE;
316 }
317
318 static void
gtk_tree_model_css_node_tree_model_init(GtkTreeModelIface * iface)319 gtk_tree_model_css_node_tree_model_init (GtkTreeModelIface *iface)
320 {
321 iface->get_flags = gtk_tree_model_css_node_get_flags;
322 iface->get_n_columns = gtk_tree_model_css_node_get_n_columns;
323 iface->get_column_type = gtk_tree_model_css_node_get_column_type;
324 iface->get_iter = gtk_tree_model_css_node_get_iter;
325 iface->get_path = gtk_tree_model_css_node_get_path;
326 iface->get_value = gtk_tree_model_css_node_get_value;
327 iface->iter_next = gtk_tree_model_css_node_iter_next;
328 iface->iter_previous = gtk_tree_model_css_node_iter_previous;
329 iface->iter_children = gtk_tree_model_css_node_iter_children;
330 iface->iter_has_child = gtk_tree_model_css_node_iter_has_child;
331 iface->iter_n_children = gtk_tree_model_css_node_iter_n_children;
332 iface->iter_nth_child = gtk_tree_model_css_node_iter_nth_child;
333 iface->iter_parent = gtk_tree_model_css_node_iter_parent;
334 }
335
336 static void
gtk_tree_model_css_node_finalize(GObject * object)337 gtk_tree_model_css_node_finalize (GObject *object)
338 {
339 GtkTreeModelCssNode *model = GTK_TREE_MODEL_CSS_NODE (object);
340 GtkTreeModelCssNodePrivate *priv = model->priv;
341
342 if (priv->root)
343 {
344 gtk_tree_model_css_node_disconnect_node (model, priv->root, FALSE, NULL, NULL);
345 priv->root = NULL;
346 }
347
348 G_OBJECT_CLASS (gtk_tree_model_css_node_parent_class)->finalize (object);
349 }
350
351 static void
gtk_tree_model_css_node_class_init(GtkTreeModelCssNodeClass * class)352 gtk_tree_model_css_node_class_init (GtkTreeModelCssNodeClass *class)
353 {
354 GObjectClass *object_class = G_OBJECT_CLASS (class);
355
356 object_class->finalize = gtk_tree_model_css_node_finalize;
357 }
358
359 static void
gtk_tree_model_css_node_init(GtkTreeModelCssNode * nodemodel)360 gtk_tree_model_css_node_init (GtkTreeModelCssNode *nodemodel)
361 {
362 nodemodel->priv = gtk_tree_model_css_node_get_instance_private (nodemodel);
363 }
364
365 GtkTreeModel *
gtk_tree_model_css_node_new(GtkTreeModelCssNodeGetFunc get_func,gint n_columns,...)366 gtk_tree_model_css_node_new (GtkTreeModelCssNodeGetFunc get_func,
367 gint n_columns,
368 ...)
369 {
370 GtkTreeModel *result;
371 va_list args;
372 GType *types;
373 gint i;
374
375 g_return_val_if_fail (get_func != NULL, NULL);
376 g_return_val_if_fail (n_columns > 0, NULL);
377
378 types = g_new (GType, n_columns);
379 va_start (args, n_columns);
380
381 for (i = 0; i < n_columns; i++)
382 {
383 types[i] = va_arg (args, GType);
384 }
385
386 va_end (args);
387
388 result = gtk_tree_model_css_node_newv (get_func, n_columns, types);
389
390 g_free (types);
391
392 return result;
393 }
394
395 GtkTreeModel *
gtk_tree_model_css_node_newv(GtkTreeModelCssNodeGetFunc get_func,gint n_columns,GType * types)396 gtk_tree_model_css_node_newv (GtkTreeModelCssNodeGetFunc get_func,
397 gint n_columns,
398 GType *types)
399 {
400 GtkTreeModelCssNode *result;
401 GtkTreeModelCssNodePrivate *priv;
402
403 g_return_val_if_fail (get_func != NULL, NULL);
404 g_return_val_if_fail (n_columns > 0, NULL);
405 g_return_val_if_fail (types != NULL, NULL);
406
407 result = g_object_new (GTK_TYPE_TREE_MODEL_CSS_NODE, NULL);
408 priv = result->priv;
409
410 priv->get_func = get_func;
411 priv->n_columns = n_columns;
412 priv->column_types = g_memdup (types, sizeof (GType) * n_columns);
413
414 return GTK_TREE_MODEL (result);
415 }
416
417 static void
child_added_cb(GtkCssNode * node,GtkCssNode * child,GtkCssNode * previous,GtkTreeModelCssNode * model)418 child_added_cb (GtkCssNode *node,
419 GtkCssNode *child,
420 GtkCssNode *previous,
421 GtkTreeModelCssNode *model)
422 {
423 gtk_tree_model_css_node_connect_node (model, child, TRUE);
424 }
425
426 static void
child_removed_cb(GtkCssNode * node,GtkCssNode * child,GtkCssNode * previous,GtkTreeModelCssNode * model)427 child_removed_cb (GtkCssNode *node,
428 GtkCssNode *child,
429 GtkCssNode *previous,
430 GtkTreeModelCssNode *model)
431 {
432 gtk_tree_model_css_node_disconnect_node (model, child, TRUE, node, previous);
433 }
434
435 static void
notify_cb(GtkCssNode * node,GParamSpec * pspec,GtkTreeModelCssNode * model)436 notify_cb (GtkCssNode *node,
437 GParamSpec *pspec,
438 GtkTreeModelCssNode *model)
439 {
440 GtkTreeIter iter;
441 GtkTreePath *path;
442
443 gtk_tree_model_css_node_get_iter_from_node (model, &iter, node);
444 path = gtk_tree_model_css_node_get_path (GTK_TREE_MODEL (model), &iter);
445
446 gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
447
448 gtk_tree_path_free (path);
449 }
450
451 static void
style_changed_cb(GtkCssNode * node,GtkCssStyleChange * change,GtkTreeModelCssNode * model)452 style_changed_cb (GtkCssNode *node,
453 GtkCssStyleChange *change,
454 GtkTreeModelCssNode *model)
455 {
456 GtkTreeIter iter;
457 GtkTreePath *path;
458
459 gtk_tree_model_css_node_get_iter_from_node (model, &iter, node);
460 path = gtk_tree_model_css_node_get_path (GTK_TREE_MODEL (model), &iter);
461
462 gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
463
464 gtk_tree_path_free (path);
465 }
466
467 static void
gtk_tree_model_css_node_connect_node(GtkTreeModelCssNode * model,GtkCssNode * node,gboolean emit_signal)468 gtk_tree_model_css_node_connect_node (GtkTreeModelCssNode *model,
469 GtkCssNode *node,
470 gboolean emit_signal)
471 {
472 GtkCssNode *child;
473
474 if (GTK_IS_CSS_TRANSIENT_NODE (node))
475 return;
476
477 g_object_ref (node);
478
479 g_signal_connect_after (node, "node-added", G_CALLBACK (child_added_cb), model);
480 g_signal_connect_after (node, "node-removed", G_CALLBACK (child_removed_cb), model);
481 g_signal_connect_after (node, "notify", G_CALLBACK (notify_cb), model);
482 g_signal_connect_after (node, "style-changed", G_CALLBACK (style_changed_cb), model);
483
484 for (child = gtk_css_node_get_first_child (node);
485 child;
486 child = gtk_css_node_get_next_sibling (child))
487 {
488 gtk_tree_model_css_node_connect_node (model, child, FALSE);
489 }
490
491 if (emit_signal)
492 {
493 GtkTreeIter iter;
494 GtkTreePath *path;
495
496 if (node != model->priv->root &&
497 gtk_css_node_get_previous_sibling (node) == NULL &&
498 gtk_css_node_get_next_sibling (node) == NULL)
499 {
500 /* We're the first child of the parent */
501 gtk_tree_model_css_node_get_iter_from_node (model, &iter, gtk_css_node_get_parent (node));
502 path = gtk_tree_model_css_node_get_path (GTK_TREE_MODEL (model), &iter);
503 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model), path, &iter);
504 gtk_tree_path_free (path);
505 }
506
507 gtk_tree_model_css_node_get_iter_from_node (model, &iter, node);
508 path = gtk_tree_model_css_node_get_path (GTK_TREE_MODEL (model), &iter);
509 gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter);
510 if (gtk_css_node_get_first_child (node))
511 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model), path, &iter);
512
513 gtk_tree_path_free (path);
514 }
515 }
516
517 static void
gtk_tree_model_css_node_disconnect_node(GtkTreeModelCssNode * model,GtkCssNode * node,gboolean emit_signal,GtkCssNode * parent,GtkCssNode * previous)518 gtk_tree_model_css_node_disconnect_node (GtkTreeModelCssNode *model,
519 GtkCssNode *node,
520 gboolean emit_signal,
521 GtkCssNode *parent,
522 GtkCssNode *previous)
523 {
524 GtkCssNode *child;
525
526 if (GTK_IS_CSS_TRANSIENT_NODE (node))
527 return;
528
529 g_signal_handlers_disconnect_by_func (node, G_CALLBACK (child_added_cb), model);
530 g_signal_handlers_disconnect_by_func (node, G_CALLBACK (child_removed_cb), model);
531 g_signal_handlers_disconnect_by_func (node, G_CALLBACK (notify_cb), model);
532 g_signal_handlers_disconnect_by_func (node, G_CALLBACK (style_changed_cb), model);
533
534 for (child = gtk_css_node_get_first_child (node);
535 child;
536 child = gtk_css_node_get_next_sibling (child))
537 {
538 gtk_tree_model_css_node_disconnect_node (model, child, FALSE, NULL, NULL);
539 }
540
541 if (emit_signal)
542 {
543 GtkTreeIter iter;
544 GtkTreePath *path;
545
546 if (parent)
547 {
548 gtk_tree_model_css_node_get_iter_from_node (model, &iter, parent);
549 path = gtk_tree_model_css_node_get_path (GTK_TREE_MODEL (model), &iter);
550 }
551 else
552 {
553 path = gtk_tree_path_new ();
554 }
555 if (previous)
556 gtk_tree_path_append_index (path, get_node_index (previous) + 1);
557 else
558 gtk_tree_path_append_index (path, 0);
559
560 gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
561
562 if (parent && gtk_css_node_get_first_child (parent) == NULL)
563 {
564 gtk_tree_path_up (path);
565 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model), path, &iter);
566 }
567
568 gtk_tree_path_free (path);
569 }
570
571 g_object_unref (node);
572 }
573
574 void
gtk_tree_model_css_node_set_root_node(GtkTreeModelCssNode * model,GtkCssNode * node)575 gtk_tree_model_css_node_set_root_node (GtkTreeModelCssNode *model,
576 GtkCssNode *node)
577 {
578 GtkTreeModelCssNodePrivate *priv;
579
580 g_return_if_fail (GTK_IS_TREE_MODEL_CSS_NODE (model));
581 g_return_if_fail (node == NULL || GTK_IS_CSS_NODE (node));
582
583 priv = model->priv;
584
585 if (priv->root == node)
586 return;
587
588 if (priv->root)
589 {
590 gtk_tree_model_css_node_disconnect_node (model, priv->root, TRUE, NULL, NULL);
591 priv->root = NULL;
592 }
593
594 if (node)
595 {
596 priv->root = node;
597 gtk_tree_model_css_node_connect_node (model, node, TRUE);
598 }
599 }
600
601 GtkCssNode *
gtk_tree_model_css_node_get_root_node(GtkTreeModelCssNode * model)602 gtk_tree_model_css_node_get_root_node (GtkTreeModelCssNode *model)
603 {
604 g_return_val_if_fail (GTK_IS_TREE_MODEL_CSS_NODE (model), NULL);
605
606 return model->priv->root;
607 }
608
609 GtkCssNode *
gtk_tree_model_css_node_get_node_from_iter(GtkTreeModelCssNode * model,GtkTreeIter * iter)610 gtk_tree_model_css_node_get_node_from_iter (GtkTreeModelCssNode *model,
611 GtkTreeIter *iter)
612 {
613 g_return_val_if_fail (GTK_IS_TREE_MODEL_CSS_NODE (model), NULL);
614 g_return_val_if_fail (iter != NULL, NULL);
615 g_return_val_if_fail (iter->user_data == model, NULL);
616 g_return_val_if_fail (GTK_IS_CSS_NODE (iter->user_data2), NULL);
617
618 return iter->user_data2;
619 }
620
621 void
gtk_tree_model_css_node_get_iter_from_node(GtkTreeModelCssNode * model,GtkTreeIter * iter,GtkCssNode * node)622 gtk_tree_model_css_node_get_iter_from_node (GtkTreeModelCssNode *model,
623 GtkTreeIter *iter,
624 GtkCssNode *node)
625 {
626 g_return_if_fail (GTK_IS_TREE_MODEL_CSS_NODE (model));
627 g_return_if_fail (iter != NULL);
628 g_return_if_fail (GTK_IS_CSS_NODE (node));
629
630 iter->user_data = model;
631 iter->user_data2 = node;
632 }
633