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