16f6046cfSSam Ravnborg /* 26f6046cfSSam Ravnborg * checklist.c -- implements the checklist box 36f6046cfSSam Ravnborg * 46f6046cfSSam Ravnborg * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 56f6046cfSSam Ravnborg * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension 66f6046cfSSam Ravnborg * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two 76f6046cfSSam Ravnborg * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 86f6046cfSSam Ravnborg * 96f6046cfSSam Ravnborg * This program is free software; you can redistribute it and/or 106f6046cfSSam Ravnborg * modify it under the terms of the GNU General Public License 116f6046cfSSam Ravnborg * as published by the Free Software Foundation; either version 2 126f6046cfSSam Ravnborg * of the License, or (at your option) any later version. 136f6046cfSSam Ravnborg * 146f6046cfSSam Ravnborg * This program is distributed in the hope that it will be useful, 156f6046cfSSam Ravnborg * but WITHOUT ANY WARRANTY; without even the implied warranty of 166f6046cfSSam Ravnborg * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 176f6046cfSSam Ravnborg * GNU General Public License for more details. 186f6046cfSSam Ravnborg * 196f6046cfSSam Ravnborg * You should have received a copy of the GNU General Public License 206f6046cfSSam Ravnborg * along with this program; if not, write to the Free Software 216f6046cfSSam Ravnborg * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 226f6046cfSSam Ravnborg */ 236f6046cfSSam Ravnborg 246f6046cfSSam Ravnborg #include "dialog.h" 256f6046cfSSam Ravnborg 2600213b17SPetr Baudis static int list_width, check_x, item_x; 276f6046cfSSam Ravnborg 286f6046cfSSam Ravnborg /* 296f6046cfSSam Ravnborg * Print list item 306f6046cfSSam Ravnborg */ 312982de69SSam Ravnborg static void print_item(WINDOW * win, int choice, int selected) 326f6046cfSSam Ravnborg { 336f6046cfSSam Ravnborg int i; 346f6046cfSSam Ravnborg 356f6046cfSSam Ravnborg /* Clear 'residue' of last item */ 3698e5a157SSam Ravnborg wattrset(win, dlg.menubox.atr); 376f6046cfSSam Ravnborg wmove(win, choice, 0); 386f6046cfSSam Ravnborg for (i = 0; i < list_width; i++) 396f6046cfSSam Ravnborg waddch(win, ' '); 406f6046cfSSam Ravnborg 416f6046cfSSam Ravnborg wmove(win, choice, check_x); 4298e5a157SSam Ravnborg wattrset(win, selected ? dlg.check_selected.atr 4398e5a157SSam Ravnborg : dlg.check.atr); 44*af6c1598SPeter Korsgaard if (!item_is_tag(':')) 452982de69SSam Ravnborg wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); 466f6046cfSSam Ravnborg 4798e5a157SSam Ravnborg wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); 482982de69SSam Ravnborg mvwaddch(win, choice, item_x, item_str()[0]); 4998e5a157SSam Ravnborg wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); 502982de69SSam Ravnborg waddstr(win, (char *)item_str() + 1); 516f6046cfSSam Ravnborg if (selected) { 526f6046cfSSam Ravnborg wmove(win, choice, check_x + 1); 536f6046cfSSam Ravnborg wrefresh(win); 546f6046cfSSam Ravnborg } 556f6046cfSSam Ravnborg } 566f6046cfSSam Ravnborg 576f6046cfSSam Ravnborg /* 586f6046cfSSam Ravnborg * Print the scroll indicators. 596f6046cfSSam Ravnborg */ 606f6046cfSSam Ravnborg static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, 616f6046cfSSam Ravnborg int y, int x, int height) 626f6046cfSSam Ravnborg { 636f6046cfSSam Ravnborg wmove(win, y, x); 646f6046cfSSam Ravnborg 656f6046cfSSam Ravnborg if (scroll > 0) { 6698e5a157SSam Ravnborg wattrset(win, dlg.uarrow.atr); 676f6046cfSSam Ravnborg waddch(win, ACS_UARROW); 686f6046cfSSam Ravnborg waddstr(win, "(-)"); 696f6046cfSSam Ravnborg } else { 7098e5a157SSam Ravnborg wattrset(win, dlg.menubox.atr); 716f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 726f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 736f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 746f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 756f6046cfSSam Ravnborg } 766f6046cfSSam Ravnborg 776f6046cfSSam Ravnborg y = y + height + 1; 786f6046cfSSam Ravnborg wmove(win, y, x); 796f6046cfSSam Ravnborg 806f6046cfSSam Ravnborg if ((height < item_no) && (scroll + choice < item_no - 1)) { 8198e5a157SSam Ravnborg wattrset(win, dlg.darrow.atr); 826f6046cfSSam Ravnborg waddch(win, ACS_DARROW); 836f6046cfSSam Ravnborg waddstr(win, "(+)"); 846f6046cfSSam Ravnborg } else { 8598e5a157SSam Ravnborg wattrset(win, dlg.menubox_border.atr); 866f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 876f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 886f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 896f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 906f6046cfSSam Ravnborg } 916f6046cfSSam Ravnborg } 926f6046cfSSam Ravnborg 936f6046cfSSam Ravnborg /* 946f6046cfSSam Ravnborg * Display the termination buttons 956f6046cfSSam Ravnborg */ 966f6046cfSSam Ravnborg static void print_buttons(WINDOW * dialog, int height, int width, int selected) 976f6046cfSSam Ravnborg { 986f6046cfSSam Ravnborg int x = width / 2 - 11; 996f6046cfSSam Ravnborg int y = height - 2; 1006f6046cfSSam Ravnborg 10175c0a8a5SEGRY Gabor print_button(dialog, gettext("Select"), y, x, selected == 0); 10275c0a8a5SEGRY Gabor print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); 1036f6046cfSSam Ravnborg 1046f6046cfSSam Ravnborg wmove(dialog, y, x + 1 + 14 * selected); 1056f6046cfSSam Ravnborg wrefresh(dialog); 1066f6046cfSSam Ravnborg } 1076f6046cfSSam Ravnborg 1086f6046cfSSam Ravnborg /* 1096f6046cfSSam Ravnborg * Display a dialog box with a list of options that can be turned on or off 11000213b17SPetr Baudis * in the style of radiolist (only one option turned on at a time). 1116f6046cfSSam Ravnborg */ 1126f6046cfSSam Ravnborg int dialog_checklist(const char *title, const char *prompt, int height, 1132982de69SSam Ravnborg int width, int list_height) 1146f6046cfSSam Ravnborg { 1156f6046cfSSam Ravnborg int i, x, y, box_x, box_y; 1162982de69SSam Ravnborg int key = 0, button = 0, choice = 0, scroll = 0, max_choice; 1176f6046cfSSam Ravnborg WINDOW *dialog, *list; 1186f6046cfSSam Ravnborg 1192982de69SSam Ravnborg /* which item to highlight */ 1202982de69SSam Ravnborg item_foreach() { 1212982de69SSam Ravnborg if (item_is_tag('X')) 1222982de69SSam Ravnborg choice = item_n(); 1232982de69SSam Ravnborg if (item_is_selected()) { 1242982de69SSam Ravnborg choice = item_n(); 1252982de69SSam Ravnborg break; 1262982de69SSam Ravnborg } 1276f6046cfSSam Ravnborg } 1286f6046cfSSam Ravnborg 129c8dc68adSSam Ravnborg do_resize: 130c8dc68adSSam Ravnborg if (getmaxy(stdscr) < (height + 6)) 131c8dc68adSSam Ravnborg return -ERRDISPLAYTOOSMALL; 132c8dc68adSSam Ravnborg if (getmaxx(stdscr) < (width + 6)) 133c8dc68adSSam Ravnborg return -ERRDISPLAYTOOSMALL; 134c8dc68adSSam Ravnborg 1352982de69SSam Ravnborg max_choice = MIN(list_height, item_count()); 1366f6046cfSSam Ravnborg 1376f6046cfSSam Ravnborg /* center dialog box on screen */ 1386f6046cfSSam Ravnborg x = (COLS - width) / 2; 1396f6046cfSSam Ravnborg y = (LINES - height) / 2; 1406f6046cfSSam Ravnborg 1416f6046cfSSam Ravnborg draw_shadow(stdscr, y, x, height, width); 1426f6046cfSSam Ravnborg 1436f6046cfSSam Ravnborg dialog = newwin(height, width, y, x); 1446f6046cfSSam Ravnborg keypad(dialog, TRUE); 1456f6046cfSSam Ravnborg 14698e5a157SSam Ravnborg draw_box(dialog, 0, 0, height, width, 14798e5a157SSam Ravnborg dlg.dialog.atr, dlg.border.atr); 14898e5a157SSam Ravnborg wattrset(dialog, dlg.border.atr); 1496f6046cfSSam Ravnborg mvwaddch(dialog, height - 3, 0, ACS_LTEE); 1506f6046cfSSam Ravnborg for (i = 0; i < width - 2; i++) 1516f6046cfSSam Ravnborg waddch(dialog, ACS_HLINE); 15298e5a157SSam Ravnborg wattrset(dialog, dlg.dialog.atr); 1536f6046cfSSam Ravnborg waddch(dialog, ACS_RTEE); 1546f6046cfSSam Ravnborg 1556f6046cfSSam Ravnborg print_title(dialog, title, width); 1566f6046cfSSam Ravnborg 15798e5a157SSam Ravnborg wattrset(dialog, dlg.dialog.atr); 1586f6046cfSSam Ravnborg print_autowrap(dialog, prompt, width - 2, 1, 3); 1596f6046cfSSam Ravnborg 1606f6046cfSSam Ravnborg list_width = width - 6; 1616f6046cfSSam Ravnborg box_y = height - list_height - 5; 1626f6046cfSSam Ravnborg box_x = (width - list_width) / 2 - 1; 1636f6046cfSSam Ravnborg 1646f6046cfSSam Ravnborg /* create new window for the list */ 1656f6046cfSSam Ravnborg list = subwin(dialog, list_height, list_width, y + box_y + 1, 1666f6046cfSSam Ravnborg x + box_x + 1); 1676f6046cfSSam Ravnborg 1686f6046cfSSam Ravnborg keypad(list, TRUE); 1696f6046cfSSam Ravnborg 1706f6046cfSSam Ravnborg /* draw a box around the list items */ 1716f6046cfSSam Ravnborg draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, 17298e5a157SSam Ravnborg dlg.menubox_border.atr, dlg.menubox.atr); 1736f6046cfSSam Ravnborg 1746f6046cfSSam Ravnborg /* Find length of longest item in order to center checklist */ 1756f6046cfSSam Ravnborg check_x = 0; 1762982de69SSam Ravnborg item_foreach() 1772982de69SSam Ravnborg check_x = MAX(check_x, strlen(item_str()) + 4); 1786f6046cfSSam Ravnborg 1796f6046cfSSam Ravnborg check_x = (list_width - check_x) / 2; 1806f6046cfSSam Ravnborg item_x = check_x + 4; 1816f6046cfSSam Ravnborg 1826f6046cfSSam Ravnborg if (choice >= list_height) { 1836f6046cfSSam Ravnborg scroll = choice - list_height + 1; 1846f6046cfSSam Ravnborg choice -= scroll; 1856f6046cfSSam Ravnborg } 1866f6046cfSSam Ravnborg 1876f6046cfSSam Ravnborg /* Print the list */ 1886f6046cfSSam Ravnborg for (i = 0; i < max_choice; i++) { 1892982de69SSam Ravnborg item_set(scroll + i); 1902982de69SSam Ravnborg print_item(list, i, i == choice); 1916f6046cfSSam Ravnborg } 1926f6046cfSSam Ravnborg 1932982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), scroll, 1946f6046cfSSam Ravnborg box_y, box_x + check_x + 5, list_height); 1956f6046cfSSam Ravnborg 1966f6046cfSSam Ravnborg print_buttons(dialog, height, width, 0); 1976f6046cfSSam Ravnborg 1986f6046cfSSam Ravnborg wnoutrefresh(dialog); 199f043ca43SSamuel Thibault wnoutrefresh(list); 2006f6046cfSSam Ravnborg doupdate(); 2016f6046cfSSam Ravnborg 202f3cbcdc9SSam Ravnborg while (key != KEY_ESC) { 2036f6046cfSSam Ravnborg key = wgetch(dialog); 2046f6046cfSSam Ravnborg 2052982de69SSam Ravnborg for (i = 0; i < max_choice; i++) { 2062982de69SSam Ravnborg item_set(i + scroll); 2072982de69SSam Ravnborg if (toupper(key) == toupper(item_str()[0])) 2086f6046cfSSam Ravnborg break; 2092982de69SSam Ravnborg } 2106f6046cfSSam Ravnborg 2116f6046cfSSam Ravnborg if (i < max_choice || key == KEY_UP || key == KEY_DOWN || 2126f6046cfSSam Ravnborg key == '+' || key == '-') { 2136f6046cfSSam Ravnborg if (key == KEY_UP || key == '-') { 2146f6046cfSSam Ravnborg if (!choice) { 2156f6046cfSSam Ravnborg if (!scroll) 2166f6046cfSSam Ravnborg continue; 2176f6046cfSSam Ravnborg /* Scroll list down */ 2186f6046cfSSam Ravnborg if (list_height > 1) { 2196f6046cfSSam Ravnborg /* De-highlight current first item */ 2202982de69SSam Ravnborg item_set(scroll); 2212982de69SSam Ravnborg print_item(list, 0, FALSE); 2226f6046cfSSam Ravnborg scrollok(list, TRUE); 2236f6046cfSSam Ravnborg wscrl(list, -1); 2246f6046cfSSam Ravnborg scrollok(list, FALSE); 2256f6046cfSSam Ravnborg } 2266f6046cfSSam Ravnborg scroll--; 2272982de69SSam Ravnborg item_set(scroll); 2282982de69SSam Ravnborg print_item(list, 0, TRUE); 2292982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), 2306f6046cfSSam Ravnborg scroll, box_y, box_x + check_x + 5, list_height); 2316f6046cfSSam Ravnborg 232f043ca43SSamuel Thibault wnoutrefresh(dialog); 233f043ca43SSamuel Thibault wrefresh(list); 2346f6046cfSSam Ravnborg 2356f6046cfSSam Ravnborg continue; /* wait for another key press */ 2366f6046cfSSam Ravnborg } else 2376f6046cfSSam Ravnborg i = choice - 1; 2386f6046cfSSam Ravnborg } else if (key == KEY_DOWN || key == '+') { 2396f6046cfSSam Ravnborg if (choice == max_choice - 1) { 2402982de69SSam Ravnborg if (scroll + choice >= item_count() - 1) 2416f6046cfSSam Ravnborg continue; 2426f6046cfSSam Ravnborg /* Scroll list up */ 2436f6046cfSSam Ravnborg if (list_height > 1) { 2446f6046cfSSam Ravnborg /* De-highlight current last item before scrolling up */ 2452982de69SSam Ravnborg item_set(scroll + max_choice - 1); 2462982de69SSam Ravnborg print_item(list, 2472982de69SSam Ravnborg max_choice - 1, 2482982de69SSam Ravnborg FALSE); 2496f6046cfSSam Ravnborg scrollok(list, TRUE); 2506f6046cfSSam Ravnborg wscrl(list, 1); 2516f6046cfSSam Ravnborg scrollok(list, FALSE); 2526f6046cfSSam Ravnborg } 2536f6046cfSSam Ravnborg scroll++; 2542982de69SSam Ravnborg item_set(scroll + max_choice - 1); 2552982de69SSam Ravnborg print_item(list, max_choice - 1, TRUE); 2566f6046cfSSam Ravnborg 2572982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), 2586f6046cfSSam Ravnborg scroll, box_y, box_x + check_x + 5, list_height); 2596f6046cfSSam Ravnborg 260f043ca43SSamuel Thibault wnoutrefresh(dialog); 261f043ca43SSamuel Thibault wrefresh(list); 2626f6046cfSSam Ravnborg 2636f6046cfSSam Ravnborg continue; /* wait for another key press */ 2646f6046cfSSam Ravnborg } else 2656f6046cfSSam Ravnborg i = choice + 1; 2666f6046cfSSam Ravnborg } 2676f6046cfSSam Ravnborg if (i != choice) { 2686f6046cfSSam Ravnborg /* De-highlight current item */ 2692982de69SSam Ravnborg item_set(scroll + choice); 2702982de69SSam Ravnborg print_item(list, choice, FALSE); 2716f6046cfSSam Ravnborg /* Highlight new item */ 2726f6046cfSSam Ravnborg choice = i; 2732982de69SSam Ravnborg item_set(scroll + choice); 2742982de69SSam Ravnborg print_item(list, choice, TRUE); 275f043ca43SSamuel Thibault wnoutrefresh(dialog); 276f043ca43SSamuel Thibault wrefresh(list); 2776f6046cfSSam Ravnborg } 2786f6046cfSSam Ravnborg continue; /* wait for another key press */ 2796f6046cfSSam Ravnborg } 2806f6046cfSSam Ravnborg switch (key) { 2816f6046cfSSam Ravnborg case 'H': 2826f6046cfSSam Ravnborg case 'h': 2836f6046cfSSam Ravnborg case '?': 2842982de69SSam Ravnborg button = 1; 2852982de69SSam Ravnborg /* fall-through */ 2862982de69SSam Ravnborg case 'S': 2872982de69SSam Ravnborg case 's': 2882982de69SSam Ravnborg case ' ': 2892982de69SSam Ravnborg case '\n': 2902982de69SSam Ravnborg item_foreach() 2912982de69SSam Ravnborg item_set_selected(0); 2922982de69SSam Ravnborg item_set(scroll + choice); 2932982de69SSam Ravnborg item_set_selected(1); 2942982de69SSam Ravnborg delwin(list); 2956f6046cfSSam Ravnborg delwin(dialog); 2962982de69SSam Ravnborg return button; 2976f6046cfSSam Ravnborg case TAB: 2986f6046cfSSam Ravnborg case KEY_LEFT: 2996f6046cfSSam Ravnborg case KEY_RIGHT: 3006f6046cfSSam Ravnborg button = ((key == KEY_LEFT ? --button : ++button) < 0) 3016f6046cfSSam Ravnborg ? 1 : (button > 1 ? 0 : button); 3026f6046cfSSam Ravnborg 3036f6046cfSSam Ravnborg print_buttons(dialog, height, width, button); 3046f6046cfSSam Ravnborg wrefresh(dialog); 3056f6046cfSSam Ravnborg break; 3066f6046cfSSam Ravnborg case 'X': 3076f6046cfSSam Ravnborg case 'x': 308f3cbcdc9SSam Ravnborg key = KEY_ESC; 309f3cbcdc9SSam Ravnborg break; 310f3cbcdc9SSam Ravnborg case KEY_ESC: 311f3cbcdc9SSam Ravnborg key = on_key_esc(dialog); 3126f6046cfSSam Ravnborg break; 313c8dc68adSSam Ravnborg case KEY_RESIZE: 314c8dc68adSSam Ravnborg delwin(list); 315c8dc68adSSam Ravnborg delwin(dialog); 316c8dc68adSSam Ravnborg on_key_resize(); 317c8dc68adSSam Ravnborg goto do_resize; 3186f6046cfSSam Ravnborg } 3196f6046cfSSam Ravnborg 3206f6046cfSSam Ravnborg /* Now, update everything... */ 3216f6046cfSSam Ravnborg doupdate(); 3226f6046cfSSam Ravnborg } 3232982de69SSam Ravnborg delwin(list); 3246f6046cfSSam Ravnborg delwin(dialog); 325f3cbcdc9SSam Ravnborg return key; /* ESC pressed */ 3266f6046cfSSam Ravnborg } 327