"Location:\n"
" -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
" -> PCI support (PCI [ = y])\n"
-" -> PCI access mode (<choice> [ = y])\n"
+"(1) -> PCI access mode (<choice> [ = y])\n"
"Selects: LIBCRC32\n"
"Selected by: BAR\n"
"-----------------------------------------------------------------\n"
"o The 'Depends on:' line lists symbols that need to be defined for\n"
" this symbol to be visible and selectable in the menu.\n"
"o The 'Location:' lines tell, where in the menu structure this symbol\n"
-" is located. A location followed by a [ = y] indicates that this is\n"
-" a selectable menu item, and the current value is displayed inside\n"
-" brackets.\n"
+" is located.\n"
+" A location followed by a [ = y] indicates that this is\n"
+" a selectable menu item, and the current value is displayed inside\n"
+" brackets.\n"
+" Press the key in the (#) prefix to jump directly to that\n"
+" location. You will be returned to the current search results\n"
+" after exiting this new menu.\n"
"o The 'Selects:' line tells, what symbol will be automatically selected\n"
" if this symbol is selected (y or m).\n"
"o The 'Selected by' line tells what symbol has selected this symbol.\n"
static char *dialog_input_result;
static int dialog_input_result_len;
+static int jump_key_char;
+static void selected_conf(struct menu *menu, struct menu *active_menu);
static void conf(struct menu *menu);
static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
return 0;
}
+struct search_data {
+ struct list_head *head;
+ struct menu *target;
+};
+
+static int next_jump_key(int key)
+{
+ if (key < '1' || key > '9')
+ return '1';
+
+ key++;
+
+ if (key > '9')
+ key = '1';
+
+ return key;
+}
+
+static int handle_search_keys(int key, size_t start, size_t end, void *_data)
+{
+ struct search_data *data = _data;
+ struct jump_key *pos;
+ int index = 0;
+
+ if (key < '1' || key > '9')
+ return 0;
+
+ list_for_each_entry(pos, data->head, entries) {
+ index = next_jump_key(index);
+
+ if (pos->offset < start)
+ continue;
+
+ if (pos->offset >= end)
+ break;
+
+ if (key == index) {
+ data->target = pos->target;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int get_jump_key_char(void)
+{
+ jump_key_char = next_jump_key(jump_key_char);
+
+ return jump_key_char;
+}
static void search_conf(void)
{
struct gstr res;
struct gstr title;
char *dialog_input;
- int dres;
+ int dres, vscroll = 0, hscroll = 0;
+ bool again;
title = str_new();
str_printf( &title, "Enter (sub)string or regexp to search for "
dialog_input += strlen(CONFIG_);
sym_arr = sym_re_search(dialog_input);
- res = get_relations_str(sym_arr, NULL);
+
+ do {
+ LIST_HEAD(head);
+ struct search_data data = {
+ .head = &head,
+ .target = NULL,
+ };
+ jump_key_char = 0;
+ res = get_relations_str(sym_arr, &head);
+ dres = show_scroll_win_ext(main_window,
+ "Search Results", str_get(&res),
+ &vscroll, &hscroll,
+ handle_search_keys, &data);
+ again = false;
+ if (dres >= '1' && dres <= '9') {
+ assert(data.target != NULL);
+ selected_conf(data.target->parent, data.target);
+ again = true;
+ }
+ str_free(&res);
+ } while (again);
free(sym_arr);
- show_scroll_win(main_window,
- "Search Results", str_get(&res));
- str_free(&res);
str_free(&title);
}
static void conf(struct menu *menu)
{
+ selected_conf(menu, NULL);
+}
+
+static void selected_conf(struct menu *menu, struct menu *active_menu)
+{
struct menu *submenu = NULL;
struct symbol *sym;
- int res;
+ int i, res;
int current_index = 0;
int last_top_row = 0;
struct match_state match_state = {
if (!child_count)
break;
+ if (active_menu != NULL) {
+ for (i = 0; i < items_num; i++) {
+ struct mitem *mcur;
+
+ mcur = (struct mitem *) item_userptr(curses_menu_items[i]);
+ if ((struct menu *) mcur->usrptr == active_menu) {
+ current_index = i;
+ break;
+ }
+ }
+ active_menu = NULL;
+ }
+
show_menu(menu_get_prompt(menu), menu_instructions,
current_index, &last_top_row);
keypad((menu_win(curses_menu)), TRUE);
refresh();
}
-/* layman's scrollable window... */
void show_scroll_win(WINDOW *main_window,
const char *title,
const char *text)
{
+ (void)show_scroll_win_ext(main_window, title, (char *)text, NULL, NULL, NULL, NULL);
+}
+
+/* layman's scrollable window... */
+int show_scroll_win_ext(WINDOW *main_window, const char *title, char *text,
+ int *vscroll, int *hscroll,
+ extra_key_cb_fn extra_key_cb, void *data)
+{
int res;
int total_lines = get_line_no(text);
int x, y, lines, columns;
WINDOW *win;
WINDOW *pad;
PANEL *panel;
+ bool done = false;
+
+ if (hscroll)
+ start_x = *hscroll;
+ if (vscroll)
+ start_y = *vscroll;
getmaxyx(stdscr, lines, columns);
panel = new_panel(win);
/* handle scrolling */
- do {
-
+ while (!done) {
copywin(pad, win, start_y, start_x, 2, 2, text_lines,
text_cols, 0);
print_in_middle(win,
case 'l':
start_x++;
break;
+ default:
+ if (extra_key_cb) {
+ size_t start = (get_line(text, start_y) - text);
+ size_t end = (get_line(text, start_y + text_lines) - text);
+
+ if (extra_key_cb(res, start, end, data)) {
+ done = true;
+ break;
+ }
+ }
}
- if (res == 10 || res == 27 || res == 'q' ||
+ if (res == 0 || res == 10 || res == 27 || res == 'q' ||
res == KEY_F(F_HELP) || res == KEY_F(F_BACK) ||
res == KEY_F(F_EXIT))
break;
start_x = 0;
if (start_x >= total_cols-text_cols)
start_x = total_cols-text_cols;
- } while (res);
+ }
+ if (hscroll)
+ *hscroll = start_x;
+ if (vscroll)
+ *vscroll = start_y;
del_panel(panel);
delwin(win);
refresh_all_windows(main_window);
+ return res;
}
void set_colors(void);
+typedef int (*extra_key_cb_fn)(int, size_t, size_t, void *);
+
/* this changes the windows attributes !!! */
void print_in_middle(WINDOW *win, int y, int width, const char *str, int attrs);
int get_line_length(const char *line);
const char *title, const char *prompt,
const char *init, char **resultp, int *result_len);
void refresh_all_windows(WINDOW *main_window);
+int show_scroll_win_ext(WINDOW *main_window, const char *title, char *text,
+ int *vscroll, int *hscroll,
+ extra_key_cb_fn extra_key_cb, void *data);
void show_scroll_win(WINDOW *main_window,
const char *title,
const char *text);