📄 listmenu.c
字号:
/* List menus functions *//* $Id: listmenu.c,v 1.35.4.2 2005/04/05 21:08:40 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <ctype.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include "elinks.h"#include "bfu/listmenu.h"#include "bfu/menu.h"#include "sched/session.h"#include "util/conv.h"#include "util/error.h"#include "util/string.h"#include "viewer/text/form.h" /* selected_item() and get_current_state() *//* TODO: massive cleanup, merging, code redundancy tracking between this file * and bfu/menu.c (and perhaps others.) * We should unify and clarify menu-related code. */static intmenu_contains(struct menu_item *m, int f){ if (m->func != do_select_submenu) return (long) m->data == f; foreach_menu_item (m, m->data) { if (menu_contains(m, f)) return 1; } return 0;}voiddo_select_submenu(struct terminal *term, void *menu_, void *ses_){ struct menu_item *menu = menu_; struct session *ses = ses_; struct menu_item *m; int def = int_max(0, get_current_state(ses)); int sel = 0; foreach_menu_item (m, menu) { if (menu_contains(m, def)) { sel = m - menu; break; } } do_menu_selected(term, menu, ses, sel, 0);}voidnew_menu_item(struct list_menu *menu, unsigned char *name, int data, int fullname) /* name == NULL - up; data == -1 - down */{ struct menu_item *new_menu_item = NULL; /* no uninitialized warnings */ struct menu_item **items; size_t stack_size = menu->stack_size; if (!name) { menu->stack_size--; return; } else if (data != -1 && menu->stack_size == 0) { mem_free(name); return; } clr_spaces(name); if (!name[0]) { mem_free(name); name = stracpy(" "); if (!name) return; } if (data == -1) { int size = (menu->stack_size + 1) * sizeof(*menu->stack); struct menu_item **stack = mem_realloc(menu->stack, size); if (stack) { menu->stack = stack; new_menu_item = new_menu(NO_INTL); } if (!stack || !new_menu_item) { if (new_menu_item) mem_free(new_menu_item); mem_free(name); return; } /* Since we increment @stack_size use cached value */ menu->stack[menu->stack_size++] = new_menu_item; if (menu->stack_size == 1) { mem_free(name); return; } } items = &menu->stack[stack_size - 1]; if (data == -1) { add_to_menu(items, name, NULL, ACT_MAIN_NONE, do_select_submenu, new_menu_item, SUBMENU); } else { add_to_menu(items, name, NULL, ACT_MAIN_NONE, selected_item, (void *) (long) data, (fullname ? MENU_FULLNAME : 0)); } if (stack_size >= 2) { struct menu_item *below = menu->stack[stack_size - 2]; while (below->text) below++; below[-1].data = *items; }}voidinit_menu(struct list_menu *menu){ menu->stack_size = 0; menu->stack = NULL; new_menu_item(menu, stracpy(""), -1, 0);}/* TODO: merge with free_menu_items() in bfu/menu.h --Zas */voidfree_menu(struct menu_item *m) /* Grrr. Recursion */{ struct menu_item *mm; if (!m) return; /* XXX: Who knows... need to be verified */ foreach_menu_item (mm, m) { mem_free_if(mm->text); if (mm->func == do_select_submenu) free_menu(mm->data); } mem_free(m);}struct menu_item *detach_menu(struct list_menu *menu){ struct menu_item *i = NULL; if (menu->stack) { if (menu->stack_size) i = menu->stack[0]; mem_free(menu->stack); } return i;}voiddestroy_menu(struct list_menu *menu){ if (menu->stack) free_menu(menu->stack[0]); detach_menu(menu);}voidmenu_labels(struct menu_item *items, unsigned char *base, unsigned char **lbls){ struct menu_item *item; unsigned char *bs; foreach_menu_item (item, items) { bs = (item->flags & MENU_FULLNAME) ? (unsigned char *) "" : base; bs = straconcat(bs, item->text, NULL); if (!bs) continue; if (item->func == do_select_submenu) { add_to_strn(&bs, " "); menu_labels(item->data, bs, lbls); mem_free(bs); } else { assert(item->func == selected_item); lbls[(long) item->data] = bs; } }}voidadd_select_item(struct list_menu *menu, struct string *string, struct string *orig_string, unsigned char **value, int order, int dont_add){ int pos = order - 1; assert(menu && string); if (!string->source) return; assert(value && pos >= 0); if (!value[pos]) /* <select> values are not mangled by various encode_*() * functions, therefore we need to store them in the * original document encoding. */ value[pos] = memacpy(orig_string->source, orig_string->length); if (dont_add) { done_string(string); } else { new_menu_item(menu, string->source, pos, 1); string->source = NULL; string->length = 0; } done_string(orig_string);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -