From 4697d1ccc1d6190788b931352b1e3a931dd0a0f7 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Thu, 25 Jul 2013 16:06:34 +0100 Subject: Expose treeview walker. --- desktop/treeview.c | 44 ++++++++++++++++++++++++++++++++++++++------ desktop/treeview.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/desktop/treeview.c b/desktop/treeview.c index b9200735b..c45e91435 100644 --- a/desktop/treeview.c +++ b/desktop/treeview.c @@ -39,12 +39,6 @@ struct treeview_globals { int icon_step; } tree_g; -enum treeview_node_type { - TREE_NODE_ROOT, - TREE_NODE_FOLDER, - TREE_NODE_ENTRY -}; - enum treeview_node_section { TV_NODE_SECTION_TOGGLE, /**< Expansion toggle */ TV_NODE_SECTION_ON_NODE, /**< Node content (text, icon) */ @@ -573,6 +567,44 @@ static nserror treeview_walk_internal(treeview_node *root, bool full, } +struct treeview_walk_ctx { + treeview_walk_callback walk_cb; + void *ctx; + enum treeview_node_type type; +}; +/** Treewalk node callback. */ +static nserror treeview_walk_cb(treeview_node *n, void *ctx, + bool *skip_children, bool *end) +{ + struct treeview_walk_ctx *tw = ctx; + + if (n->type & tw->type) { + return tw->walk_cb(tw->ctx, n->client_data, tw->type, end); + } + + return NSERROR_OK; +} +/* Exported interface, documented in treeview.h */ +nserror treeview_walk(treeview *tree, treeview_node *root, + treeview_walk_callback walk_cb, void *ctx, + enum treeview_node_type type) +{ + struct treeview_walk_ctx tw = { + .walk_cb = walk_cb, + .ctx = ctx, + .type = type + }; + + assert(tree != NULL); + assert(tree->root != NULL); + + if (root == NULL) + root = tree->root; + + return treeview_walk_internal(root, true, NULL, treeview_walk_cb, &tw); +} + + struct treeview_node_delete { treeview *tree; int height_reduction; diff --git a/desktop/treeview.h b/desktop/treeview.h index 82a7af17f..ddd9be661 100644 --- a/desktop/treeview.h +++ b/desktop/treeview.h @@ -33,6 +33,12 @@ typedef struct treeview treeview; typedef struct treeview_node treeview_node; +enum treeview_node_type { + TREE_NODE_ROOT = (1 << 0), + TREE_NODE_FOLDER = (1 << 1), + TREE_NODE_ENTRY = (1 << 2) +}; + enum treeview_relationship { TREE_REL_FIRST_CHILD, TREE_REL_NEXT_SIBLING @@ -208,6 +214,37 @@ nserror treeview_update_node_entry(treeview *tree, const struct treeview_field_data fields[], void *data); + +/** + * Client callback for treeview_walk + * + * \param ctx Client context + * \param node_data Client data for the current treeview node + * \param type The node type + * \param abort Set to true to abort treeview walk prematurely + * \return NSERROR_OK on success, or appropriate error otherwise + */ +typedef nserror (*treeview_walk_callback)(void *ctx, void *node_data, + enum treeview_node_type type, bool *abort); + +/** + * Walk (depth first) a treeview subtree, calling a callback at each node of + * required type. + * + * \param tree Treeview object to walk + * \param root Root node to walk tree from (or NULL for tree root) + * \param walk_cb Function to call on each node + * \param ctx Client context, passed back to callback function + * \param type The node type(s) of interest + * \return NSERROR_OK on success, or appropriate error otherwise + * + * Note, if deleting returned node, walk_cb must terminate the treeview walk by + * setting abort to true. + */ +nserror treeview_walk(treeview *tree, treeview_node *root, + treeview_walk_callback walk_cb, void *ctx, + enum treeview_node_type type); + /** * Delete a treeview node * -- cgit v1.2.3