Updated Spanish translation
[evolution.git] / e-util / e-tree-model.c
blob1bf702ca344adaea620e42fb325daf70c8134ac7
1 /*
2 * e-tree-model.c
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 #include "e-tree-model.h"
20 enum {
21 PRE_CHANGE,
22 NODE_CHANGED,
23 NODE_DATA_CHANGED,
24 NODE_INSERTED,
25 NODE_REMOVED,
26 NODE_DELETED,
27 REBUILT,
28 LAST_SIGNAL
31 static guint signals[LAST_SIGNAL];
33 G_DEFINE_INTERFACE (ETreeModel, e_tree_model, G_TYPE_OBJECT)
35 static void
36 e_tree_model_default_init (ETreeModelInterface *iface)
38 signals[PRE_CHANGE] = g_signal_new (
39 "pre_change",
40 G_TYPE_FROM_INTERFACE (iface),
41 G_SIGNAL_RUN_LAST,
42 G_STRUCT_OFFSET (ETreeModelInterface, pre_change),
43 NULL, NULL, NULL,
44 G_TYPE_NONE, 0);
46 signals[REBUILT] = g_signal_new (
47 "rebuilt",
48 G_TYPE_FROM_INTERFACE (iface),
49 G_SIGNAL_RUN_LAST,
50 G_STRUCT_OFFSET (ETreeModelInterface, rebuilt),
51 NULL, NULL, NULL,
52 G_TYPE_NONE, 0);
54 signals[NODE_CHANGED] = g_signal_new (
55 "node_changed",
56 G_TYPE_FROM_INTERFACE (iface),
57 G_SIGNAL_RUN_LAST,
58 G_STRUCT_OFFSET (ETreeModelInterface, node_changed),
59 NULL, NULL, NULL,
60 G_TYPE_NONE, 1,
61 G_TYPE_POINTER);
63 signals[NODE_DATA_CHANGED] = g_signal_new (
64 "node_data_changed",
65 G_TYPE_FROM_INTERFACE (iface),
66 G_SIGNAL_RUN_LAST,
67 G_STRUCT_OFFSET (ETreeModelInterface, node_data_changed),
68 NULL, NULL, NULL,
69 G_TYPE_NONE, 1,
70 G_TYPE_POINTER);
72 signals[NODE_INSERTED] = g_signal_new (
73 "node_inserted",
74 G_TYPE_FROM_INTERFACE (iface),
75 G_SIGNAL_RUN_LAST,
76 G_STRUCT_OFFSET (ETreeModelInterface, node_inserted),
77 NULL, NULL, NULL,
78 G_TYPE_NONE, 2,
79 G_TYPE_POINTER,
80 G_TYPE_POINTER);
82 signals[NODE_REMOVED] = g_signal_new (
83 "node_removed",
84 G_TYPE_FROM_INTERFACE (iface),
85 G_SIGNAL_RUN_LAST,
86 G_STRUCT_OFFSET (ETreeModelInterface, node_removed),
87 NULL, NULL, NULL,
88 G_TYPE_NONE, 3,
89 G_TYPE_POINTER,
90 G_TYPE_POINTER,
91 G_TYPE_INT);
93 signals[NODE_DELETED] = g_signal_new (
94 "node_deleted",
95 G_TYPE_FROM_INTERFACE (iface),
96 G_SIGNAL_RUN_LAST,
97 G_STRUCT_OFFSET (ETreeModelInterface, node_deleted),
98 NULL, NULL, NULL,
99 G_TYPE_NONE, 1,
100 G_TYPE_POINTER);
104 * e_tree_model_pre_change:
105 * @tree_model:
107 * Return value:
109 void
110 e_tree_model_pre_change (ETreeModel *tree_model)
112 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
114 g_signal_emit (tree_model, signals[PRE_CHANGE], 0);
118 * e_tree_model_rebuilt:
119 * @tree_model:
121 * Return value:
123 void
124 e_tree_model_rebuilt (ETreeModel *tree_model)
126 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
128 g_signal_emit (tree_model, signals[REBUILT], 0);
131 * e_tree_model_node_changed:
132 * @tree_model:
133 * @path:
137 * Return value:
139 void
140 e_tree_model_node_changed (ETreeModel *tree_model,
141 ETreePath path)
143 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
145 g_signal_emit (tree_model, signals[NODE_CHANGED], 0, path);
149 * e_tree_model_node_data_changed:
150 * @tree_model:
151 * @path:
155 * Return value:
157 void
158 e_tree_model_node_data_changed (ETreeModel *tree_model,
159 ETreePath path)
161 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
163 g_signal_emit (tree_model, signals[NODE_DATA_CHANGED], 0, path);
167 * e_tree_model_node_inserted:
168 * @tree_model:
169 * @parent_path:
170 * @inserted_path:
174 void
175 e_tree_model_node_inserted (ETreeModel *tree_model,
176 ETreePath parent_path,
177 ETreePath inserted_path)
179 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
181 g_signal_emit (
182 tree_model, signals[NODE_INSERTED], 0,
183 parent_path, inserted_path);
187 * e_tree_model_node_removed:
188 * @tree_model:
189 * @parent_path:
190 * @removed_path:
194 void
195 e_tree_model_node_removed (ETreeModel *tree_model,
196 ETreePath parent_path,
197 ETreePath removed_path,
198 gint old_position)
200 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
202 g_signal_emit (
203 tree_model, signals[NODE_REMOVED], 0,
204 parent_path, removed_path, old_position);
208 * e_tree_model_node_deleted:
209 * @tree_model:
210 * @deleted_path:
214 void
215 e_tree_model_node_deleted (ETreeModel *tree_model,
216 ETreePath deleted_path)
218 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
220 g_signal_emit (tree_model, signals[NODE_DELETED], 0, deleted_path);
224 * e_tree_model_get_root
225 * @tree_model: the ETreeModel of which we want the root node.
227 * Accessor for the root node of @tree_model.
229 * return values: the ETreePath corresponding to the root node.
231 ETreePath
232 e_tree_model_get_root (ETreeModel *tree_model)
234 ETreeModelInterface *iface;
236 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
238 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
239 g_return_val_if_fail (iface->get_root != NULL, NULL);
241 return iface->get_root (tree_model);
245 * e_tree_model_node_get_parent:
246 * @tree_model:
247 * @path:
251 * Return value:
253 ETreePath
254 e_tree_model_node_get_parent (ETreeModel *tree_model,
255 ETreePath path)
257 ETreeModelInterface *iface;
259 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
261 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
262 g_return_val_if_fail (iface->get_parent != NULL, NULL);
264 return iface->get_parent (tree_model, path);
268 * e_tree_model_node_get_first_child:
269 * @tree_model:
270 * @path:
274 * Return value:
276 ETreePath
277 e_tree_model_node_get_first_child (ETreeModel *tree_model,
278 ETreePath path)
280 ETreeModelInterface *iface;
282 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
284 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
285 g_return_val_if_fail (iface->get_first_child != NULL, NULL);
287 return iface->get_first_child (tree_model, path);
291 * e_tree_model_node_get_next:
292 * @tree_model:
293 * @path:
297 * Return value:
299 ETreePath
300 e_tree_model_node_get_next (ETreeModel *tree_model,
301 ETreePath path)
303 ETreeModelInterface *iface;
305 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
307 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
308 g_return_val_if_fail (iface->get_next != NULL, NULL);
310 return iface->get_next (tree_model, path);
314 * e_tree_model_node_is_root:
315 * @tree_model:
316 * @path:
320 * Return value:
322 gboolean
323 e_tree_model_node_is_root (ETreeModel *tree_model,
324 ETreePath path)
326 ETreeModelInterface *iface;
328 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), FALSE);
330 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
331 g_return_val_if_fail (iface->is_root != NULL, FALSE);
333 return iface->is_root (tree_model, path);
337 * e_tree_model_node_is_expandable:
338 * @tree_model:
339 * @path:
343 * Return value:
345 gboolean
346 e_tree_model_node_is_expandable (ETreeModel *tree_model,
347 ETreePath path)
349 ETreeModelInterface *iface;
351 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), FALSE);
352 g_return_val_if_fail (path != NULL, FALSE);
354 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
355 g_return_val_if_fail (iface->is_expandable != NULL, FALSE);
357 return iface->is_expandable (tree_model, path);
360 guint
361 e_tree_model_node_get_n_nodes (ETreeModel *tree_model)
363 ETreeModelInterface *iface;
365 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), 0);
367 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
368 g_return_val_if_fail (iface->get_n_nodes != NULL, 0);
370 return iface->get_n_nodes (tree_model);
373 guint
374 e_tree_model_node_get_n_children (ETreeModel *tree_model,
375 ETreePath path)
377 ETreeModelInterface *iface;
379 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), 0);
381 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
382 g_return_val_if_fail (iface->get_n_children != NULL, 0);
384 return iface->get_n_children (tree_model, path);
388 * e_tree_model_node_depth:
389 * @tree_model:
390 * @path:
394 * Return value:
396 guint
397 e_tree_model_node_depth (ETreeModel *tree_model,
398 ETreePath path)
400 ETreeModelInterface *iface;
402 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), 0);
404 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
405 g_return_val_if_fail (iface->depth != NULL, 0);
407 return iface->depth (tree_model, path);
411 * e_tree_model_get_expanded_default
412 * @tree_model: The ETreeModel.
414 * XXX docs here.
416 * return values: Whether nodes should be expanded by default.
418 gboolean
419 e_tree_model_get_expanded_default (ETreeModel *tree_model)
421 ETreeModelInterface *iface;
423 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), FALSE);
425 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
426 g_return_val_if_fail (iface->get_expanded_default != NULL, FALSE);
428 return iface->get_expanded_default (tree_model);
432 * e_tree_model_column_count
433 * @tree_model: The ETreeModel.
435 * XXX docs here.
437 * return values: The number of columns
439 gint
440 e_tree_model_column_count (ETreeModel *tree_model)
442 ETreeModelInterface *iface;
444 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), 0);
446 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
447 g_return_val_if_fail (iface->column_count != NULL, 0);
449 return iface->column_count (tree_model);
453 * e_tree_model_get_save_id
454 * @tree_model: The ETreeModel.
455 * @path: The ETreePath.
457 * XXX docs here.
459 * return values: The save id for this path.
461 gchar *
462 e_tree_model_get_save_id (ETreeModel *tree_model,
463 ETreePath path)
465 ETreeModelInterface *iface;
467 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
469 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
470 g_return_val_if_fail (iface->get_save_id != NULL, NULL);
472 return iface->get_save_id (tree_model, path);
476 * e_tree_model_get_node_by_id
477 * @tree_model: The ETreeModel.
478 * @save_id:
480 * get_node_by_id(get_save_id(node)) should be the original node.
481 * Likewise if get_node_by_id is not NULL, then
482 * get_save_id(get_node_by_id(string)) should be a copy of the
483 * original string.
485 * return values: The path for this save id.
487 ETreePath
488 e_tree_model_get_node_by_id (ETreeModel *tree_model,
489 const gchar *save_id)
491 ETreeModelInterface *iface;
493 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
495 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
496 g_return_val_if_fail (iface->get_node_by_id != NULL, NULL);
498 return iface->get_node_by_id (tree_model, save_id);
502 * e_tree_model_sort_value_at:
503 * @tree_model: The ETreeModel.
504 * @path: The ETreePath to the node we're getting the data from.
505 * @col: the column to retrieve data from
507 * Return value: This function returns the value that is stored by the
508 * @tree_model in column @col and node @path. The data returned can be a
509 * pointer or any data value that can be stored inside a pointer.
511 * The data returned is typically used by an sort renderer if it wants
512 * to proxy the data of cell value_at at a better sorting order.
514 * The data returned must be valid until the model sends a signal that
515 * affect that piece of data. node_changed and node_deleted affect
516 * all data in tha t node and all nodes under that node.
517 * node_data_changed affects the data in that node. node_col_changed
518 * affects the data in that node for that column. node_inserted,
519 * node_removed, and no_change don't affect any data in this way.
521 gpointer
522 e_tree_model_sort_value_at (ETreeModel *tree_model,
523 ETreePath path,
524 gint col)
526 ETreeModelInterface *iface;
528 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
530 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
531 g_return_val_if_fail (iface->sort_value_at != NULL, NULL);
533 return iface->sort_value_at (tree_model, path, col);
537 * e_tree_model_value_at:
538 * @tree_model: The ETreeModel.
539 * @path: The ETreePath to the node we're getting the data from.
540 * @col: the column to retrieve data from
542 * Return value: This function returns the value that is stored by the
543 * @tree_model in column @col and node @path. The data returned can be a
544 * pointer or any data value that can be stored inside a pointer.
546 * The data returned is typically used by an ECell renderer.
548 * The data returned must be valid until the model sends a signal that
549 * affect that piece of data. node_changed and node_deleted affect
550 * all data in tha t node and all nodes under that node.
551 * node_data_changed affects the data in that node. node_col_changed
552 * affects the data in that node for that column. node_inserted,
553 * node_removed, and no_change don't affect any data in this way.
555 gpointer
556 e_tree_model_value_at (ETreeModel *tree_model,
557 ETreePath path,
558 gint col)
560 ETreeModelInterface *iface;
562 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
564 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
565 g_return_val_if_fail (iface->value_at != NULL, NULL);
567 return iface->value_at (tree_model, path, col);
571 * e_tree_model_duplicate_value:
572 * @tree_model:
573 * @col:
574 * @value:
577 * Return value:
579 gpointer
580 e_tree_model_duplicate_value (ETreeModel *tree_model,
581 gint col,
582 gconstpointer value)
584 ETreeModelInterface *iface;
586 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
588 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
589 g_return_val_if_fail (iface->duplicate_value != NULL, NULL);
591 return iface->duplicate_value (tree_model, col, value);
595 * e_tree_model_free_value:
596 * @tree_model:
597 * @col:
598 * @value:
601 * Return value:
603 void
604 e_tree_model_free_value (ETreeModel *tree_model,
605 gint col,
606 gpointer value)
608 ETreeModelInterface *iface;
610 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
612 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
613 g_return_if_fail (iface->free_value != NULL);
615 iface->free_value (tree_model, col, value);
619 * e_tree_model_initialize_value:
620 * @tree_model:
621 * @col:
625 * Return value:
627 gpointer
628 e_tree_model_initialize_value (ETreeModel *tree_model,
629 gint col)
631 ETreeModelInterface *iface;
633 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
635 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
636 g_return_val_if_fail (iface->initialize_value != NULL, NULL);
638 return iface->initialize_value (tree_model, col);
642 * e_tree_model_value_is_empty:
643 * @tree_model:
644 * @col:
645 * @value:
648 * Return value:
650 gboolean
651 e_tree_model_value_is_empty (ETreeModel *tree_model,
652 gint col,
653 gconstpointer value)
655 ETreeModelInterface *iface;
657 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), TRUE);
659 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
660 g_return_val_if_fail (iface->value_is_empty != NULL, TRUE);
662 return iface->value_is_empty (tree_model, col, value);
666 * e_tree_model_value_to_string:
667 * @tree_model:
668 * @col:
669 * @value:
672 * Return value:
674 gchar *
675 e_tree_model_value_to_string (ETreeModel *tree_model,
676 gint col,
677 gconstpointer value)
679 ETreeModelInterface *iface;
681 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
683 iface = E_TREE_MODEL_GET_INTERFACE (tree_model);
684 g_return_val_if_fail (iface->value_to_string != NULL, NULL);
686 return iface->value_to_string (tree_model, col, value);
690 * e_tree_model_node_traverse:
691 * @tree_model:
692 * @path:
693 * @func:
694 * @data:
698 void
699 e_tree_model_node_traverse (ETreeModel *tree_model,
700 ETreePath path,
701 ETreePathFunc func,
702 gpointer data)
704 ETreePath child;
706 g_return_if_fail (E_IS_TREE_MODEL (tree_model));
707 g_return_if_fail (path != NULL);
709 child = e_tree_model_node_get_first_child (tree_model, path);
711 while (child) {
712 ETreePath next_child;
714 next_child = e_tree_model_node_get_next (tree_model, child);
715 e_tree_model_node_traverse (tree_model, child, func, data);
716 if (func (tree_model, child, data))
717 return;
719 child = next_child;
723 static ETreePath
724 e_tree_model_node_real_traverse (ETreeModel *model,
725 ETreePath path,
726 ETreePath end_path,
727 ETreePathFunc func,
728 gpointer data)
730 ETreePath child;
732 g_return_val_if_fail (E_IS_TREE_MODEL (model), NULL);
733 g_return_val_if_fail (path != NULL, NULL);
735 child = e_tree_model_node_get_first_child (model, path);
737 while (child) {
738 ETreePath result;
740 if (child == end_path || func (model, child, data))
741 return child;
743 if ((result = e_tree_model_node_real_traverse (
744 model, child, end_path, func, data)))
745 return result;
747 child = e_tree_model_node_get_next (model, child);
750 return NULL;
754 * e_tree_model_node_find:
755 * @tree_model:
756 * @path:
757 * @end_path:
758 * @func:
759 * @data:
763 ETreePath
764 e_tree_model_node_find (ETreeModel *tree_model,
765 ETreePath path,
766 ETreePath end_path,
767 ETreePathFunc func,
768 gpointer data)
770 ETreePath result;
771 ETreePath next;
773 g_return_val_if_fail (E_IS_TREE_MODEL (tree_model), NULL);
775 /* Just search the whole tree in this case. */
776 if (path == NULL) {
777 ETreePath root;
778 root = e_tree_model_get_root (tree_model);
780 if (end_path == root || func (tree_model, root, data))
781 return root;
783 result = e_tree_model_node_real_traverse (
784 tree_model, root, end_path, func, data);
785 if (result)
786 return result;
788 return NULL;
791 while (1) {
793 if ((result = e_tree_model_node_real_traverse (
794 tree_model, path, end_path, func, data)))
795 return result;
796 next = e_tree_model_node_get_next (tree_model, path);
798 while (next == NULL) {
799 path = e_tree_model_node_get_parent (tree_model, path);
801 if (path == NULL)
802 return NULL;
804 next = e_tree_model_node_get_next (tree_model, path);
807 if (end_path == next || func (tree_model, next, data))
808 return next;
810 path = next;