New function to do a search through a tree in one direction or the other.

2002-01-31  Christopher James Lahey  <clahey@ximian.com>

	* 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
This commit is contained in:
Christopher James Lahey
2002-01-31 08:17:57 +00:00
committed by Chris Lahey
parent 42ffb93955
commit e2defdb06f
2 changed files with 206 additions and 89 deletions

View File

@ -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;
}

View File

@ -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
}