/* Display the whole tree (single/split/full view) */ static void display_tree(struct menu *menu) { struct symbol *sym; struct property *prop; struct menu *child; enum prop_type ptype; if (menu == &rootmenu) { indent = 1; current = &rootmenu; } for (child = menu->list; child; child = child->next) { prop = child->prompt; sym = child->sym; ptype = prop ? prop->type : P_UNKNOWN; if (sym) sym->flags &= ~SYMBOL_CHANGED; if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) && (tree == tree1)) continue; if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) && (tree == tree2)) continue; if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) || (opt_mode == OPT_PROMPT && menu_has_prompt(child)) || (opt_mode == OPT_ALL && menu_get_prompt(child))) place_node(child, fill_row(child)); #ifdef DEBUG printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); printf("%s", prop_get_type_name(ptype)); printf(" | "); if (sym) { printf("%s", sym_type_name(sym->type)); printf(" | "); printf("%s", dbg_sym_flags(sym->flags)); printf("\n"); } else printf("\n"); #endif if ((view_mode != FULL_VIEW) && (ptype == P_MENU) && (tree == tree2)) continue; /* if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW))*/ if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW)) { indent++; display_tree(child); indent--; } } }
static void build_conf(struct menu *menu) { struct symbol *sym; struct property *prop; struct menu *child; int type, tmp, doint = 2; tristate val; char ch; bool visible; /* * note: menu_is_visible() has side effect that it will * recalc the value of the symbol. */ visible = menu_is_visible(menu); if (show_all_options && !menu_has_prompt(menu)) return; else if (!show_all_options && !visible) return; sym = menu->sym; prop = menu->prompt; if (!sym) { if (prop && menu != current_menu) { const char *prompt = menu_get_prompt(menu); switch (prop->type) { case P_MENU: child_count++; prompt = _(prompt); if (single_menu_mode) { item_make("%s%*c%s", menu->data ? "-->" : "++>", indent + 1, ' ', prompt); } else item_make(" %*c%s --->", indent + 1, ' ', prompt); item_set_tag('m'); item_set_data(menu); if (single_menu_mode && menu->data) goto conf_childs; return; case P_COMMENT: if (prompt) { child_count++; item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt)); item_set_tag(':'); item_set_data(menu); } break; default: if (prompt) { child_count++; item_make("---%*c%s", indent + 1, ' ', _(prompt)); item_set_tag(':'); item_set_data(menu); } } } else doint = 0; goto conf_childs; } type = sym_get_type(sym); if (sym_is_choice(sym)) { struct symbol *def_sym = sym_get_choice_value(sym); struct menu *def_menu = NULL; child_count++; for (child = menu->list; child; child = child->next) { if (menu_is_visible(child) && child->sym == def_sym) def_menu = child; } val = sym_get_tristate_value(sym); if (sym_is_changable(sym)) { switch (type) { case S_BOOLEAN: item_make("[%c]", val == no ? ' ' : '*'); break; case S_TRISTATE: switch (val) { case yes: ch = '*'; break; case mod: ch = 'M'; break; default: ch = ' '; break; } item_make("<%c>", ch); break; } item_set_tag('t'); item_set_data(menu); } else { item_make(" "); item_set_tag(def_menu ? 't' : ':'); item_set_data(menu); } item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); if (val == yes) { if (def_menu) { item_add_str(" (%s)", _(menu_get_prompt(def_menu))); item_add_str(" --->"); if (def_menu->list) { indent += 2; build_conf(def_menu); indent -= 2; } } return; } } else { if (menu == current_menu) { item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); item_set_tag(':'); item_set_data(menu); goto conf_childs; } child_count++; val = sym_get_tristate_value(sym); if (sym_is_choice_value(sym) && val == yes) { item_make(" "); item_set_tag(':'); item_set_data(menu); } else { switch (type) { case S_BOOLEAN: if (sym_is_changable(sym)) item_make("[%c]", val == no ? ' ' : '*'); else item_make("-%c-", val == no ? ' ' : '*'); item_set_tag('t'); item_set_data(menu); break; case S_TRISTATE: switch (val) { case yes: ch = '*'; break; case mod: ch = 'M'; break; default: ch = ' '; break; } if (sym_is_changable(sym)) { if (sym->rev_dep.tri == mod) item_make("{%c}", ch); else item_make("<%c>", ch); } else item_make("-%c-", ch); item_set_tag('t'); item_set_data(menu); break; default: tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */ item_make("(%s)", sym_get_string_value(sym)); tmp = indent - tmp + 4; if (tmp < 0) tmp = 0; item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), (sym_has_value(sym) || !sym_is_changable(sym)) ? "" : _(" (NEW)")); item_set_tag('s'); item_set_data(menu); goto conf_childs; } } item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), (sym_has_value(sym) || !sym_is_changable(sym)) ? "" : _(" (NEW)")); if (menu->prompt->type == P_MENU) { item_add_str(" --->"); return; } } conf_childs: indent += doint; for (child = menu->list; child; child = child->next) build_conf(child); indent -= doint; }
/* * Update the tree by adding/removing entries * Does not change other nodes */ static void update_tree(struct menu *src, GtkTreeIter * dst) { struct menu *child1; GtkTreeIter iter, tmp; GtkTreeIter *child2 = &iter; gboolean valid; GtkTreeIter *sibling; struct symbol *sym; struct property *prop; struct menu *menu1, *menu2; if (src == &rootmenu) indent = 1; valid = gtk_tree_model_iter_children(model2, child2, dst); for (child1 = src->list; child1; child1 = child1->next) { prop = child1->prompt; sym = child1->sym; reparse: menu1 = child1; if (valid) gtk_tree_model_get(model2, child2, COL_MENU, &menu2, -1); else menu2 = NULL; // force adding of a first child #ifdef DEBUG printf("%*c%s | %s\n", indent, ' ', menu1 ? menu_get_prompt(menu1) : "nil", menu2 ? menu_get_prompt(menu2) : "nil"); #endif if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) || (opt_mode == OPT_ALL && !menu_get_prompt(child1))) { /* remove node */ if (gtktree_iter_find_node(dst, menu1) != NULL) { memcpy(&tmp, child2, sizeof(GtkTreeIter)); valid = gtk_tree_model_iter_next(model2, child2); gtk_tree_store_remove(tree2, &tmp); if (!valid) return; /* next parent */ else goto reparse; /* next child */ } else continue; } if (menu1 != menu2) { if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node if (!valid && !menu2) sibling = NULL; else sibling = child2; gtk_tree_store_insert_before(tree2, child2, dst, sibling); set_node(child2, menu1, fill_row(menu1)); if (menu2 == NULL) valid = TRUE; } else { // remove node memcpy(&tmp, child2, sizeof(GtkTreeIter)); valid = gtk_tree_model_iter_next(model2, child2); gtk_tree_store_remove(tree2, &tmp); if (!valid) return; // next parent else goto reparse; // next child } } else if (sym && (sym->flags & SYMBOL_CHANGED)) { set_node(child2, menu1, fill_row(menu1)); } indent++; update_tree(child1, child2); indent--; valid = gtk_tree_model_iter_next(model2, child2); } }