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; 34e7401d83SLi Zefan char *list_item = malloc(list_width + 1); 35e7401d83SLi Zefan 36e7401d83SLi Zefan strncpy(list_item, item_str(), list_width - item_x); 37e7401d83SLi Zefan list_item[list_width - item_x] = '\0'; 386f6046cfSSam Ravnborg 396f6046cfSSam Ravnborg /* Clear 'residue' of last item */ 4098e5a157SSam Ravnborg wattrset(win, dlg.menubox.atr); 416f6046cfSSam Ravnborg wmove(win, choice, 0); 426f6046cfSSam Ravnborg for (i = 0; i < list_width; i++) 436f6046cfSSam Ravnborg waddch(win, ' '); 446f6046cfSSam Ravnborg 456f6046cfSSam Ravnborg wmove(win, choice, check_x); 4698e5a157SSam Ravnborg wattrset(win, selected ? dlg.check_selected.atr 4798e5a157SSam Ravnborg : dlg.check.atr); 48af6c1598SPeter Korsgaard if (!item_is_tag(':')) 492982de69SSam Ravnborg wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); 506f6046cfSSam Ravnborg 5198e5a157SSam Ravnborg wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); 52e7401d83SLi Zefan mvwaddch(win, choice, item_x, list_item[0]); 5398e5a157SSam Ravnborg wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); 54e7401d83SLi Zefan waddstr(win, list_item + 1); 556f6046cfSSam Ravnborg if (selected) { 566f6046cfSSam Ravnborg wmove(win, choice, check_x + 1); 576f6046cfSSam Ravnborg wrefresh(win); 586f6046cfSSam Ravnborg } 59e7401d83SLi Zefan free(list_item); 606f6046cfSSam Ravnborg } 616f6046cfSSam Ravnborg 626f6046cfSSam Ravnborg /* 636f6046cfSSam Ravnborg * Print the scroll indicators. 646f6046cfSSam Ravnborg */ 656f6046cfSSam Ravnborg static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, 666f6046cfSSam Ravnborg int y, int x, int height) 676f6046cfSSam Ravnborg { 686f6046cfSSam Ravnborg wmove(win, y, x); 696f6046cfSSam Ravnborg 706f6046cfSSam Ravnborg if (scroll > 0) { 7198e5a157SSam Ravnborg wattrset(win, dlg.uarrow.atr); 726f6046cfSSam Ravnborg waddch(win, ACS_UARROW); 736f6046cfSSam Ravnborg waddstr(win, "(-)"); 746f6046cfSSam Ravnborg } else { 7598e5a157SSam Ravnborg wattrset(win, dlg.menubox.atr); 766f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 776f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 786f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 796f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 806f6046cfSSam Ravnborg } 816f6046cfSSam Ravnborg 826f6046cfSSam Ravnborg y = y + height + 1; 836f6046cfSSam Ravnborg wmove(win, y, x); 846f6046cfSSam Ravnborg 856f6046cfSSam Ravnborg if ((height < item_no) && (scroll + choice < item_no - 1)) { 8698e5a157SSam Ravnborg wattrset(win, dlg.darrow.atr); 876f6046cfSSam Ravnborg waddch(win, ACS_DARROW); 886f6046cfSSam Ravnborg waddstr(win, "(+)"); 896f6046cfSSam Ravnborg } else { 9098e5a157SSam Ravnborg wattrset(win, dlg.menubox_border.atr); 916f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 926f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 936f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 946f6046cfSSam Ravnborg waddch(win, ACS_HLINE); 956f6046cfSSam Ravnborg } 966f6046cfSSam Ravnborg } 976f6046cfSSam Ravnborg 986f6046cfSSam Ravnborg /* 996f6046cfSSam Ravnborg * Display the termination buttons 1006f6046cfSSam Ravnborg */ 1016f6046cfSSam Ravnborg static void print_buttons(WINDOW * dialog, int height, int width, int selected) 1026f6046cfSSam Ravnborg { 1036f6046cfSSam Ravnborg int x = width / 2 - 11; 1046f6046cfSSam Ravnborg int y = height - 2; 1056f6046cfSSam Ravnborg 106*694c49a7SSam Ravnborg print_button(dialog, "Select", y, x, selected == 0); 107*694c49a7SSam Ravnborg print_button(dialog, " Help ", y, x + 14, selected == 1); 1086f6046cfSSam Ravnborg 1096f6046cfSSam Ravnborg wmove(dialog, y, x + 1 + 14 * selected); 1106f6046cfSSam Ravnborg wrefresh(dialog); 1116f6046cfSSam Ravnborg } 1126f6046cfSSam Ravnborg 1136f6046cfSSam Ravnborg /* 1146f6046cfSSam Ravnborg * Display a dialog box with a list of options that can be turned on or off 11500213b17SPetr Baudis * in the style of radiolist (only one option turned on at a time). 1166f6046cfSSam Ravnborg */ 1176f6046cfSSam Ravnborg int dialog_checklist(const char *title, const char *prompt, int height, 1182982de69SSam Ravnborg int width, int list_height) 1196f6046cfSSam Ravnborg { 1206f6046cfSSam Ravnborg int i, x, y, box_x, box_y; 1212982de69SSam Ravnborg int key = 0, button = 0, choice = 0, scroll = 0, max_choice; 1226f6046cfSSam Ravnborg WINDOW *dialog, *list; 1236f6046cfSSam Ravnborg 1242982de69SSam Ravnborg /* which item to highlight */ 1252982de69SSam Ravnborg item_foreach() { 1262982de69SSam Ravnborg if (item_is_tag('X')) 1272982de69SSam Ravnborg choice = item_n(); 1282982de69SSam Ravnborg if (item_is_selected()) { 1292982de69SSam Ravnborg choice = item_n(); 1302982de69SSam Ravnborg break; 1312982de69SSam Ravnborg } 1326f6046cfSSam Ravnborg } 1336f6046cfSSam Ravnborg 134c8dc68adSSam Ravnborg do_resize: 135851f6657SSedat Dilek if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN)) 136c8dc68adSSam Ravnborg return -ERRDISPLAYTOOSMALL; 137851f6657SSedat Dilek if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN)) 138c8dc68adSSam Ravnborg return -ERRDISPLAYTOOSMALL; 139c8dc68adSSam Ravnborg 1402982de69SSam Ravnborg max_choice = MIN(list_height, item_count()); 1416f6046cfSSam Ravnborg 1426f6046cfSSam Ravnborg /* center dialog box on screen */ 1434f2de3e1SDirk Gouders x = (getmaxx(stdscr) - width) / 2; 1444f2de3e1SDirk Gouders y = (getmaxy(stdscr) - height) / 2; 1456f6046cfSSam Ravnborg 1466f6046cfSSam Ravnborg draw_shadow(stdscr, y, x, height, width); 1476f6046cfSSam Ravnborg 1486f6046cfSSam Ravnborg dialog = newwin(height, width, y, x); 1496f6046cfSSam Ravnborg keypad(dialog, TRUE); 1506f6046cfSSam Ravnborg 15198e5a157SSam Ravnborg draw_box(dialog, 0, 0, height, width, 15298e5a157SSam Ravnborg dlg.dialog.atr, dlg.border.atr); 15398e5a157SSam Ravnborg wattrset(dialog, dlg.border.atr); 1546f6046cfSSam Ravnborg mvwaddch(dialog, height - 3, 0, ACS_LTEE); 1556f6046cfSSam Ravnborg for (i = 0; i < width - 2; i++) 1566f6046cfSSam Ravnborg waddch(dialog, ACS_HLINE); 15798e5a157SSam Ravnborg wattrset(dialog, dlg.dialog.atr); 1586f6046cfSSam Ravnborg waddch(dialog, ACS_RTEE); 1596f6046cfSSam Ravnborg 1606f6046cfSSam Ravnborg print_title(dialog, title, width); 1616f6046cfSSam Ravnborg 16298e5a157SSam Ravnborg wattrset(dialog, dlg.dialog.atr); 1636f6046cfSSam Ravnborg print_autowrap(dialog, prompt, width - 2, 1, 3); 1646f6046cfSSam Ravnborg 1656f6046cfSSam Ravnborg list_width = width - 6; 1666f6046cfSSam Ravnborg box_y = height - list_height - 5; 1676f6046cfSSam Ravnborg box_x = (width - list_width) / 2 - 1; 1686f6046cfSSam Ravnborg 1696f6046cfSSam Ravnborg /* create new window for the list */ 1706f6046cfSSam Ravnborg list = subwin(dialog, list_height, list_width, y + box_y + 1, 1716f6046cfSSam Ravnborg x + box_x + 1); 1726f6046cfSSam Ravnborg 1736f6046cfSSam Ravnborg keypad(list, TRUE); 1746f6046cfSSam Ravnborg 1756f6046cfSSam Ravnborg /* draw a box around the list items */ 1766f6046cfSSam Ravnborg draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, 17798e5a157SSam Ravnborg dlg.menubox_border.atr, dlg.menubox.atr); 1786f6046cfSSam Ravnborg 1796f6046cfSSam Ravnborg /* Find length of longest item in order to center checklist */ 1806f6046cfSSam Ravnborg check_x = 0; 1812982de69SSam Ravnborg item_foreach() 1822982de69SSam Ravnborg check_x = MAX(check_x, strlen(item_str()) + 4); 18342ef223cSLi Zefan check_x = MIN(check_x, list_width); 1846f6046cfSSam Ravnborg 1856f6046cfSSam Ravnborg check_x = (list_width - check_x) / 2; 1866f6046cfSSam Ravnborg item_x = check_x + 4; 1876f6046cfSSam Ravnborg 1886f6046cfSSam Ravnborg if (choice >= list_height) { 1896f6046cfSSam Ravnborg scroll = choice - list_height + 1; 1906f6046cfSSam Ravnborg choice -= scroll; 1916f6046cfSSam Ravnborg } 1926f6046cfSSam Ravnborg 1936f6046cfSSam Ravnborg /* Print the list */ 1946f6046cfSSam Ravnborg for (i = 0; i < max_choice; i++) { 1952982de69SSam Ravnborg item_set(scroll + i); 1962982de69SSam Ravnborg print_item(list, i, i == choice); 1976f6046cfSSam Ravnborg } 1986f6046cfSSam Ravnborg 1992982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), scroll, 2006f6046cfSSam Ravnborg box_y, box_x + check_x + 5, list_height); 2016f6046cfSSam Ravnborg 2026f6046cfSSam Ravnborg print_buttons(dialog, height, width, 0); 2036f6046cfSSam Ravnborg 2046f6046cfSSam Ravnborg wnoutrefresh(dialog); 205f043ca43SSamuel Thibault wnoutrefresh(list); 2066f6046cfSSam Ravnborg doupdate(); 2076f6046cfSSam Ravnborg 208f3cbcdc9SSam Ravnborg while (key != KEY_ESC) { 2096f6046cfSSam Ravnborg key = wgetch(dialog); 2106f6046cfSSam Ravnborg 2112982de69SSam Ravnborg for (i = 0; i < max_choice; i++) { 2122982de69SSam Ravnborg item_set(i + scroll); 2132982de69SSam Ravnborg if (toupper(key) == toupper(item_str()[0])) 2146f6046cfSSam Ravnborg break; 2152982de69SSam Ravnborg } 2166f6046cfSSam Ravnborg 2176f6046cfSSam Ravnborg if (i < max_choice || key == KEY_UP || key == KEY_DOWN || 2186f6046cfSSam Ravnborg key == '+' || key == '-') { 2196f6046cfSSam Ravnborg if (key == KEY_UP || key == '-') { 2206f6046cfSSam Ravnborg if (!choice) { 2216f6046cfSSam Ravnborg if (!scroll) 2226f6046cfSSam Ravnborg continue; 2236f6046cfSSam Ravnborg /* Scroll list down */ 2246f6046cfSSam Ravnborg if (list_height > 1) { 2256f6046cfSSam Ravnborg /* De-highlight current first item */ 2262982de69SSam Ravnborg item_set(scroll); 2272982de69SSam Ravnborg print_item(list, 0, FALSE); 2286f6046cfSSam Ravnborg scrollok(list, TRUE); 2296f6046cfSSam Ravnborg wscrl(list, -1); 2306f6046cfSSam Ravnborg scrollok(list, FALSE); 2316f6046cfSSam Ravnborg } 2326f6046cfSSam Ravnborg scroll--; 2332982de69SSam Ravnborg item_set(scroll); 2342982de69SSam Ravnborg print_item(list, 0, TRUE); 2352982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), 2366f6046cfSSam Ravnborg scroll, box_y, box_x + check_x + 5, list_height); 2376f6046cfSSam Ravnborg 238f043ca43SSamuel Thibault wnoutrefresh(dialog); 239f043ca43SSamuel Thibault wrefresh(list); 2406f6046cfSSam Ravnborg 2416f6046cfSSam Ravnborg continue; /* wait for another key press */ 2426f6046cfSSam Ravnborg } else 2436f6046cfSSam Ravnborg i = choice - 1; 2446f6046cfSSam Ravnborg } else if (key == KEY_DOWN || key == '+') { 2456f6046cfSSam Ravnborg if (choice == max_choice - 1) { 2462982de69SSam Ravnborg if (scroll + choice >= item_count() - 1) 2476f6046cfSSam Ravnborg continue; 2486f6046cfSSam Ravnborg /* Scroll list up */ 2496f6046cfSSam Ravnborg if (list_height > 1) { 2506f6046cfSSam Ravnborg /* De-highlight current last item before scrolling up */ 2512982de69SSam Ravnborg item_set(scroll + max_choice - 1); 2522982de69SSam Ravnborg print_item(list, 2532982de69SSam Ravnborg max_choice - 1, 2542982de69SSam Ravnborg FALSE); 2556f6046cfSSam Ravnborg scrollok(list, TRUE); 2566f6046cfSSam Ravnborg wscrl(list, 1); 2576f6046cfSSam Ravnborg scrollok(list, FALSE); 2586f6046cfSSam Ravnborg } 2596f6046cfSSam Ravnborg scroll++; 2602982de69SSam Ravnborg item_set(scroll + max_choice - 1); 2612982de69SSam Ravnborg print_item(list, max_choice - 1, TRUE); 2626f6046cfSSam Ravnborg 2632982de69SSam Ravnborg print_arrows(dialog, choice, item_count(), 2646f6046cfSSam Ravnborg scroll, box_y, box_x + check_x + 5, list_height); 2656f6046cfSSam Ravnborg 266f043ca43SSamuel Thibault wnoutrefresh(dialog); 267f043ca43SSamuel Thibault wrefresh(list); 2686f6046cfSSam Ravnborg 2696f6046cfSSam Ravnborg continue; /* wait for another key press */ 2706f6046cfSSam Ravnborg } else 2716f6046cfSSam Ravnborg i = choice + 1; 2726f6046cfSSam Ravnborg } 2736f6046cfSSam Ravnborg if (i != choice) { 2746f6046cfSSam Ravnborg /* De-highlight current item */ 2752982de69SSam Ravnborg item_set(scroll + choice); 2762982de69SSam Ravnborg print_item(list, choice, FALSE); 2776f6046cfSSam Ravnborg /* Highlight new item */ 2786f6046cfSSam Ravnborg choice = i; 2792982de69SSam Ravnborg item_set(scroll + choice); 2802982de69SSam Ravnborg print_item(list, choice, TRUE); 281f043ca43SSamuel Thibault wnoutrefresh(dialog); 282f043ca43SSamuel Thibault wrefresh(list); 2836f6046cfSSam Ravnborg } 2846f6046cfSSam Ravnborg continue; /* wait for another key press */ 2856f6046cfSSam Ravnborg } 2866f6046cfSSam Ravnborg switch (key) { 2876f6046cfSSam Ravnborg case 'H': 2886f6046cfSSam Ravnborg case 'h': 2896f6046cfSSam Ravnborg case '?': 2902982de69SSam Ravnborg button = 1; 2912982de69SSam Ravnborg /* fall-through */ 2922982de69SSam Ravnborg case 'S': 2932982de69SSam Ravnborg case 's': 2942982de69SSam Ravnborg case ' ': 2952982de69SSam Ravnborg case '\n': 2962982de69SSam Ravnborg item_foreach() 2972982de69SSam Ravnborg item_set_selected(0); 2982982de69SSam Ravnborg item_set(scroll + choice); 2992982de69SSam Ravnborg item_set_selected(1); 3002982de69SSam Ravnborg delwin(list); 3016f6046cfSSam Ravnborg delwin(dialog); 3022982de69SSam Ravnborg return button; 3036f6046cfSSam Ravnborg case TAB: 3046f6046cfSSam Ravnborg case KEY_LEFT: 3056f6046cfSSam Ravnborg case KEY_RIGHT: 3066f6046cfSSam Ravnborg button = ((key == KEY_LEFT ? --button : ++button) < 0) 3076f6046cfSSam Ravnborg ? 1 : (button > 1 ? 0 : button); 3086f6046cfSSam Ravnborg 3096f6046cfSSam Ravnborg print_buttons(dialog, height, width, button); 3106f6046cfSSam Ravnborg wrefresh(dialog); 3116f6046cfSSam Ravnborg break; 3126f6046cfSSam Ravnborg case 'X': 3136f6046cfSSam Ravnborg case 'x': 314f3cbcdc9SSam Ravnborg key = KEY_ESC; 315f3cbcdc9SSam Ravnborg break; 316f3cbcdc9SSam Ravnborg case KEY_ESC: 317f3cbcdc9SSam Ravnborg key = on_key_esc(dialog); 3186f6046cfSSam Ravnborg break; 319c8dc68adSSam Ravnborg case KEY_RESIZE: 320c8dc68adSSam Ravnborg delwin(list); 321c8dc68adSSam Ravnborg delwin(dialog); 322c8dc68adSSam Ravnborg on_key_resize(); 323c8dc68adSSam Ravnborg goto do_resize; 3246f6046cfSSam Ravnborg } 3256f6046cfSSam Ravnborg 3266f6046cfSSam Ravnborg /* Now, update everything... */ 3276f6046cfSSam Ravnborg doupdate(); 3286f6046cfSSam Ravnborg } 3292982de69SSam Ravnborg delwin(list); 3306f6046cfSSam Ravnborg delwin(dialog); 331f3cbcdc9SSam Ravnborg return key; /* ESC pressed */ 3326f6046cfSSam Ravnborg } 333