#include "lkc.h"
#include "lxdialog/dialog.h"
-#define JUMP_NB 9
-
static const char mconf_readme[] =
"OpenWrt config is based on Kernel kconfig\n"
"so ipkg packages are referred here as modules.\n"
"(especially with a larger number of unrolled categories) than the\n"
"default mode.\n"
"\n"
+
+"Search\n"
+"-------\n"
+"Pressing the forward-slash (/) anywhere brings up a search dialog box.\n"
+"\n"
+
"Different color themes available\n"
"--------------------------------\n"
"It is possible to select different color themes using the variable\n"
static int show_all_options;
static int save_and_exit;
static int silent;
+static int jump_key_char;
static void conf(struct menu *menu, struct menu *active_menu);
-static void conf_choice(struct menu *menu);
-static void conf_string(struct menu *menu);
-static void conf_load(void);
-static void conf_save(void);
-static int show_textbox_ext(const char *title, char *text, int r, int c,
- int *keys, int *vscroll, int *hscroll,
- update_text_fn update_text, void *data);
-static void show_textbox(const char *title, const char *text, int r, int c);
-static void show_helptext(const char *title, const char *text);
-static void show_help(struct menu *menu);
static char filename[PATH_MAX+1];
static void set_config_filename(const char *config_filename)
set_dialog_subtitles(subtitles);
}
+static int show_textbox_ext(const char *title, const char *text, int r, int c,
+ int *vscroll, int *hscroll,
+ int (*extra_key_cb)(int, size_t, size_t, void *),
+ void *data)
+{
+ dialog_clear();
+ return dialog_textbox(title, text, r, c, vscroll, hscroll,
+ extra_key_cb, data);
+}
+
+static void show_textbox(const char *title, const char *text, int r, int c)
+{
+ show_textbox_ext(title, text, r, c, NULL, NULL, NULL, NULL);
+}
+
+static void show_helptext(const char *title, const char *text)
+{
+ show_textbox(title, text, 0, 0);
+}
+
+static void show_help(struct menu *menu)
+{
+ struct gstr help = str_new();
+
+ help.max_width = getmaxx(stdscr) - 10;
+ menu_get_ext_help(menu, &help);
+
+ show_helptext(menu_get_prompt(menu), str_get(&help));
+ str_free(&help);
+}
+
struct search_data {
struct list_head *head;
- struct menu **targets;
- int *keys;
+ struct menu *target;
};
-static void update_text(char *buf, size_t start, size_t end, void *_data)
+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 k = 0;
+ int index = 0;
+
+ if (key < '1' || key > '9')
+ return 0;
list_for_each_entry(pos, data->head, entries) {
- if (pos->offset >= start && pos->offset < end) {
- char header[4];
+ index = next_jump_key(index);
- if (k < JUMP_NB) {
- int key = '0' + (pos->index % JUMP_NB) + 1;
+ if (pos->offset < start)
+ continue;
- sprintf(header, "(%c)", key);
- data->keys[k] = key;
- data->targets[k] = pos->target;
- k++;
- } else {
- sprintf(header, " ");
- }
+ if (pos->offset >= end)
+ break;
- memcpy(buf + pos->offset, header, sizeof(header) - 1);
+ if (key == index) {
+ data->target = pos->target;
+ return 1;
}
}
- data->keys[k] = 0;
+
+ 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)
sym_arr = sym_re_search(dialog_input);
do {
LIST_HEAD(head);
- struct menu *targets[JUMP_NB];
- int keys[JUMP_NB + 1], i;
struct search_data data = {
.head = &head,
- .targets = targets,
- .keys = keys,
};
struct jump_key *pos, *tmp;
+ jump_key_char = 0;
res = get_relations_str(sym_arr, &head);
set_subtitle();
- dres = show_textbox_ext("Search Results", (char *)
- str_get(&res), 0, 0, keys, &vscroll,
- &hscroll, &update_text, (void *)
- &data);
+ dres = show_textbox_ext("Search Results", str_get(&res), 0, 0,
+ &vscroll, &hscroll,
+ handle_search_keys, &data);
again = false;
- for (i = 0; i < JUMP_NB && keys[i]; i++)
- if (dres == keys[i]) {
- conf(targets[i]->parent, targets[i]);
- again = true;
- }
+ if (dres >= '1' && dres <= '9') {
+ assert(data.target != NULL);
+ conf(data.target->parent, data.target);
+ again = true;
+ }
str_free(&res);
list_for_each_entry_safe(pos, tmp, &head, entries)
free(pos);
indent -= doint;
}
-static void conf(struct menu *menu, struct menu *active_menu)
-{
- struct menu *submenu;
- const char *prompt = menu_get_prompt(menu);
- struct subtitle_part stpart;
- struct symbol *sym;
- int res;
- int s_scroll = 0;
-
- if (menu != &rootmenu)
- stpart.text = menu_get_prompt(menu);
- else
- stpart.text = NULL;
- list_add_tail(&stpart.entries, &trail);
-
- while (1) {
- item_reset();
- current_menu = menu;
- build_conf(menu);
- if (!child_count)
- break;
- set_subtitle();
- dialog_clear();
- res = dialog_menu(prompt ? prompt : "Main Menu",
- menu_instructions,
- active_menu, &s_scroll);
- if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
- break;
- if (item_count() != 0) {
- if (!item_activate_selected())
- continue;
- if (!item_tag())
- continue;
- }
- submenu = item_data();
- active_menu = item_data();
- if (submenu)
- sym = submenu->sym;
- else
- sym = NULL;
-
- switch (res) {
- case 0:
- switch (item_tag()) {
- case 'm':
- if (single_menu_mode)
- submenu->data = (void *) (long) !submenu->data;
- else
- conf(submenu, NULL);
- break;
- case 't':
- if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
- conf_choice(submenu);
- else if (submenu->prompt->type == P_MENU)
- conf(submenu, NULL);
- break;
- case 's':
- conf_string(submenu);
- break;
- }
- break;
- case 2:
- if (sym)
- show_help(submenu);
- else {
- reset_subtitle();
- show_helptext("README", mconf_readme);
- }
- break;
- case 3:
- reset_subtitle();
- conf_save();
- break;
- case 4:
- reset_subtitle();
- conf_load();
- break;
- case 5:
- if (item_is_tag('t')) {
- if (sym_set_tristate_value(sym, yes))
- break;
- if (sym_set_tristate_value(sym, mod))
- show_textbox(NULL, setmod_text, 6, 74);
- }
- break;
- case 6:
- if (item_is_tag('t'))
- sym_set_tristate_value(sym, no);
- break;
- case 7:
- if (item_is_tag('t'))
- sym_set_tristate_value(sym, mod);
- break;
- case 8:
- if (item_is_tag('t'))
- sym_toggle_tristate_value(sym);
- else if (item_is_tag('m'))
- conf(submenu, NULL);
- break;
- case 9:
- search_conf();
- break;
- case 10:
- show_all_options = !show_all_options;
- break;
- }
- }
-
- list_del(trail.prev);
-}
-
-static int show_textbox_ext(const char *title, char *text, int r, int c, int
- *keys, int *vscroll, int *hscroll, update_text_fn
- update_text, void *data)
-{
- dialog_clear();
- return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
- update_text, data);
-}
-
-static void show_textbox(const char *title, const char *text, int r, int c)
-{
- show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
- NULL, NULL);
-}
-
-static void show_helptext(const char *title, const char *text)
-{
- show_textbox(title, text, 0, 0);
-}
-
-static void conf_message_callback(const char *s)
-{
- if (save_and_exit) {
- if (!silent)
- printf("%s", s);
- } else {
- show_textbox(NULL, s, 6, 60);
- }
-}
-
-static void show_help(struct menu *menu)
-{
- struct gstr help = str_new();
-
- help.max_width = getmaxx(stdscr) - 10;
- menu_get_ext_help(menu, &help);
-
- show_helptext(menu_get_prompt(menu), str_get(&help));
- str_free(&help);
-}
-
static void conf_choice(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
}
}
+static void conf(struct menu *menu, struct menu *active_menu)
+{
+ struct menu *submenu;
+ const char *prompt = menu_get_prompt(menu);
+ struct subtitle_part stpart;
+ struct symbol *sym;
+ int res;
+ int s_scroll = 0;
+
+ if (menu != &rootmenu)
+ stpart.text = menu_get_prompt(menu);
+ else
+ stpart.text = NULL;
+ list_add_tail(&stpart.entries, &trail);
+
+ while (1) {
+ item_reset();
+ current_menu = menu;
+ build_conf(menu);
+ if (!child_count)
+ break;
+ set_subtitle();
+ dialog_clear();
+ res = dialog_menu(prompt ? prompt : "Main Menu",
+ menu_instructions,
+ active_menu, &s_scroll);
+ if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
+ break;
+ if (item_count() != 0) {
+ if (!item_activate_selected())
+ continue;
+ if (!item_tag())
+ continue;
+ }
+ submenu = item_data();
+ active_menu = item_data();
+ if (submenu)
+ sym = submenu->sym;
+ else
+ sym = NULL;
+
+ switch (res) {
+ case 0:
+ switch (item_tag()) {
+ case 'm':
+ if (single_menu_mode)
+ submenu->data = (void *) (long) !submenu->data;
+ else
+ conf(submenu, NULL);
+ break;
+ case 't':
+ if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
+ conf_choice(submenu);
+ else if (submenu->prompt->type == P_MENU)
+ conf(submenu, NULL);
+ break;
+ case 's':
+ conf_string(submenu);
+ break;
+ }
+ break;
+ case 2:
+ if (sym)
+ show_help(submenu);
+ else {
+ reset_subtitle();
+ show_helptext("README", mconf_readme);
+ }
+ break;
+ case 3:
+ reset_subtitle();
+ conf_save();
+ break;
+ case 4:
+ reset_subtitle();
+ conf_load();
+ break;
+ case 5:
+ if (item_is_tag('t')) {
+ if (sym_set_tristate_value(sym, yes))
+ break;
+ if (sym_set_tristate_value(sym, mod))
+ show_textbox(NULL, setmod_text, 6, 74);
+ }
+ break;
+ case 6:
+ if (item_is_tag('t'))
+ sym_set_tristate_value(sym, no);
+ break;
+ case 7:
+ if (item_is_tag('t'))
+ sym_set_tristate_value(sym, mod);
+ break;
+ case 8:
+ if (item_is_tag('t'))
+ sym_toggle_tristate_value(sym);
+ else if (item_is_tag('m'))
+ conf(submenu, NULL);
+ break;
+ case 9:
+ search_conf();
+ break;
+ case 10:
+ show_all_options = !show_all_options;
+ break;
+ }
+ }
+
+ list_del(trail.prev);
+}
+
+static void conf_message_callback(const char *s)
+{
+ if (save_and_exit) {
+ if (!silent)
+ printf("%s", s);
+ } else {
+ show_textbox(NULL, s, 6, 60);
+ }
+}
+
static int handle_exit(void)
{
int res;