From e2defdb06fc9bf7a73bb5ec0d4abcfd2c71a658d Mon Sep 17 00:00:00 2001 From: Christopher James Lahey Date: Thu, 31 Jan 2002 08:17:57 +0000 Subject: New function to do a search through a tree in one direction or the other. 2002-01-31 Christopher James Lahey * e-tree-model.c, e-tree-model.h (e_tree_model_node_find): New function to do a search through a tree in one direction or the other. svn path=/trunk/; revision=15536 --- widgets/table/e-tree-model.c | 114 +++++++++++++++++++++++++++ widgets/table/e-tree-model.h | 181 ++++++++++++++++++++++--------------------- 2 files changed, 206 insertions(+), 89 deletions(-) diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c index 12253bcd09..d90088624f 100644 --- a/widgets/table/e-tree-model.c +++ b/widgets/table/e-tree-model.c @@ -943,3 +943,117 @@ e_tree_model_node_traverse_preorder (ETreeModel *model, ETreePath path, ETreePat } } +/** + * e_tree_model_node_traverse_preorder: + * @model: + * @path: + * @func: + * @data: + * + * + **/ +static ETreePath +e_tree_model_node_real_traverse (ETreeModel *model, ETreePath path, ETreePath end_path, gboolean forward_direction, ETreePathFunc func, gpointer data) +{ + ETreePath child; + + g_return_val_if_fail (model != NULL, NULL); + g_return_val_if_fail (E_IS_TREE_MODEL (model), NULL); + g_return_val_if_fail (path != NULL, NULL); + + if (forward_direction) + child = e_tree_model_node_get_first_child (model, path); + else + child = e_tree_model_node_get_last_child (model, path); + + while (child) { + ETreePath next_child; + ETreePath result; + + if (child == end_path || func (model, child, data)) + return child; + + if (forward_direction) + next_child = e_tree_model_node_get_next (model, child); + else + next_child = e_tree_model_node_get_prev (model, child); + + if ((result = e_tree_model_node_real_traverse (model, child, end_path, forward_direction, func, data))) + return result; + + child = next_child; + } + return NULL; +} + +/** + * e_tree_model_node_traverse_preorder: + * @model: + * @path: + * @func: + * @data: + * + * + **/ +ETreePath +e_tree_model_node_find (ETreeModel *model, ETreePath path, ETreePath end_path, gboolean forward_direction, ETreePathFunc func, gpointer data) +{ + ETreePath result; + ETreePath next; + + g_return_val_if_fail (model != NULL, NULL); + g_return_val_if_fail (E_IS_TREE_MODEL (model), NULL); + + /* Just search the whole tree in this case. */ + if (path == NULL) { + ETreePath root; + root = e_tree_model_get_root (model); + + if (forward_direction && (end_path == root || func (model, root, data))) + return root; + + if ((result = e_tree_model_node_real_traverse (model, root, end_path, forward_direction, func, data))) + return result; + + if (!forward_direction && (end_path == root || func (model, root, data))) + return root; + + return NULL; + } + + start: + + if (forward_direction) { + if ((result = e_tree_model_node_real_traverse (model, path, end_path, forward_direction, func, data))) + return result; + next = e_tree_model_node_get_next (model, path); + } else { + next = e_tree_model_node_get_prev (model, path); + if (next && (result = e_tree_model_node_real_traverse (model, next, end_path, forward_direction, func, data))) + return result; + } + + if (next) { + if (end_path == next || func (model, next, data)) + return next; + + /* return e_tree_model_node_find (model, next, end_path, forward_direction, func, data) */ + path = next; + goto start; + } + + path = e_tree_model_node_get_parent (model, path); + + if (path && forward_direction) + path = e_tree_model_node_get_next (model, path); + + if (path) { + if (end_path == path || func (model, path, data)) + return path; + + /* return e_tree_model_node_find (model, path, end_path, forward_direction, func, data) */ + goto start; + } + return NULL; +} + diff --git a/widgets/table/e-tree-model.h b/widgets/table/e-tree-model.h index c80a131b1c..bd3714b847 100644 --- a/widgets/table/e-tree-model.h +++ b/widgets/table/e-tree-model.h @@ -111,104 +111,107 @@ struct ETreeModelClass { void (*node_removed) (ETreeModel *etm, ETreePath parent, ETreePath removed_node, int old_position); void (*node_deleted) (ETreeModel *etm, ETreePath deleted_node); }; -GtkType e_tree_model_get_type (void); -ETreeModel *e_tree_model_new (void); + + +GtkType e_tree_model_get_type (void); +ETreeModel *e_tree_model_new (void); /* tree traversal operations */ -ETreePath e_tree_model_get_root (ETreeModel *etree); -ETreePath e_tree_model_node_get_parent (ETreeModel *etree, - ETreePath path); -ETreePath e_tree_model_node_get_first_child (ETreeModel *etree, - ETreePath path); -ETreePath e_tree_model_node_get_last_child (ETreeModel *etree, - ETreePath path); -ETreePath e_tree_model_node_get_next (ETreeModel *etree, - ETreePath path); -ETreePath e_tree_model_node_get_prev (ETreeModel *etree, - ETreePath path); +ETreePath e_tree_model_get_root (ETreeModel *etree); +ETreePath e_tree_model_node_get_parent (ETreeModel *etree, + ETreePath path); +ETreePath e_tree_model_node_get_first_child (ETreeModel *etree, + ETreePath path); +ETreePath e_tree_model_node_get_last_child (ETreeModel *etree, + ETreePath path); +ETreePath e_tree_model_node_get_next (ETreeModel *etree, + ETreePath path); +ETreePath e_tree_model_node_get_prev (ETreeModel *etree, + ETreePath path); /* node accessors */ -gboolean e_tree_model_node_is_root (ETreeModel *etree, - ETreePath path); -gboolean e_tree_model_node_is_expandable (ETreeModel *etree, - ETreePath path); -guint e_tree_model_node_get_children (ETreeModel *etree, - ETreePath path, - ETreePath **paths); -guint e_tree_model_node_depth (ETreeModel *etree, - ETreePath path); -GdkPixbuf *e_tree_model_icon_at (ETreeModel *etree, - ETreePath path); -gboolean e_tree_model_get_expanded_default (ETreeModel *model); -gint e_tree_model_column_count (ETreeModel *model); - - -gboolean e_tree_model_has_save_id (ETreeModel *model); -gchar *e_tree_model_get_save_id (ETreeModel *model, - ETreePath node); - -gboolean e_tree_model_has_get_node_by_id (ETreeModel *model); -ETreePath e_tree_model_get_node_by_id (ETreeModel *model, - const char *save_id); - -gboolean e_tree_model_has_change_pending (ETreeModel *model); - -void *e_tree_model_value_at (ETreeModel *etree, - ETreePath node, - int col); -void e_tree_model_set_value_at (ETreeModel *etree, - ETreePath node, - int col, - const void *val); -gboolean e_tree_model_node_is_editable (ETreeModel *etree, - ETreePath node, - int col); -void *e_tree_model_duplicate_value (ETreeModel *etree, - int col, - const void *value); -void e_tree_model_free_value (ETreeModel *etree, - int col, - void *value); -void *e_tree_model_initialize_value (ETreeModel *etree, - int col); -gboolean e_tree_model_value_is_empty (ETreeModel *etree, - int col, - const void *value); -char *e_tree_model_value_to_string (ETreeModel *etree, - int col, - const void *value); +gboolean e_tree_model_node_is_root (ETreeModel *etree, + ETreePath path); +gboolean e_tree_model_node_is_expandable (ETreeModel *etree, + ETreePath path); +guint e_tree_model_node_get_children (ETreeModel *etree, + ETreePath path, + ETreePath **paths); +guint e_tree_model_node_depth (ETreeModel *etree, + ETreePath path); +GdkPixbuf *e_tree_model_icon_at (ETreeModel *etree, + ETreePath path); +gboolean e_tree_model_get_expanded_default (ETreeModel *model); +gint e_tree_model_column_count (ETreeModel *model); +gboolean e_tree_model_has_save_id (ETreeModel *model); +gchar *e_tree_model_get_save_id (ETreeModel *model, + ETreePath node); +gboolean e_tree_model_has_get_node_by_id (ETreeModel *model); +ETreePath e_tree_model_get_node_by_id (ETreeModel *model, + const char *save_id); +gboolean e_tree_model_has_change_pending (ETreeModel *model); +void *e_tree_model_value_at (ETreeModel *etree, + ETreePath node, + int col); +void e_tree_model_set_value_at (ETreeModel *etree, + ETreePath node, + int col, + const void *val); +gboolean e_tree_model_node_is_editable (ETreeModel *etree, + ETreePath node, + int col); +void *e_tree_model_duplicate_value (ETreeModel *etree, + int col, + const void *value); +void e_tree_model_free_value (ETreeModel *etree, + int col, + void *value); +void *e_tree_model_initialize_value (ETreeModel *etree, + int col); +gboolean e_tree_model_value_is_empty (ETreeModel *etree, + int col, + const void *value); +char *e_tree_model_value_to_string (ETreeModel *etree, + int col, + const void *value); /* depth first traversal of path's descendents, calling func on each one */ -void e_tree_model_node_traverse (ETreeModel *model, - ETreePath path, - ETreePathFunc func, - gpointer data); -void e_tree_model_node_traverse_preorder (ETreeModel *model, - ETreePath path, - ETreePathFunc func, - gpointer data); - +void e_tree_model_node_traverse (ETreeModel *model, + ETreePath path, + ETreePathFunc func, + gpointer data); +void e_tree_model_node_traverse_preorder (ETreeModel *model, + ETreePath path, + ETreePathFunc func, + gpointer data); +ETreePath e_tree_model_node_find (ETreeModel *model, + ETreePath path, + ETreePath end_path, + gboolean forward_direction, + ETreePathFunc func, + gpointer data); + /* ** Routines for emitting signals on the ETreeModel */ -void e_tree_model_pre_change (ETreeModel *tree_model); -void e_tree_model_no_change (ETreeModel *tree_model); -void e_tree_model_node_changed (ETreeModel *tree_model, - ETreePath node); -void e_tree_model_node_data_changed (ETreeModel *tree_model, - ETreePath node); -void e_tree_model_node_col_changed (ETreeModel *tree_model, - ETreePath node, - int col); -void e_tree_model_node_inserted (ETreeModel *tree_model, - ETreePath parent_node, - ETreePath inserted_node); -void e_tree_model_node_removed (ETreeModel *tree_model, - ETreePath parent_node, - ETreePath removed_node, - int old_position); -void e_tree_model_node_deleted (ETreeModel *tree_model, - ETreePath deleted_node); +void e_tree_model_pre_change (ETreeModel *tree_model); +void e_tree_model_no_change (ETreeModel *tree_model); +void e_tree_model_node_changed (ETreeModel *tree_model, + ETreePath node); +void e_tree_model_node_data_changed (ETreeModel *tree_model, + ETreePath node); +void e_tree_model_node_col_changed (ETreeModel *tree_model, + ETreePath node, + int col); +void e_tree_model_node_inserted (ETreeModel *tree_model, + ETreePath parent_node, + ETreePath inserted_node); +void e_tree_model_node_removed (ETreeModel *tree_model, + ETreePath parent_node, + ETreePath removed_node, + int old_position); +void e_tree_model_node_deleted (ETreeModel *tree_model, + ETreePath deleted_node); #ifdef __cplusplus } -- cgit