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 */ 31*2982de69SSam 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*2982de69SSam Ravnborg wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); 456f6046cfSSam Ravnborg 4698e5a157SSam Ravnborg wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); 47*2982de69SSam Ravnborg mvwaddch(win, choice, item_x, item_str()[0]); 4898e5a157SSam Ravnborg wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); 49*2982de69SSam Ravnborg waddstr(win, (char *)item_str() + 1); 506f6046cfSSam Ravnborg if (selected) { 516f6046cfSSam Ravnborg wmove(win, choice, check_x + 1); 526f6046cfSSam Ravnborg wrefresh(win); 536f6046cfSSam Ravnborg } 546f6046cfSSam Ravnborg } 556f6046cfSSam Ravnborg 566f6046cfSSam Ravnborg /* 576f6046cfSSam Ravnborg * Print the scroll indicators. 586f6046cfSSam Ravnborg */ 596f6046cfSSam Ravnborg static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, 606f6046cfSSam Ravnborg int y, int x, int height) 616f6046cfSSam Ravnborg { 626f6046cfSSam Ravnborg wmove(win, y, x); 636f6046cfSSam Ravnborg 646f6046cfSSam Ravnborg if (scroll > 0) { 6598e5a157SSam Ravnborg wattrset(win, dlg.uarrow.atr); 666f6046cfSSam Ravnborg waddch(win, ACS_UARROW); 676f6046cfSSam Ravnborg waddstr(win, "(-)"); 686f6046cfSSam Ravnborg } else { 6998e5a157SSam Ravnborg wattrset(win, dlg.menubox.atr); 706f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 716f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 726f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 736f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 746f6046cfSSam Ravnborg } 756f6046cfSSam Ravnborg 766f6046cfSSam Ravnborg y = y + height + 1; 776f6046cfSSam Ravnborg wmove(win, y, x); 786f6046cfSSam Ravnborg 796f6046cfSSam Ravnborg if ((height < item_no) && (scroll + choice < item_no - 1)) { 8098e5a157SSam Ravnborg wattrset(win, dlg.darrow.atr); 816f6046cfSSam Ravnborg waddch(win, ACS_DARROW); 826f6046cfSSam Ravnborg waddstr(win, "(+)"); 836f6046cfSSam Ravnborg } else { 8498e5a157SSam Ravnborg wattrset(win, dlg.menubox_border.atr); 856f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 866f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 876f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 886f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 896f6046cfSSam Ravnborg } 906f6046cfSSam Ravnborg } 916f6046cfSSam Ravnborg 926f6046cfSSam Ravnborg /* 936f6046cfSSam Ravnborg * Display the termination buttons 946f6046cfSSam Ravnborg */ 956f6046cfSSam Ravnborg static void print_buttons(WINDOW * dialog, int height, int width, int selected) 966f6046cfSSam Ravnborg { 976f6046cfSSam Ravnborg int x = width / 2 - 11; 986f6046cfSSam Ravnborg int y = height - 2; 996f6046cfSSam Ravnborg 1006f6046cfSSam Ravnborg print_button(dialog, "Select", y, x, selected == 0); 1016f6046cfSSam Ravnborg print_button(dialog, " Help ", y, x + 14, selected == 1); 1026f6046cfSSam Ravnborg 1036f6046cfSSam Ravnborg wmove(dialog, y, x + 1 + 14 * selected); 1046f6046cfSSam Ravnborg wrefresh(dialog); 1056f6046cfSSam Ravnborg } 1066f6046cfSSam Ravnborg 1076f6046cfSSam Ravnborg /* 1086f6046cfSSam Ravnborg * Display a dialog box with a list of options that can be turned on or off 10900213b17SPetr Baudis * in the style of radiolist (only one option turned on at a time). 1106f6046cfSSam Ravnborg */ 1116f6046cfSSam Ravnborg int dialog_checklist(const char *title, const char *prompt, int height, 112*2982de69SSam Ravnborg int width, int list_height) 1136f6046cfSSam Ravnborg { 1146f6046cfSSam Ravnborg int i, x, y, box_x, box_y; 115*2982de69SSam Ravnborg int key = 0, button = 0, choice = 0, scroll = 0, max_choice; 1166f6046cfSSam Ravnborg WINDOW *dialog, *list; 1176f6046cfSSam Ravnborg 118*2982de69SSam Ravnborg /* which item to highlight */ 119*2982de69SSam Ravnborg item_foreach() { 120*2982de69SSam Ravnborg if (item_is_tag('X')) 121*2982de69SSam Ravnborg choice = item_n(); 122*2982de69SSam Ravnborg if (item_is_selected()) { 123*2982de69SSam Ravnborg choice = item_n(); 124*2982de69SSam Ravnborg break; 125*2982de69SSam Ravnborg } 1266f6046cfSSam Ravnborg } 1276f6046cfSSam Ravnborg 128*2982de69SSam Ravnborg max_choice = MIN(list_height, item_count()); 1296f6046cfSSam Ravnborg 1306f6046cfSSam Ravnborg /* center dialog box on screen */ 1316f6046cfSSam Ravnborg x = (COLS - width) / 2; 1326f6046cfSSam Ravnborg y = (LINES - height) / 2; 1336f6046cfSSam Ravnborg 1346f6046cfSSam Ravnborg draw_shadow(stdscr, y, x, height, width); 1356f6046cfSSam Ravnborg 1366f6046cfSSam Ravnborg dialog = newwin(height, width, y, x); 1376f6046cfSSam Ravnborg keypad(dialog, TRUE); 1386f6046cfSSam Ravnborg 13998e5a157SSam Ravnborg draw_box(dialog, 0, 0, height, width, 14098e5a157SSam Ravnborg dlg.dialog.atr, dlg.border.atr); 14198e5a157SSam Ravnborg wattrset(dialog, dlg.border.atr); 1426f6046cfSSam Ravnborg mvwaddch(dialog, height - 3, 0, ACS_LTEE); 1436f6046cfSSam Ravnborg for (i = 0; i < width - 2; i++) 1446f6046cfSSam Ravnborg waddch(dialog, ACS_HLINE); 14598e5a157SSam Ravnborg wattrset(dialog, dlg.dialog.atr); 1466f6046cfSSam Ravnborg waddch(dialog, ACS_RTEE); 1476f6046cfSSam Ravnborg 1486f6046cfSSam Ravnborg print_title(dialog, title, width); 1496f6046cfSSam Ravnborg 15098e5a157SSam Ravnborg wattrset(dialog, dlg.dialog.atr); 1516f6046cfSSam Ravnborg print_autowrap(dialog, prompt, width - 2, 1, 3); 1526f6046cfSSam Ravnborg 1536f6046cfSSam Ravnborg list_width = width - 6; 1546f6046cfSSam Ravnborg box_y = height - list_height - 5; 1556f6046cfSSam Ravnborg box_x = (width - list_width) / 2 - 1; 1566f6046cfSSam Ravnborg 1576f6046cfSSam Ravnborg /* create new window for the list */ 1586f6046cfSSam Ravnborg list = subwin(dialog, list_height, list_width, y + box_y + 1, 1596f6046cfSSam Ravnborg x + box_x + 1); 1606f6046cfSSam Ravnborg 1616f6046cfSSam Ravnborg keypad(list, TRUE); 1626f6046cfSSam Ravnborg 1636f6046cfSSam Ravnborg /* draw a box around the list items */ 1646f6046cfSSam Ravnborg draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, 16598e5a157SSam Ravnborg dlg.menubox_border.atr, dlg.menubox.atr); 1666f6046cfSSam Ravnborg 1676f6046cfSSam Ravnborg /* Find length of longest item in order to center checklist */ 1686f6046cfSSam Ravnborg check_x = 0; 169*2982de69SSam Ravnborg item_foreach() 170*2982de69SSam Ravnborg check_x = MAX(check_x, strlen(item_str()) + 4); 1716f6046cfSSam Ravnborg 1726f6046cfSSam Ravnborg check_x = (list_width - check_x) / 2; 1736f6046cfSSam Ravnborg item_x = check_x + 4; 1746f6046cfSSam Ravnborg 1756f6046cfSSam Ravnborg if (choice >= list_height) { 1766f6046cfSSam Ravnborg scroll = choice - list_height + 1; 1776f6046cfSSam Ravnborg choice -= scroll; 1786f6046cfSSam Ravnborg } 1796f6046cfSSam Ravnborg 1806f6046cfSSam Ravnborg /* Print the list */ 1816f6046cfSSam Ravnborg for (i = 0; i < max_choice; i++) { 182*2982de69SSam Ravnborg item_set(scroll + i); 183*2982de69SSam Ravnborg print_item(list, i, i == choice); 1846f6046cfSSam Ravnborg } 1856f6046cfSSam Ravnborg 186*2982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), scroll, 1876f6046cfSSam Ravnborg box_y, box_x + check_x + 5, list_height); 1886f6046cfSSam Ravnborg 1896f6046cfSSam Ravnborg print_buttons(dialog, height, width, 0); 1906f6046cfSSam Ravnborg 1916f6046cfSSam Ravnborg wnoutrefresh(dialog); 192f043ca43SSamuel Thibault wnoutrefresh(list); 1936f6046cfSSam Ravnborg doupdate(); 1946f6046cfSSam Ravnborg 1956f6046cfSSam Ravnborg while (key != ESC) { 1966f6046cfSSam Ravnborg key = wgetch(dialog); 1976f6046cfSSam Ravnborg 198*2982de69SSam Ravnborg for (i = 0; i < max_choice; i++) { 199*2982de69SSam Ravnborg item_set(i + scroll); 200*2982de69SSam Ravnborg if (toupper(key) == toupper(item_str()[0])) 2016f6046cfSSam Ravnborg break; 202*2982de69SSam Ravnborg } 2036f6046cfSSam Ravnborg 2046f6046cfSSam Ravnborg if (i < max_choice || key == KEY_UP || key == KEY_DOWN || 2056f6046cfSSam Ravnborg key == '+' || key == '-') { 2066f6046cfSSam Ravnborg if (key == KEY_UP || key == '-') { 2076f6046cfSSam Ravnborg if (!choice) { 2086f6046cfSSam Ravnborg if (!scroll) 2096f6046cfSSam Ravnborg continue; 2106f6046cfSSam Ravnborg /* Scroll list down */ 2116f6046cfSSam Ravnborg if (list_height > 1) { 2126f6046cfSSam Ravnborg /* De-highlight current first item */ 213*2982de69SSam Ravnborg item_set(scroll); 214*2982de69SSam Ravnborg print_item(list, 0, FALSE); 2156f6046cfSSam Ravnborg scrollok(list, TRUE); 2166f6046cfSSam Ravnborg wscrl(list, -1); 2176f6046cfSSam Ravnborg scrollok(list, FALSE); 2186f6046cfSSam Ravnborg } 2196f6046cfSSam Ravnborg scroll--; 220*2982de69SSam Ravnborg item_set(scroll); 221*2982de69SSam Ravnborg print_item(list, 0, TRUE); 222*2982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), 2236f6046cfSSam Ravnborg scroll, box_y, box_x + check_x + 5, list_height); 2246f6046cfSSam Ravnborg 225f043ca43SSamuel Thibault wnoutrefresh(dialog); 226f043ca43SSamuel Thibault wrefresh(list); 2276f6046cfSSam Ravnborg 2286f6046cfSSam Ravnborg continue; /* wait for another key press */ 2296f6046cfSSam Ravnborg } else 2306f6046cfSSam Ravnborg i = choice - 1; 2316f6046cfSSam Ravnborg } else if (key == KEY_DOWN || key == '+') { 2326f6046cfSSam Ravnborg if (choice == max_choice - 1) { 233*2982de69SSam Ravnborg if (scroll + choice >= item_count() - 1) 2346f6046cfSSam Ravnborg continue; 2356f6046cfSSam Ravnborg /* Scroll list up */ 2366f6046cfSSam Ravnborg if (list_height > 1) { 2376f6046cfSSam Ravnborg /* De-highlight current last item before scrolling up */ 238*2982de69SSam Ravnborg item_set(scroll + max_choice - 1); 239*2982de69SSam Ravnborg print_item(list, 240*2982de69SSam Ravnborg max_choice - 1, 241*2982de69SSam Ravnborg FALSE); 2426f6046cfSSam Ravnborg scrollok(list, TRUE); 2436f6046cfSSam Ravnborg wscrl(list, 1); 2446f6046cfSSam Ravnborg scrollok(list, FALSE); 2456f6046cfSSam Ravnborg } 2466f6046cfSSam Ravnborg scroll++; 247*2982de69SSam Ravnborg item_set(scroll + max_choice - 1); 248*2982de69SSam Ravnborg print_item(list, max_choice - 1, TRUE); 2496f6046cfSSam Ravnborg 250*2982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), 2516f6046cfSSam Ravnborg scroll, box_y, box_x + check_x + 5, list_height); 2526f6046cfSSam Ravnborg 253f043ca43SSamuel Thibault wnoutrefresh(dialog); 254f043ca43SSamuel Thibault wrefresh(list); 2556f6046cfSSam Ravnborg 2566f6046cfSSam Ravnborg continue; /* wait for another key press */ 2576f6046cfSSam Ravnborg } else 2586f6046cfSSam Ravnborg i = choice + 1; 2596f6046cfSSam Ravnborg } 2606f6046cfSSam Ravnborg if (i != choice) { 2616f6046cfSSam Ravnborg /* De-highlight current item */ 262*2982de69SSam Ravnborg item_set(scroll + choice); 263*2982de69SSam Ravnborg print_item(list, choice, FALSE); 2646f6046cfSSam Ravnborg /* Highlight new item */ 2656f6046cfSSam Ravnborg choice = i; 266*2982de69SSam Ravnborg item_set(scroll + choice); 267*2982de69SSam Ravnborg print_item(list, choice, TRUE); 268f043ca43SSamuel Thibault wnoutrefresh(dialog); 269f043ca43SSamuel Thibault wrefresh(list); 2706f6046cfSSam Ravnborg } 2716f6046cfSSam Ravnborg continue; /* wait for another key press */ 2726f6046cfSSam Ravnborg } 2736f6046cfSSam Ravnborg switch (key) { 2746f6046cfSSam Ravnborg case 'H': 2756f6046cfSSam Ravnborg case 'h': 2766f6046cfSSam Ravnborg case '?': 277*2982de69SSam Ravnborg button = 1; 278*2982de69SSam Ravnborg /* fall-through */ 279*2982de69SSam Ravnborg case 'S': 280*2982de69SSam Ravnborg case 's': 281*2982de69SSam Ravnborg case ' ': 282*2982de69SSam Ravnborg case '\n': 283*2982de69SSam Ravnborg item_foreach() 284*2982de69SSam Ravnborg item_set_selected(0); 285*2982de69SSam Ravnborg item_set(scroll + choice); 286*2982de69SSam Ravnborg item_set_selected(1); 287*2982de69SSam Ravnborg delwin(list); 2886f6046cfSSam Ravnborg delwin(dialog); 289*2982de69SSam Ravnborg return button; 2906f6046cfSSam Ravnborg case TAB: 2916f6046cfSSam Ravnborg case KEY_LEFT: 2926f6046cfSSam Ravnborg case KEY_RIGHT: 2936f6046cfSSam Ravnborg button = ((key == KEY_LEFT ? --button : ++button) < 0) 2946f6046cfSSam Ravnborg ? 1 : (button > 1 ? 0 : button); 2956f6046cfSSam Ravnborg 2966f6046cfSSam Ravnborg print_buttons(dialog, height, width, button); 2976f6046cfSSam Ravnborg wrefresh(dialog); 2986f6046cfSSam Ravnborg break; 2996f6046cfSSam Ravnborg case 'X': 3006f6046cfSSam Ravnborg case 'x': 3016f6046cfSSam Ravnborg key = ESC; 3026f6046cfSSam Ravnborg case ESC: 3036f6046cfSSam Ravnborg break; 3046f6046cfSSam Ravnborg } 3056f6046cfSSam Ravnborg 3066f6046cfSSam Ravnborg /* Now, update everything... */ 3076f6046cfSSam Ravnborg doupdate(); 3086f6046cfSSam Ravnborg } 309*2982de69SSam Ravnborg delwin(list); 3106f6046cfSSam Ravnborg delwin(dialog); 311*2982de69SSam Ravnborg return 255; /* ESC pressed */ 3126f6046cfSSam Ravnborg } 313