Commit a72f3e2b authored by Nir Tzachar's avatar Nir Tzachar Committed by Michal Marek

nconfig: add search support

Remove the old hotkeys feature, and replace it by an interactive string
search.
From nconfig help:

Searching: pressing '/' triggers interactive search mode.
           nconfig performs a case insensitive search for the string
           in the menu prompts (no regex support).
           Pressing the up/down keys highlights the previous/next
           matching item. Backspace removes one character from the
           match string. Pressing either '/' again or ESC exits
           search mode. All other keys behave normally.

Miscellaneous other changes (including Rundy's and Justin's input).
Signed-off-by: default avatarNir Tzachar <nir.tzachar@gmail.com>
Acked-by: default avatarSam Ravnborg <sam@ravnborg.org>
Signed-off-by: default avatarMichal Marek <mmarek@suse.cz>
parent 3643f849
...@@ -5,9 +5,12 @@ ...@@ -5,9 +5,12 @@
* Derived from menuconfig. * Derived from menuconfig.
* *
*/ */
#define _GNU_SOURCE
#include <string.h>
#define LKC_DIRECT_LINK #define LKC_DIRECT_LINK
#include "lkc.h" #include "lkc.h"
#include "nconf.h" #include "nconf.h"
#include <ctype.h>
static const char nconf_readme[] = N_( static const char nconf_readme[] = N_(
"Overview\n" "Overview\n"
...@@ -23,7 +26,7 @@ static const char nconf_readme[] = N_( ...@@ -23,7 +26,7 @@ static const char nconf_readme[] = N_(
" < > can be built in, modularized or removed\n" " < > can be built in, modularized or removed\n"
" { } can be built in or modularized (selected by other feature)\n" " { } can be built in or modularized (selected by other feature)\n"
" - - are selected by other feature,\n" " - - are selected by other feature,\n"
" XXX cannot be selected. use Symbol Info to find out why,\n" " XXX cannot be selected. Use Symbol Info to find out why,\n"
"while *, M or whitespace inside braces means to build in, build as\n" "while *, M or whitespace inside braces means to build in, build as\n"
"a module or to exclude the feature respectively.\n" "a module or to exclude the feature respectively.\n"
"\n" "\n"
...@@ -41,9 +44,13 @@ static const char nconf_readme[] = N_( ...@@ -41,9 +44,13 @@ static const char nconf_readme[] = N_(
" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" " pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
" Submenus are designated by \"--->\".\n" " Submenus are designated by \"--->\".\n"
"\n" "\n"
" Shortcut: Press the option's highlighted letter (hotkey).\n" " Searching: pressing '/' triggers interactive search mode.\n"
" Pressing a hotkey more than once will sequence\n" " nconfig performs a case insensitive search for the string\n"
" through all visible items which use that hotkey.\n" " in the menu prompts (no regex support).\n"
" Pressing the up/down keys highlights the previous/next\n"
" matching item. Backspace removes one character from the\n"
" match string. Pressing either '/' again or ESC exits\n"
" search mode. All other keys behave normally.\n"
"\n" "\n"
" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
" unseen options into view.\n" " unseen options into view.\n"
...@@ -141,21 +148,21 @@ menu_no_f_instructions[] = N_( ...@@ -141,21 +148,21 @@ menu_no_f_instructions[] = N_(
" <Enter> or <right-arrow> selects submenus --->.\n" " <Enter> or <right-arrow> selects submenus --->.\n"
" Capital Letters are hotkeys.\n" " Capital Letters are hotkeys.\n"
" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
" Pressing SpaceBar toggles between the above options\n" " Pressing SpaceBar toggles between the above options.\n"
" Press <Esc> or <left-arrow> to go back one menu, \n" " Press <Esc> or <left-arrow> to go back one menu,\n"
" <?> or <h> for Help, </> for Search.\n" " <?> or <h> for Help, </> for Search.\n"
" <1> is interchangable with <F1>, <2> with <F2>, etc.\n" " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
" <Esc> always leaves the current window\n"), " <Esc> always leaves the current window.\n"),
menu_instructions[] = N_( menu_instructions[] = N_(
" Arrow keys navigate the menu.\n" " Arrow keys navigate the menu.\n"
" <Enter> or <right-arrow> selects submenus --->.\n" " <Enter> or <right-arrow> selects submenus --->.\n"
" Capital Letters are hotkeys.\n" " Capital Letters are hotkeys.\n"
" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
" Pressing SpaceBar toggles between the above options\n" " Pressing SpaceBar toggles between the above options\n"
" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n" " Press <Esc>, <F5> or <left-arrow> to go back one menu,\n"
" <?>, <F1> or <h> for Help, </> for Search.\n" " <?>, <F1> or <h> for Help, </> for Search.\n"
" <1> is interchangable with <F1>, <2> with <F2>, etc.\n" " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
" <Esc> always leaves the current window\n"), " <Esc> always leaves the current window\n"),
radiolist_instructions[] = N_( radiolist_instructions[] = N_(
...@@ -252,7 +259,6 @@ struct mitem { ...@@ -252,7 +259,6 @@ struct mitem {
char str[256]; char str[256];
char tag; char tag;
void *usrptr; void *usrptr;
int is_hot;
int is_visible; int is_visible;
}; };
...@@ -275,14 +281,6 @@ static int items_num; ...@@ -275,14 +281,6 @@ static int items_num;
static int global_exit; static int global_exit;
/* the currently selected button */ /* the currently selected button */
const char *current_instructions = menu_instructions; const char *current_instructions = menu_instructions;
/* this array is used to implement hot keys. it is updated in item_make and
* resetted in clean_items. It would be better to use a hash, but lets keep it
* simple... */
#define MAX_SAME_KEY MAX_MENU_ITEMS
struct {
int count;
int ptrs[MAX_MENU_ITEMS];
} hotkeys[1<<(sizeof(char)*8)];
static void conf(struct menu *menu); static void conf(struct menu *menu);
static void conf_choice(struct menu *menu); static void conf_choice(struct menu *menu);
...@@ -292,6 +290,7 @@ static void conf_save(void); ...@@ -292,6 +290,7 @@ static void conf_save(void);
static void show_help(struct menu *menu); static void show_help(struct menu *menu);
static int do_exit(void); static int do_exit(void);
static void setup_windows(void); static void setup_windows(void);
static void search_conf(void);
typedef void (*function_key_handler_t)(int *key, struct menu *menu); typedef void (*function_key_handler_t)(int *key, struct menu *menu);
static void handle_f1(int *key, struct menu *current_item); static void handle_f1(int *key, struct menu *current_item);
...@@ -302,6 +301,7 @@ static void handle_f5(int *key, struct menu *current_item); ...@@ -302,6 +301,7 @@ static void handle_f5(int *key, struct menu *current_item);
static void handle_f6(int *key, struct menu *current_item); static void handle_f6(int *key, struct menu *current_item);
static void handle_f7(int *key, struct menu *current_item); static void handle_f7(int *key, struct menu *current_item);
static void handle_f8(int *key, struct menu *current_item); static void handle_f8(int *key, struct menu *current_item);
static void handle_f9(int *key, struct menu *current_item);
struct function_keys { struct function_keys {
const char *key_str; const char *key_str;
...@@ -310,7 +310,7 @@ struct function_keys { ...@@ -310,7 +310,7 @@ struct function_keys {
function_key_handler_t handler; function_key_handler_t handler;
}; };
static const int function_keys_num = 8; static const int function_keys_num = 9;
struct function_keys function_keys[] = { struct function_keys function_keys[] = {
{ {
.key_str = "F1", .key_str = "F1",
...@@ -320,13 +320,13 @@ struct function_keys function_keys[] = { ...@@ -320,13 +320,13 @@ struct function_keys function_keys[] = {
}, },
{ {
.key_str = "F2", .key_str = "F2",
.func = "Symbol Info", .func = "Sym Info",
.key = F_SYMBOL, .key = F_SYMBOL,
.handler = handle_f2, .handler = handle_f2,
}, },
{ {
.key_str = "F3", .key_str = "F3",
.func = "Instructions", .func = "Insts",
.key = F_INSTS, .key = F_INSTS,
.handler = handle_f3, .handler = handle_f3,
}, },
...@@ -356,9 +356,15 @@ struct function_keys function_keys[] = { ...@@ -356,9 +356,15 @@ struct function_keys function_keys[] = {
}, },
{ {
.key_str = "F8", .key_str = "F8",
.func = "Sym Search",
.key = F_SEARCH,
.handler = handle_f8,
},
{
.key_str = "F9",
.func = "Exit", .func = "Exit",
.key = F_EXIT, .key = F_EXIT,
.handler = handle_f8, .handler = handle_f9,
}, },
}; };
...@@ -444,8 +450,15 @@ static void handle_f7(int *key, struct menu *current_item) ...@@ -444,8 +450,15 @@ static void handle_f7(int *key, struct menu *current_item)
return; return;
} }
/* exit */ /* search */
static void handle_f8(int *key, struct menu *current_item) static void handle_f8(int *key, struct menu *current_item)
{
search_conf();
return;
}
/* exit */
static void handle_f9(int *key, struct menu *current_item)
{ {
do_exit(); do_exit();
return; return;
...@@ -479,110 +492,44 @@ static void clean_items(void) ...@@ -479,110 +492,44 @@ static void clean_items(void)
free_item(curses_menu_items[i]); free_item(curses_menu_items[i]);
bzero(curses_menu_items, sizeof(curses_menu_items)); bzero(curses_menu_items, sizeof(curses_menu_items));
bzero(k_menu_items, sizeof(k_menu_items)); bzero(k_menu_items, sizeof(k_menu_items));
bzero(hotkeys, sizeof(hotkeys));
items_num = 0; items_num = 0;
} }
/* return the index of the next hot item, or -1 if no such item exists */ typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
static int get_next_hot(int c) FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
{
static int hot_index;
static int hot_char;
if (c < 0 || c > 255 || hotkeys[c].count <= 0)
return -1;
if (hot_char == c) {
hot_index = (hot_index+1)%hotkeys[c].count;
return hotkeys[c].ptrs[hot_index];
} else {
hot_char = c;
hot_index = 0;
return hotkeys[c].ptrs[0];
}
}
/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */
static int canbhot(char c)
{
c = tolower(c);
return isalnum(c) && c != 'y' && c != 'm' && c != 'h' &&
c != 'n' && c != '?';
}
/* check if str already contains a hot key. */
static int is_hot(int index)
{
return k_menu_items[index].is_hot;
}
/* find the first possible hot key, and mark it. /* return the index of the matched item, or -1 if no such item exists */
* index is the index of the item in the menu static int get_mext_match(const char *match_str, match_f flag)
* return 0 on success*/
static int make_hot(char *dest, int len, const char *org, int index)
{ {
int position = -1; int match_start = item_index(current_item(curses_menu));
int i; int index;
int tmp;
int c; if (flag == FIND_NEXT_MATCH_DOWN)
int org_len = strlen(org); ++match_start;
else if (flag == FIND_NEXT_MATCH_UP)
if (org == NULL || is_hot(index)) --match_start;
return 1;
index = match_start;
/* make sure not to make hot keys out of markers. index = (index + items_num) % items_num;
* find where to start looking for a hot key while (true) {
*/ char *str = k_menu_items[index].str;
i = 0; if (strcasestr(str, match_str) != 0)
/* skip white space */ return index;
while (i < org_len && org[i] == ' ') if (flag == FIND_NEXT_MATCH_UP ||
i++; flag == MATCH_TINKER_PATTERN_UP)
if (i == org_len) --index;
return -1; else
/* if encountering '(' or '<' or '[', find the match and look from there ++index;
**/ index = (index + items_num) % items_num;
if (org[i] == '[' || org[i] == '<' || org[i] == '(') { if (index == match_start)
i++; return -1;
for (; i < org_len; i++)
if (org[i] == ']' || org[i] == '>' || org[i] == ')')
break;
}
if (i == org_len)
return -1;
for (; i < org_len; i++) {
if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') {
position = i;
break;
}
} }
if (position == -1)
return 1;
/* ok, char at org[position] should be a hot key to this item */
c = tolower(org[position]);
tmp = hotkeys[c].count;
hotkeys[c].ptrs[tmp] = index;
hotkeys[c].count++;
/*
snprintf(dest, len, "%.*s(%c)%s", position, org, org[position],
&org[position+1]);
*/
/* make org[position] uppercase, and all leading letter small case */
strncpy(dest, org, len);
for (i = 0; i < position; i++)
dest[i] = tolower(dest[i]);
dest[position] = toupper(dest[position]);
k_menu_items[index].is_hot = 1;
return 0;
} }
/* Make a new item. Add a hotkey mark in the first possible letter. /* Make a new item. */
* As ncurses does not allow any attributes inside menue item, we mark the
* hot key as the first capitalized letter in the string */
static void item_make(struct menu *menu, char tag, const char *fmt, ...) static void item_make(struct menu *menu, char tag, const char *fmt, ...)
{ {
va_list ap; va_list ap;
char tmp_str[256];
if (items_num > MAX_MENU_ITEMS-1) if (items_num > MAX_MENU_ITEMS-1)
return; return;
...@@ -597,16 +544,13 @@ static void item_make(struct menu *menu, char tag, const char *fmt, ...) ...@@ -597,16 +544,13 @@ static void item_make(struct menu *menu, char tag, const char *fmt, ...)
k_menu_items[items_num].is_visible = 1; k_menu_items[items_num].is_visible = 1;
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap); vsnprintf(k_menu_items[items_num].str,
if (!k_menu_items[items_num].is_visible) sizeof(k_menu_items[items_num].str),
memcpy(tmp_str, "XXX", 3); fmt, ap);
va_end(ap); va_end(ap);
if (make_hot(
k_menu_items[items_num].str, if (!k_menu_items[items_num].is_visible)
sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0) memcpy(k_menu_items[items_num].str, "XXX", 3);
strncpy(k_menu_items[items_num].str,
tmp_str,
sizeof(k_menu_items[items_num].str));
curses_menu_items[items_num] = new_item( curses_menu_items[items_num] = new_item(
k_menu_items[items_num].str, k_menu_items[items_num].str,
...@@ -638,11 +582,9 @@ static void item_add_str(const char *fmt, ...) ...@@ -638,11 +582,9 @@ static void item_add_str(const char *fmt, ...)
va_end(ap); va_end(ap);
snprintf(tmp_str, sizeof(tmp_str), "%s%s", snprintf(tmp_str, sizeof(tmp_str), "%s%s",
k_menu_items[index].str, new_str); k_menu_items[index].str, new_str);
if (make_hot(k_menu_items[index].str, strncpy(k_menu_items[index].str,
sizeof(k_menu_items[index].str), tmp_str, index) != 0) tmp_str,
strncpy(k_menu_items[index].str, sizeof(k_menu_items[index].str));
tmp_str,
sizeof(k_menu_items[index].str));
free_item(curses_menu_items[index]); free_item(curses_menu_items[index]);
curses_menu_items[index] = new_item( curses_menu_items[index] = new_item(
...@@ -1027,23 +969,18 @@ static void reset_menu(void) ...@@ -1027,23 +969,18 @@ static void reset_menu(void)
static void center_item(int selected_index, int *last_top_row) static void center_item(int selected_index, int *last_top_row)
{ {
int toprow; int toprow;
int maxy, maxx;
scale_menu(curses_menu, &maxy, &maxx);
set_top_row(curses_menu, *last_top_row); set_top_row(curses_menu, *last_top_row);
toprow = top_row(curses_menu); toprow = top_row(curses_menu);
if (selected_index >= toprow && selected_index < toprow+maxy) { if (selected_index < toprow ||
/* we can only move the selected item. no need to scroll */ selected_index >= toprow+mwin_max_lines) {
set_current_item(curses_menu, toprow = max(selected_index-mwin_max_lines/2, 0);
curses_menu_items[selected_index]); if (toprow >= item_count(curses_menu)-mwin_max_lines)
} else {
toprow = max(selected_index-maxy/2, 0);
if (toprow >= item_count(curses_menu)-maxy)
toprow = item_count(curses_menu)-mwin_max_lines; toprow = item_count(curses_menu)-mwin_max_lines;
set_top_row(curses_menu, toprow); set_top_row(curses_menu, toprow);
set_current_item(curses_menu,
curses_menu_items[selected_index]);
} }
set_current_item(curses_menu,
curses_menu_items[selected_index]);
*last_top_row = toprow; *last_top_row = toprow;
post_menu(curses_menu); post_menu(curses_menu);
refresh_all_windows(main_window); refresh_all_windows(main_window);
...@@ -1075,7 +1012,7 @@ static void show_menu(const char *prompt, const char *instructions, ...@@ -1075,7 +1012,7 @@ static void show_menu(const char *prompt, const char *instructions,
/* position the menu at the middle of the screen */ /* position the menu at the middle of the screen */
scale_menu(curses_menu, &maxy, &maxx); scale_menu(curses_menu, &maxy, &maxx);
maxx = min(maxx, mwin_max_cols-2); maxx = min(maxx, mwin_max_cols-2);
maxy = mwin_max_lines-2; maxy = mwin_max_lines;
menu_window = derwin(main_window, menu_window = derwin(main_window,
maxy, maxy,
maxx, maxx,
...@@ -1099,10 +1036,77 @@ static void show_menu(const char *prompt, const char *instructions, ...@@ -1099,10 +1036,77 @@ static void show_menu(const char *prompt, const char *instructions,
refresh_all_windows(main_window); refresh_all_windows(main_window);
} }
static void adj_match_dir(match_f *match_direction)
{
if (*match_direction == FIND_NEXT_MATCH_DOWN)
*match_direction =
MATCH_TINKER_PATTERN_DOWN;
else if (*match_direction == FIND_NEXT_MATCH_UP)
*match_direction =
MATCH_TINKER_PATTERN_UP;
/* else, do no change.. */
}
static void conf(struct menu *menu) struct match_state
{ {
int in_search;
match_f match_direction;
char pattern[256]; char pattern[256];
};
/* Return 0 means I have handled the key. In such a case, ans should hold the
* item to center, or -1 otherwise.
* Else return -1 .
*/
static int do_match(int key, struct match_state *state, int *ans)
{
char c = (char) key;
int terminate_search = 0;
*ans = -1;
if (key == '/' || (state->in_search && key == 27)) {
move(0, 0);
refresh();
clrtoeol();
state->in_search = 1-state->in_search;
bzero(state->pattern, sizeof(state->pattern));
state->match_direction = MATCH_TINKER_PATTERN_DOWN;
return 0;
} else if (!state->in_search)
return 1;
if (isalnum(c) || isgraph(c) || c == ' ') {
state->pattern[strlen(state->pattern)] = c;
state->pattern[strlen(state->pattern)] = '\0';
adj_match_dir(&state->match_direction);
*ans = get_mext_match(state->pattern,
state->match_direction);
} else if (key == KEY_DOWN) {
state->match_direction = FIND_NEXT_MATCH_DOWN;
*ans = get_mext_match(state->pattern,
state->match_direction);
} else if (key == KEY_UP) {
state->match_direction = FIND_NEXT_MATCH_UP;
*ans = get_mext_match(state->pattern,
state->match_direction);
} else if (key == KEY_BACKSPACE || key == 127) {
state->pattern[strlen(state->pattern)-1] = '\0';
adj_match_dir(&state->match_direction);
} else
terminate_search = 1;
if (terminate_search) {
state->in_search = 0;
bzero(state->pattern, sizeof(state->pattern));
move(0, 0);
refresh();
clrtoeol();
return -1;
}
return 0;
}
static void conf(struct menu *menu)
{
struct menu *submenu = 0; struct menu *submenu = 0;
const char *prompt = menu_get_prompt(menu); const char *prompt = menu_get_prompt(menu);
struct symbol *sym; struct symbol *sym;
...@@ -1110,8 +1114,11 @@ static void conf(struct menu *menu) ...@@ -1110,8 +1114,11 @@ static void conf(struct menu *menu)
int res; int res;
int current_index = 0; int current_index = 0;
int last_top_row = 0; int last_top_row = 0;
struct match_state match_state = {
bzero(pattern, sizeof(pattern)); .in_search = 0,
.match_direction = MATCH_TINKER_PATTERN_DOWN,
.pattern = "",
};
while (!global_exit) { while (!global_exit) {
reset_menu(); reset_menu();
...@@ -1124,7 +1131,22 @@ static void conf(struct menu *menu) ...@@ -1124,7 +1131,22 @@ static void conf(struct menu *menu)
_(menu_instructions), _(menu_instructions),
current_index, &last_top_row); current_index, &last_top_row);
keypad((menu_win(curses_menu)), TRUE); keypad((menu_win(curses_menu)), TRUE);
while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { while (!global_exit) {
if (match_state.in_search) {
mvprintw(0, 0,
"searching: %s", match_state.pattern);
clrtoeol();
}
refresh_all_windows(main_window);
res = wgetch(menu_win(curses_menu));
if (!res)
break;
if (do_match(res, &match_state, &current_index) == 0) {
if (current_index != -1)
center_item(current_index,
&last_top_row);
continue;
}
if (process_special_keys(&res, if (process_special_keys(&res,
(struct menu *) item_data())) (struct menu *) item_data()))
break; break;
...@@ -1155,19 +1177,13 @@ static void conf(struct menu *menu) ...@@ -1155,19 +1177,13 @@ static void conf(struct menu *menu)
if (res == 10 || res == 27 || if (res == 10 || res == 27 ||
res == 32 || res == 'n' || res == 'y' || res == 32 || res == 'n' || res == 'y' ||
res == KEY_LEFT || res == KEY_RIGHT || res == KEY_LEFT || res == KEY_RIGHT ||
res == 'm' || res == '/') res == 'm')
break; break;
else if (canbhot(res)) {
/* check for hot keys: */
int tmp = get_next_hot(res);
if (tmp != -1)
center_item(tmp, &last_top_row);
}
refresh_all_windows(main_window); refresh_all_windows(main_window);
} }
refresh_all_windows(main_window); refresh_all_windows(main_window);
/* if ESC or left*/ /* if ESC or left*/
if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
break; break;
...@@ -1235,9 +1251,6 @@ static void conf(struct menu *menu) ...@@ -1235,9 +1251,6 @@ static void conf(struct menu *menu)
if (item_is_tag('t')) if (item_is_tag('t'))
sym_set_tristate_value(sym, mod); sym_set_tristate_value(sym, mod);
break; break;
case '/':
search_conf();
break;
} }
} }
} }
...@@ -1268,6 +1281,11 @@ static void conf_choice(struct menu *menu) ...@@ -1268,6 +1281,11 @@ static void conf_choice(struct menu *menu)
int selected_index = 0; int selected_index = 0;
int last_top_row = 0; int last_top_row = 0;
int res, i = 0; int res, i = 0;
struct match_state match_state = {
.in_search = 0,
.match_direction = MATCH_TINKER_PATTERN_DOWN,
.pattern = "",
};
active = sym_get_choice_value(menu->sym); active = sym_get_choice_value(menu->sym);
/* this is mostly duplicated from the conf() function. */ /* this is mostly duplicated from the conf() function. */
...@@ -1294,7 +1312,22 @@ static void conf_choice(struct menu *menu) ...@@ -1294,7 +1312,22 @@ static void conf_choice(struct menu *menu)
_(radiolist_instructions), _(radiolist_instructions),
selected_index, selected_index,
&last_top_row); &last_top_row);
while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { while (!global_exit) {
if (match_state.in_search) {
mvprintw(0, 0, "searching: %s",
match_state.pattern);
clrtoeol();
}
refresh_all_windows(main_window);
res = wgetch(menu_win(curses_menu));
if (!res)
break;
if (do_match(res, &match_state, &selected_index) == 0) {
if (selected_index != -1)
center_item(selected_index,
&last_top_row);
continue;
}
if (process_special_keys( if (process_special_keys(
&res, &res,
(struct menu *) item_data())) (struct menu *) item_data()))
...@@ -1324,13 +1357,8 @@ static void conf_choice(struct menu *menu) ...@@ -1324,13 +1357,8 @@ static void conf_choice(struct menu *menu)
break; break;
} }
if (res == 10 || res == 27 || res == ' ' || if (res == 10 || res == 27 || res == ' ' ||
res == KEY_LEFT) res == KEY_LEFT){
break; break;
else if (canbhot(res)) {
/* check for hot keys: */
int tmp = get_next_hot(res);
if (tmp != -1)
center_item(tmp, &last_top_row);
} }
refresh_all_windows(main_window); refresh_all_windows(main_window);
} }
...@@ -1485,7 +1513,7 @@ void setup_windows(void) ...@@ -1485,7 +1513,7 @@ void setup_windows(void)
/* set up the menu and menu window */ /* set up the menu and menu window */
main_window = newwin(LINES-2, COLS-2, 2, 1); main_window = newwin(LINES-2, COLS-2, 2, 1);
keypad(main_window, TRUE); keypad(main_window, TRUE);
mwin_max_lines = LINES-6; mwin_max_lines = LINES-7;
mwin_max_cols = COLS-6; mwin_max_cols = COLS-6;
/* panels order is from bottom to top */ /* panels order is from bottom to top */
...@@ -1532,9 +1560,10 @@ int main(int ac, char **av) ...@@ -1532,9 +1560,10 @@ int main(int ac, char **av)
/* set btns menu */ /* set btns menu */
curses_menu = new_menu(curses_menu_items); curses_menu = new_menu(curses_menu_items);
menu_opts_off(curses_menu, O_SHOWDESC); menu_opts_off(curses_menu, O_SHOWDESC);
menu_opts_off(curses_menu, O_SHOWMATCH); menu_opts_on(curses_menu, O_SHOWMATCH);
menu_opts_on(curses_menu, O_ONEVALUE); menu_opts_on(curses_menu, O_ONEVALUE);
menu_opts_on(curses_menu, O_NONCYCLIC); menu_opts_on(curses_menu, O_NONCYCLIC);
menu_opts_on(curses_menu, O_IGNORECASE);
set_menu_mark(curses_menu, " "); set_menu_mark(curses_menu, " ");
set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
...@@ -1550,8 +1579,6 @@ int main(int ac, char **av) ...@@ -1550,8 +1579,6 @@ int main(int ac, char **av)
_(menu_no_f_instructions)); _(menu_no_f_instructions));
} }
/* do the work */ /* do the work */
while (!global_exit) { while (!global_exit) {
conf(&rootmenu); conf(&rootmenu);
......
...@@ -167,7 +167,7 @@ void print_in_middle(WINDOW *win, ...@@ -167,7 +167,7 @@ void print_in_middle(WINDOW *win,
length = strlen(string); length = strlen(string);
temp = (width - length) / 2; temp = (width - length) / 2;
x = startx + (int)temp; x = startx + (int)temp;
wattrset(win, color); (void) wattrset(win, color);
mvwprintw(win, y, x, "%s", string); mvwprintw(win, y, x, "%s", string);
refresh(); refresh();
} }
...@@ -297,11 +297,11 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) ...@@ -297,11 +297,11 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
set_menu_back(menu, attributes[DIALOG_MENU_BACK]); set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
wattrset(win, attributes[DIALOG_BOX]); (void) wattrset(win, attributes[DIALOG_BOX]);
box(win, 0, 0); box(win, 0, 0);
/* print message */ /* print message */
wattrset(msg_win, attributes[DIALOG_TEXT]); (void) wattrset(msg_win, attributes[DIALOG_TEXT]);
fill_window(msg_win, msg); fill_window(msg_win, msg);
set_menu_win(menu, win); set_menu_win(menu, win);
...@@ -392,16 +392,16 @@ int dialog_inputbox(WINDOW *main_window, ...@@ -392,16 +392,16 @@ int dialog_inputbox(WINDOW *main_window,
form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
keypad(form_win, TRUE); keypad(form_win, TRUE);
wattrset(form_win, attributes[INPUT_FIELD]); (void) wattrset(form_win, attributes[INPUT_FIELD]);
wattrset(win, attributes[INPUT_BOX]); (void) wattrset(win, attributes[INPUT_BOX]);
box(win, 0, 0); box(win, 0, 0);
wattrset(win, attributes[INPUT_HEADING]); (void) wattrset(win, attributes[INPUT_HEADING]);
if (title) if (title)
mvwprintw(win, 0, 3, "%s", title); mvwprintw(win, 0, 3, "%s", title);
/* print message */ /* print message */
wattrset(prompt_win, attributes[INPUT_TEXT]); (void) wattrset(prompt_win, attributes[INPUT_TEXT]);
fill_window(prompt_win, prompt); fill_window(prompt_win, prompt);
mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
...@@ -531,7 +531,7 @@ void show_scroll_win(WINDOW *main_window, ...@@ -531,7 +531,7 @@ void show_scroll_win(WINDOW *main_window,
/* create the pad */ /* create the pad */
pad = newpad(total_lines+10, total_cols+10); pad = newpad(total_lines+10, total_cols+10);
wattrset(pad, attributes[SCROLLWIN_TEXT]); (void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
fill_window(pad, text); fill_window(pad, text);
win_lines = min(total_lines+4, LINES-2); win_lines = min(total_lines+4, LINES-2);
...@@ -546,9 +546,9 @@ void show_scroll_win(WINDOW *main_window, ...@@ -546,9 +546,9 @@ void show_scroll_win(WINDOW *main_window,
win = newwin(win_lines, win_cols, y, x); win = newwin(win_lines, win_cols, y, x);
keypad(win, TRUE); keypad(win, TRUE);
/* show the help in the help window, and show the help panel */ /* show the help in the help window, and show the help panel */
wattrset(win, attributes[SCROLLWIN_BOX]); (void) wattrset(win, attributes[SCROLLWIN_BOX]);
box(win, 0, 0); box(win, 0, 0);
wattrset(win, attributes[SCROLLWIN_HEADING]); (void) wattrset(win, attributes[SCROLLWIN_HEADING]);
mvwprintw(win, 0, 3, " %s ", title); mvwprintw(win, 0, 3, " %s ", title);
panel = new_panel(win); panel = new_panel(win);
......
...@@ -69,7 +69,8 @@ typedef enum { ...@@ -69,7 +69,8 @@ typedef enum {
F_BACK = 5, F_BACK = 5,
F_SAVE = 6, F_SAVE = 6,
F_LOAD = 7, F_LOAD = 7,
F_EXIT = 8 F_SEARCH = 8,
F_EXIT = 9,
} function_key; } function_key;
void set_colors(void); void set_colors(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment