aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig
diff options
context:
space:
mode:
authorBenjamin Poirier <bpoirier@suse.de>2013-04-16 10:07:23 -0400
committerYann E. MORIN <yann.morin.1998@free.fr>2013-04-16 16:00:31 -0400
commit9a69abf80edf2ea0dac058cab156879d29362788 (patch)
treeb94e9a202805b4de9afce670e17ba720592d2cc5 /scripts/kconfig
parentedb749f4390b3c1604233dc7c4fb0361f472e712 (diff)
menuconfig: Add "breadcrumbs" navigation aid
Displays a trail of the menu entries used to get to the current menu. Signed-off-by: Benjamin Poirier <bpoirier@suse.de> Tested-by: "Yann E. MORIN" <yann.morin.1998@free.fr> [yann.morin.1998@free.fr: small, trivial code re-ordering] Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Diffstat (limited to 'scripts/kconfig')
-rw-r--r--scripts/kconfig/list.h27
-rw-r--r--scripts/kconfig/lxdialog/dialog.h7
-rw-r--r--scripts/kconfig/lxdialog/util.c45
-rw-r--r--scripts/kconfig/mconf.c71
4 files changed, 147 insertions, 3 deletions
diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h
index b87206cc92f4..ea1d58119d20 100644
--- a/scripts/kconfig/list.h
+++ b/scripts/kconfig/list.h
@@ -101,4 +101,31 @@ static inline void list_add_tail(struct list_head *_new, struct list_head *head)
101 __list_add(_new, head->prev, head); 101 __list_add(_new, head->prev, head);
102} 102}
103 103
104/*
105 * Delete a list entry by making the prev/next entries
106 * point to each other.
107 *
108 * This is only for internal list manipulation where we know
109 * the prev/next entries already!
110 */
111static inline void __list_del(struct list_head *prev, struct list_head *next)
112{
113 next->prev = prev;
114 prev->next = next;
115}
116
117#define LIST_POISON1 ((void *) 0x00100100)
118#define LIST_POISON2 ((void *) 0x00200200)
119/**
120 * list_del - deletes entry from list.
121 * @entry: the element to delete from the list.
122 * Note: list_empty() on entry does not return true after this, the entry is
123 * in an undefined state.
124 */
125static inline void list_del(struct list_head *entry)
126{
127 __list_del(entry->prev, entry->next);
128 entry->next = LIST_POISON1;
129 entry->prev = LIST_POISON2;
130}
104#endif 131#endif
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index 307022a8beef..1099337079b6 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -106,8 +106,14 @@ struct dialog_color {
106 int hl; /* highlight this item */ 106 int hl; /* highlight this item */
107}; 107};
108 108
109struct subtitle_list {
110 struct subtitle_list *next;
111 const char *text;
112};
113
109struct dialog_info { 114struct dialog_info {
110 const char *backtitle; 115 const char *backtitle;
116 struct subtitle_list *subtitles;
111 struct dialog_color screen; 117 struct dialog_color screen;
112 struct dialog_color shadow; 118 struct dialog_color shadow;
113 struct dialog_color dialog; 119 struct dialog_color dialog;
@@ -196,6 +202,7 @@ int on_key_resize(void);
196 202
197int init_dialog(const char *backtitle); 203int init_dialog(const char *backtitle);
198void set_dialog_backtitle(const char *backtitle); 204void set_dialog_backtitle(const char *backtitle);
205void set_dialog_subtitles(struct subtitle_list *subtitles);
199void end_dialog(int x, int y); 206void end_dialog(int x, int y);
200void attr_clear(WINDOW * win, int height, int width, chtype attr); 207void attr_clear(WINDOW * win, int height, int width, chtype attr);
201void dialog_clear(void); 208void dialog_clear(void);
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index 109d53117d22..a0e97c299410 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -257,12 +257,48 @@ void dialog_clear(void)
257 attr_clear(stdscr, LINES, COLS, dlg.screen.atr); 257 attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
258 /* Display background title if it exists ... - SLH */ 258 /* Display background title if it exists ... - SLH */
259 if (dlg.backtitle != NULL) { 259 if (dlg.backtitle != NULL) {
260 int i; 260 int i, len = 0, skip = 0;
261 struct subtitle_list *pos;
261 262
262 wattrset(stdscr, dlg.screen.atr); 263 wattrset(stdscr, dlg.screen.atr);
263 mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); 264 mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
265
266 for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
267 /* 3 is for the arrow and spaces */
268 len += strlen(pos->text) + 3;
269 }
270
264 wmove(stdscr, 1, 1); 271 wmove(stdscr, 1, 1);
265 for (i = 1; i < COLS - 1; i++) 272 if (len > COLS - 2) {
273 const char *ellipsis = "[...] ";
274 waddstr(stdscr, ellipsis);
275 skip = len - (COLS - 2 - strlen(ellipsis));
276 }
277
278 for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
279 if (skip == 0)
280 waddch(stdscr, ACS_RARROW);
281 else
282 skip--;
283
284 if (skip == 0)
285 waddch(stdscr, ' ');
286 else
287 skip--;
288
289 if (skip < strlen(pos->text)) {
290 waddstr(stdscr, pos->text + skip);
291 skip = 0;
292 } else
293 skip -= strlen(pos->text);
294
295 if (skip == 0)
296 waddch(stdscr, ' ');
297 else
298 skip--;
299 }
300
301 for (i = len + 1; i < COLS - 1; i++)
266 waddch(stdscr, ACS_HLINE); 302 waddch(stdscr, ACS_HLINE);
267 } 303 }
268 wnoutrefresh(stdscr); 304 wnoutrefresh(stdscr);
@@ -302,6 +338,11 @@ void set_dialog_backtitle(const char *backtitle)
302 dlg.backtitle = backtitle; 338 dlg.backtitle = backtitle;
303} 339}
304 340
341void set_dialog_subtitles(struct subtitle_list *subtitles)
342{
343 dlg.subtitles = subtitles;
344}
345
305/* 346/*
306 * End using dialog functions. 347 * End using dialog functions.
307 */ 348 */
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index c5418d622a05..387dc8daf7b2 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -311,6 +311,50 @@ static void set_config_filename(const char *config_filename)
311 filename[sizeof(filename)-1] = '\0'; 311 filename[sizeof(filename)-1] = '\0';
312} 312}
313 313
314struct subtitle_part {
315 struct list_head entries;
316 const char *text;
317};
318static LIST_HEAD(trail);
319
320static struct subtitle_list *subtitles;
321static void set_subtitle(void)
322{
323 struct subtitle_part *sp;
324 struct subtitle_list *pos, *tmp;
325
326 for (pos = subtitles; pos != NULL; pos = tmp) {
327 tmp = pos->next;
328 free(pos);
329 }
330
331 subtitles = NULL;
332 list_for_each_entry(sp, &trail, entries) {
333 if (sp->text) {
334 if (pos) {
335 pos->next = xcalloc(sizeof(*pos), 1);
336 pos = pos->next;
337 } else {
338 subtitles = pos = xcalloc(sizeof(*pos), 1);
339 }
340 pos->text = sp->text;
341 }
342 }
343
344 set_dialog_subtitles(subtitles);
345}
346
347static void reset_subtitle(void)
348{
349 struct subtitle_list *pos, *tmp;
350
351 for (pos = subtitles; pos != NULL; pos = tmp) {
352 tmp = pos->next;
353 free(pos);
354 }
355 subtitles = NULL;
356 set_dialog_subtitles(subtitles);
357}
314 358
315struct search_data { 359struct search_data {
316 struct list_head *head; 360 struct list_head *head;
@@ -353,6 +397,8 @@ static void search_conf(void)
353 char *dialog_input; 397 char *dialog_input;
354 int dres, vscroll = 0, hscroll = 0; 398 int dres, vscroll = 0, hscroll = 0;
355 bool again; 399 bool again;
400 struct gstr sttext;
401 struct subtitle_part stpart;
356 402
357 title = str_new(); 403 title = str_new();
358 str_printf( &title, _("Enter %s (sub)string to search for " 404 str_printf( &title, _("Enter %s (sub)string to search for "
@@ -379,6 +425,11 @@ again:
379 if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) 425 if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
380 dialog_input += strlen(CONFIG_); 426 dialog_input += strlen(CONFIG_);
381 427
428 sttext = str_new();
429 str_printf(&sttext, "Search (%s)", dialog_input_result);
430 stpart.text = str_get(&sttext);
431 list_add_tail(&stpart.entries, &trail);
432
382 sym_arr = sym_re_search(dialog_input); 433 sym_arr = sym_re_search(dialog_input);
383 do { 434 do {
384 LIST_HEAD(head); 435 LIST_HEAD(head);
@@ -392,6 +443,7 @@ again:
392 struct jump_key *pos, *tmp; 443 struct jump_key *pos, *tmp;
393 444
394 res = get_relations_str(sym_arr, &head); 445 res = get_relations_str(sym_arr, &head);
446 set_subtitle();
395 dres = show_textbox_ext(_("Search Results"), (char *) 447 dres = show_textbox_ext(_("Search Results"), (char *)
396 str_get(&res), 0, 0, keys, &vscroll, 448 str_get(&res), 0, 0, keys, &vscroll,
397 &hscroll, &update_text, (void *) 449 &hscroll, &update_text, (void *)
@@ -408,6 +460,8 @@ again:
408 } while (again); 460 } while (again);
409 free(sym_arr); 461 free(sym_arr);
410 str_free(&title); 462 str_free(&title);
463 list_del(trail.prev);
464 str_free(&sttext);
411} 465}
412 466
413static void build_conf(struct menu *menu) 467static void build_conf(struct menu *menu)
@@ -592,16 +646,24 @@ static void conf(struct menu *menu, struct menu *active_menu)
592{ 646{
593 struct menu *submenu; 647 struct menu *submenu;
594 const char *prompt = menu_get_prompt(menu); 648 const char *prompt = menu_get_prompt(menu);
649 struct subtitle_part stpart;
595 struct symbol *sym; 650 struct symbol *sym;
596 int res; 651 int res;
597 int s_scroll = 0; 652 int s_scroll = 0;
598 653
654 if (menu != &rootmenu)
655 stpart.text = menu_get_prompt(menu);
656 else
657 stpart.text = NULL;
658 list_add_tail(&stpart.entries, &trail);
659
599 while (1) { 660 while (1) {
600 item_reset(); 661 item_reset();
601 current_menu = menu; 662 current_menu = menu;
602 build_conf(menu); 663 build_conf(menu);
603 if (!child_count) 664 if (!child_count)
604 break; 665 break;
666 set_subtitle();
605 dialog_clear(); 667 dialog_clear();
606 res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), 668 res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
607 _(menu_instructions), 669 _(menu_instructions),
@@ -643,13 +705,17 @@ static void conf(struct menu *menu, struct menu *active_menu)
643 case 2: 705 case 2:
644 if (sym) 706 if (sym)
645 show_help(submenu); 707 show_help(submenu);
646 else 708 else {
709 reset_subtitle();
647 show_helptext(_("README"), _(mconf_readme)); 710 show_helptext(_("README"), _(mconf_readme));
711 }
648 break; 712 break;
649 case 3: 713 case 3:
714 reset_subtitle();
650 conf_save(); 715 conf_save();
651 break; 716 break;
652 case 4: 717 case 4:
718 reset_subtitle();
653 conf_load(); 719 conf_load();
654 break; 720 break;
655 case 5: 721 case 5:
@@ -682,6 +748,8 @@ static void conf(struct menu *menu, struct menu *active_menu)
682 break; 748 break;
683 } 749 }
684 } 750 }
751
752 list_del(trail.prev);
685} 753}
686 754
687static int show_textbox_ext(const char *title, char *text, int r, int c, int 755static int show_textbox_ext(const char *title, char *text, int r, int c, int
@@ -884,6 +952,7 @@ static int handle_exit(void)
884 int res; 952 int res;
885 953
886 save_and_exit = 1; 954 save_and_exit = 1;
955 reset_subtitle();
887 dialog_clear(); 956 dialog_clear();
888 if (conf_get_changed()) 957 if (conf_get_changed())
889 res = dialog_yesno(NULL, 958 res = dialog_yesno(NULL,