diff --git a/desktop/cookie_manager.c b/desktop/cookie_manager.c index e342a2bfe..5f7f038d3 100644 --- a/desktop/cookie_manager.c +++ b/desktop/cookie_manager.c @@ -331,9 +331,9 @@ static nserror cookie_manager_create_cookie_node( err = treeview_create_node_entry(cm_ctx.tree, &(cookie->entry), parent->folder, TREE_REL_FIRST_CHILD, cookie->data, cookie, - cm_ctx.built ? TREE_CREATE_NONE : - TREE_CREATE_SUPPRESS_RESIZE | - TREE_CREATE_SUPPRESS_REDRAW); + cm_ctx.built ? TREE_OPTION_NONE : + TREE_OPTION_SUPPRESS_RESIZE | + TREE_OPTION_SUPPRESS_REDRAW); if (err != NSERROR_OK) { cookie_manager_free_treeview_field_data(cookie); free(cookie); @@ -412,9 +412,9 @@ static nserror cookie_manager_create_domain_folder( err = treeview_create_node_folder(cm_ctx.tree, &(f->folder), NULL, TREE_REL_FIRST_CHILD, &f->data, f, - cm_ctx.built ? TREE_CREATE_NONE : - TREE_CREATE_SUPPRESS_RESIZE | - TREE_CREATE_SUPPRESS_REDRAW); + cm_ctx.built ? TREE_OPTION_NONE : + TREE_OPTION_SUPPRESS_RESIZE | + TREE_OPTION_SUPPRESS_REDRAW); if (err != NSERROR_OK) { free((void *)f->data.value); free(f); @@ -499,7 +499,7 @@ void cookie_manager_remove(const struct cookie_data *data) } /* Delete the node */ - treeview_delete_node(cm_ctx.tree, cookie->entry); + treeview_delete_node(cm_ctx.tree, cookie->entry, TREE_OPTION_NONE); } diff --git a/desktop/global_history.c b/desktop/global_history.c index 66bf37dcb..2b384b1ef 100644 --- a/desktop/global_history.c +++ b/desktop/global_history.c @@ -197,9 +197,9 @@ static nserror global_history_create_dir(enum global_history_folders f) relation, rel, &gh_ctx.folders[f].data, &gh_ctx.folders[f], - gh_ctx.built ? TREE_CREATE_NONE : - TREE_CREATE_SUPPRESS_RESIZE | - TREE_CREATE_SUPPRESS_REDRAW); + gh_ctx.built ? TREE_OPTION_NONE : + TREE_OPTION_SUPPRESS_RESIZE | + TREE_OPTION_SUPPRESS_REDRAW); return err; } @@ -326,9 +326,9 @@ static nserror global_history_entry_insert(struct global_history_entry *e, err = treeview_create_node_entry(gh_ctx.tree, &(e->entry), parent, TREE_REL_FIRST_CHILD, e->data, e, - gh_ctx.built ? TREE_CREATE_NONE : - TREE_CREATE_SUPPRESS_RESIZE | - TREE_CREATE_SUPPRESS_REDRAW); + gh_ctx.built ? TREE_OPTION_NONE : + TREE_OPTION_SUPPRESS_RESIZE | + TREE_OPTION_SUPPRESS_REDRAW); if (err != NSERROR_OK) { return err; } @@ -500,7 +500,9 @@ static bool global_history_add_entry(nsurl *url, /* Delete any existing entry for this URL */ e = global_history_find(url); if (e != NULL) { - treeview_delete_node(gh_ctx.tree, e->entry); + treeview_delete_node(gh_ctx.tree, e->entry, + TREE_OPTION_SUPPRESS_REDRAW | + TREE_OPTION_SUPPRESS_RESIZE); } } diff --git a/desktop/hotlist.c b/desktop/hotlist.c index 6ef8385e3..683fdc4b1 100644 --- a/desktop/hotlist.c +++ b/desktop/hotlist.c @@ -141,8 +141,8 @@ static nserror hotlist_entry_insert(struct hotlist_entry *e, err = treeview_create_node_entry(hl_ctx.tree, &(e->entry), relation, rel, e->data, e, hl_ctx.built ? - TREE_CREATE_NONE : TREE_CREATE_SUPPRESS_RESIZE | - TREE_CREATE_SUPPRESS_REDRAW); + TREE_OPTION_NONE : TREE_OPTION_SUPPRESS_RESIZE | + TREE_OPTION_SUPPRESS_REDRAW); if (err != NSERROR_OK) { return err; } @@ -314,8 +314,8 @@ static nserror hotlist_add_folder_internal( err = treeview_create_node_folder(hl_ctx.tree, &n, relation, rel, &f->data, f, hl_ctx.built ? - TREE_CREATE_NONE : TREE_CREATE_SUPPRESS_RESIZE | - TREE_CREATE_SUPPRESS_REDRAW); + TREE_OPTION_NONE : TREE_OPTION_SUPPRESS_RESIZE | + TREE_OPTION_SUPPRESS_REDRAW); if (err != NSERROR_OK) { free((void *)title); /* Eww */ free(f); @@ -1219,7 +1219,8 @@ static nserror hotlist_remove_url_walk_cb(void *ctx, void *node_data, if (nsurl_compare(e->url, tw->url, NSURL_COMPLETE) == true) { /* Found what we're looking for: delete it */ - treeview_delete_node(hl_ctx.tree, e->entry); + treeview_delete_node(hl_ctx.tree, e->entry, + TREE_OPTION_NONE); } } diff --git a/desktop/sslcert_viewer.c b/desktop/sslcert_viewer.c index d9dd5c763..736237173 100644 --- a/desktop/sslcert_viewer.c +++ b/desktop/sslcert_viewer.c @@ -189,7 +189,7 @@ static nserror sslcert_viewer_create_node( /* Create the new treeview node */ err = treeview_create_node_entry(ssl_d->tree, &(e->entry), NULL, TREE_REL_FIRST_CHILD, - e->data, e, TREE_CREATE_NONE); + e->data, e, TREE_OPTION_NONE); if (err != NSERROR_OK) { sslcert_viewer_free_treeview_field_data(e); free(e); diff --git a/desktop/treeview.c b/desktop/treeview.c index f4fa7e8e5..20694bf68 100644 --- a/desktop/treeview.c +++ b/desktop/treeview.c @@ -524,7 +524,7 @@ nserror treeview_create_node_folder(treeview *tree, treeview_node *relation, enum treeview_relationship rel, const struct treeview_field_data *field, - void *data, treeview_node_create_flags flags) + void *data, treeview_node_options_flags flags) { treeview_node *n; @@ -562,12 +562,12 @@ nserror treeview_create_node_folder(treeview *tree, if (n->parent->flags & TREE_NODE_EXPANDED) { /* Inform front end of change in dimensions */ - if (!(flags & TREE_CREATE_SUPPRESS_RESIZE)) + if (!(flags & TREE_OPTION_SUPPRESS_RESIZE)) tree->cw_t->update_size(tree->cw_h, -1, tree->root->height); /* Redraw */ - if (!(flags & TREE_CREATE_SUPPRESS_REDRAW)) { + if (!(flags & TREE_OPTION_SUPPRESS_REDRAW)) { struct rect r; r.x0 = 0; r.y0 = treeview_node_y(tree, n); @@ -707,7 +707,7 @@ nserror treeview_create_node_entry(treeview *tree, treeview_node *relation, enum treeview_relationship rel, const struct treeview_field_data fields[], - void *data, treeview_node_create_flags flags) + void *data, treeview_node_options_flags flags) { bool match; struct treeview_node_entry *e; @@ -768,12 +768,12 @@ nserror treeview_create_node_entry(treeview *tree, if (n->parent->flags & TREE_NODE_EXPANDED) { /* Inform front end of change in dimensions */ - if (!(flags & TREE_CREATE_SUPPRESS_RESIZE)) + if (!(flags & TREE_OPTION_SUPPRESS_RESIZE)) tree->cw_t->update_size(tree->cw_h, -1, tree->root->height); /* Redraw */ - if (!(flags & TREE_CREATE_SUPPRESS_REDRAW)) { + if (!(flags & TREE_OPTION_SUPPRESS_REDRAW)) { struct rect r; r.x0 = 0; r.y0 = treeview_node_y(tree, n); @@ -968,7 +968,7 @@ static void treeview_edit_done(treeview *tree) struct treeview_node_delete { treeview *tree; - int height_reduction; + int h_reduction; bool user_interaction; }; /** Treewalk node callback deleting nodes. */ @@ -983,7 +983,7 @@ static nserror treeview_delete_node_walk_cb(treeview_node *n, assert(n->children == NULL); if (treeview_unlink_node(n)) - nd->height_reduction += (n->type == TREE_NODE_ENTRY) ? + nd->h_reduction += (n->type == TREE_NODE_ENTRY) ? n->height : tree_g.line_height; /* Handle any special treatment */ @@ -1016,6 +1016,7 @@ static nserror treeview_delete_node_walk_cb(treeview_node *n, * \param tree Treeview object to delete node from * \param n Node to delete * \param interaction Delete is result of user interaction with treeview + * \param flags Treeview node options flags * \return NSERROR_OK on success, appropriate error otherwise * * Will emit folder or entry deletion msg callback. @@ -1027,13 +1028,13 @@ static nserror treeview_delete_node_walk_cb(treeview_node *n, * set, caller must also call treeview_delete_empty. */ static nserror treeview_delete_node_internal(treeview *tree, treeview_node *n, - bool interaction) + bool interaction, treeview_node_options_flags flags) { nserror err; treeview_node *p = n->parent; struct treeview_node_delete nd = { .tree = tree, - .height_reduction = 0, + .h_reduction = 0, .user_interaction = interaction }; @@ -1056,22 +1057,26 @@ static nserror treeview_delete_node_internal(treeview *tree, treeview_node *n, return err; } + n = p; /* Reduce ancestor heights */ - while (p != NULL && p->flags & TREE_NODE_EXPANDED) { - p->height -= nd.height_reduction; - p = p->parent; + while (n != NULL && n->flags & TREE_NODE_EXPANDED) { + n->height -= nd.h_reduction; + n = n->parent; } /* Inform front end of change in dimensions */ - if (tree->root != NULL) - tree->cw_t->update_size(tree->cw_h, -1, tree->root->height); + if (tree->root != NULL && p != NULL && p->flags & TREE_NODE_EXPANDED && + !(flags & TREE_OPTION_SUPPRESS_RESIZE)) { + tree->cw_t->update_size(tree->cw_h, -1, + tree->root->height); + } return NSERROR_OK; } /** - * Delete a treeview node + * Delete any empty treeview folder nodes * * \param tree Treeview object to delete empty nodes from * \param interaction Delete is result of user interaction with treeview @@ -1083,13 +1088,13 @@ static nserror treeview_delete_node_internal(treeview *tree, treeview_node *n, */ static nserror treeview_delete_empty_nodes(treeview *tree, bool interaction) { - treeview_node *node, *child, *parent, *next_sibling; + treeview_node *node, *child, *parent, *next_sibling, *p; treeview_node *root = tree->root; bool abort = false; nserror err; struct treeview_node_delete nd = { .tree = tree, - .height_reduction = 0, + .h_reduction = 0, .user_interaction = interaction }; @@ -1113,11 +1118,21 @@ static nserror treeview_delete_empty_nodes(treeview *tree, bool interaction) if (node->type == TREE_NODE_FOLDER && node->children == NULL) { /* Delete node */ + p = node->parent; err = treeview_delete_node_walk_cb( node, &nd, &abort); if (err != NSERROR_OK) { return err; } + + /* Reduce ancestor heights */ + while (p != NULL && + p->flags & + TREE_NODE_EXPANDED) { + p->height -= nd.h_reduction; + p = p->parent; + } + nd.h_reduction = 0; } node = parent; parent = node->parent; @@ -1130,11 +1145,20 @@ static nserror treeview_delete_empty_nodes(treeview *tree, bool interaction) if (node->type == TREE_NODE_FOLDER && node->children == NULL) { /* Delete node */ + p = node->parent; err = treeview_delete_node_walk_cb( node, &nd, &abort); if (err != NSERROR_OK) { return err; } + + /* Reduce ancestor heights */ + while (p != NULL && + p->flags & TREE_NODE_EXPANDED) { + p->height -= nd.h_reduction; + p = p->parent; + } + nd.h_reduction = 0; } node = next_sibling; } @@ -1153,11 +1177,13 @@ static nserror treeview_delete_empty_nodes(treeview *tree, bool interaction) /* Exported interface, documented in treeview.h */ -nserror treeview_delete_node(treeview *tree, treeview_node *n) +nserror treeview_delete_node(treeview *tree, treeview_node *n, + treeview_node_options_flags flags) { nserror err; struct rect r; treeview_node *p; + int h; assert(tree != NULL); assert(n != NULL); @@ -1167,19 +1193,25 @@ nserror treeview_delete_node(treeview *tree, treeview_node *n) r.y0 = treeview_node_y(tree, n); r.y1 = tree->root->height; - err = treeview_delete_node_internal(tree, n, false); + err = treeview_delete_node_internal(tree, n, false, flags); if (err != NSERROR_OK) return err; + h = tree->root->height; if (tree->flags & TREEVIEW_DEL_EMPTY_DIRS) { /* Delete any empty nodes */ err = treeview_delete_empty_nodes(tree, false); if (err != NSERROR_OK) return err; } - /* Inform front end of change in dimensions */ - if (p->flags & TREE_NODE_EXPANDED) { + if (tree->root->height != h && !(flags & TREE_OPTION_SUPPRESS_RESIZE)) { + tree->cw_t->update_size(tree->cw_h, -1, tree->root->height); + } + + /* Redraw */ + if (p->flags & TREE_NODE_EXPANDED && + !(flags & TREE_OPTION_SUPPRESS_REDRAW)) { r.x0 = 0; r.x1 = REDRAW_MAX; tree->cw_t->redraw_request(tree->cw_h, &r); @@ -1283,7 +1315,9 @@ nserror treeview_destroy(treeview *tree) assert(tree != NULL); /* Destroy nodes */ - treeview_delete_node_internal(tree, tree->root, false); + treeview_delete_node_internal(tree, tree->root, false, + TREE_OPTION_SUPPRESS_RESIZE | + TREE_OPTION_SUPPRESS_REDRAW); /* Destroy feilds */ for (f = 0; f <= tree->n_fields; f++) { @@ -1388,7 +1422,7 @@ nserror treeview_node_expand(treeview *tree, static nserror treeview_node_contract_cb(treeview_node *n, void *ctx, bool *skip_children, bool *end) { - int height_reduction; + int h_reduction; assert(n != NULL); assert(n->type != TREE_NODE_ROOT); @@ -1401,12 +1435,12 @@ static nserror treeview_node_contract_cb(treeview_node *n, void *ctx, } n->flags ^= TREE_NODE_EXPANDED; - height_reduction = n->height - tree_g.line_height; + h_reduction = n->height - tree_g.line_height; - assert(height_reduction >= 0); + assert(h_reduction >= 0); do { - n->height -= height_reduction; + n->height -= h_reduction; n = n->parent; } while (n != NULL); @@ -1749,7 +1783,8 @@ static nserror treeview_node_selection_walk_cb(treeview_node *n, case TREEVIEW_WALK_DELETE_SELECTION: if (n->flags & TREE_NODE_SELECTED) { - err = treeview_delete_node_internal(sw->tree, n, true); + err = treeview_delete_node_internal(sw->tree, n, true, + TREE_OPTION_NONE); if (err != NSERROR_OK) { return err; } diff --git a/desktop/treeview.h b/desktop/treeview.h index 6f443212c..33c4c5018 100644 --- a/desktop/treeview.h +++ b/desktop/treeview.h @@ -45,10 +45,10 @@ enum treeview_relationship { }; /**< Relationship between nodes */ typedef enum { - TREE_CREATE_NONE = (0), /* No flags set */ - TREE_CREATE_SUPPRESS_RESIZE = (1 << 0), /* Suppress callback */ - TREE_CREATE_SUPPRESS_REDRAW = (1 << 1) /* Suppress callback */ -} treeview_node_create_flags; /**< Node creation settings */ + TREE_OPTION_NONE = (0), /* No flags set */ + TREE_OPTION_SUPPRESS_RESIZE = (1 << 0), /* Suppress callback */ + TREE_OPTION_SUPPRESS_REDRAW = (1 << 1) /* Suppress callback */ +} treeview_node_options_flags; /**< Node creation settings */ typedef enum { TREEVIEW_NO_FLAGS = (0), /**< No flags set */ @@ -181,7 +181,7 @@ nserror treeview_get_relation(treeview *tree, treeview_node **relation, * \param rel Folder's relationship to relation * \param field Field data * \param data Client data for node event callbacks - * \param flags Node creation flags + * \param flags Treeview node options flags * \return NSERROR_OK on success, appropriate error otherwise * * Field name must match name past in treeview_create fields[N-1]. @@ -193,7 +193,7 @@ nserror treeview_create_node_folder(treeview *tree, treeview_node *relation, enum treeview_relationship rel, const struct treeview_field_data *field, - void *data, treeview_node_create_flags flags); + void *data, treeview_node_options_flags flags); /** * Create an entry node in given treeview @@ -204,7 +204,7 @@ nserror treeview_create_node_folder(treeview *tree, * \param rel Folder's relationship to relation * \param fields Array of field data * \param data Client data for node event callbacks - * \param flags Node creation flags + * \param flags Treeview node options flags * \return NSERROR_OK on success, appropriate error otherwise * * Fields array names must match names past in treeview_create fields[0...N-2]. @@ -216,7 +216,7 @@ nserror treeview_create_node_entry(treeview *tree, treeview_node *relation, enum treeview_relationship rel, const struct treeview_field_data fields[], - void *data, treeview_node_create_flags flags); + void *data, treeview_node_options_flags flags); /** * Update an folder node in given treeview @@ -290,11 +290,13 @@ nserror treeview_walk(treeview *tree, treeview_node *root, * * \param tree Treeview object to delete node from * \param n Node to delete + * \param flags Treeview node options flags * \return NSERROR_OK on success, appropriate error otherwise * * Will emit folder or entry deletion msg callback. */ -nserror treeview_delete_node(treeview *tree, treeview_node *n); +nserror treeview_delete_node(treeview *tree, treeview_node *n, + treeview_node_options_flags flags); /** * Expand a treeview node