base/config/kconfig/lxdialog/checklist.c

Go to the documentation of this file.
00001 /* 00002 * checklist.c -- implements the checklist box 00003 * 00004 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 00005 * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension 00006 * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two 00007 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License 00011 * as published by the Free Software Foundation; either version 2 00012 * of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00022 */ 00023 00024 #include "dialog.h" 00025 00026 static int list_width, check_x, item_x, checkflag; 00027 00028 /* 00029 * Print list item 00030 */ 00031 static void 00032 print_item (WINDOW * win, const char *item, int status, 00033 int choice, int selected) 00034 { 00035 int i; 00036 00037 /* Clear 'residue' of last item */ 00038 wattrset (win, menubox_attr); 00039 wmove (win, choice, 0); 00040 for (i = 0; i < list_width; i++) 00041 waddch (win, ' '); 00042 00043 wmove (win, choice, check_x); 00044 wattrset (win, selected ? check_selected_attr : check_attr); 00045 if (checkflag == FLAG_CHECK) 00046 wprintw (win, "[%c]", status ? 'X' : ' '); 00047 else 00048 wprintw (win, "(%c)", status ? 'X' : ' '); 00049 00050 wattrset (win, selected ? tag_selected_attr : tag_attr); 00051 mvwaddch(win, choice, item_x, item[0]); 00052 wattrset (win, selected ? item_selected_attr : item_attr); 00053 waddstr (win, (char *)item+1); 00054 if (selected) { 00055 wmove (win, choice, check_x+1); 00056 wrefresh (win); 00057 } 00058 } 00059 00060 /* 00061 * Print the scroll indicators. 00062 */ 00063 static void 00064 print_arrows (WINDOW * win, int choice, int item_no, int scroll, 00065 int y, int x, int height) 00066 { 00067 wmove(win, y, x); 00068 00069 if (scroll > 0) { 00070 wattrset (win, uarrow_attr); 00071 waddch (win, ACS_UARROW); 00072 waddstr (win, "(-)"); 00073 } 00074 else { 00075 wattrset (win, menubox_attr); 00076 waddch (win, ACS_HLINE); 00077 waddch (win, ACS_HLINE); 00078 waddch (win, ACS_HLINE); 00079 waddch (win, ACS_HLINE); 00080 } 00081 00082 y = y + height + 1; 00083 wmove(win, y, x); 00084 00085 if ((height < item_no) && (scroll + choice < item_no - 1)) { 00086 wattrset (win, darrow_attr); 00087 waddch (win, ACS_DARROW); 00088 waddstr (win, "(+)"); 00089 } 00090 else { 00091 wattrset (win, menubox_border_attr); 00092 waddch (win, ACS_HLINE); 00093 waddch (win, ACS_HLINE); 00094 waddch (win, ACS_HLINE); 00095 waddch (win, ACS_HLINE); 00096 } 00097 } 00098 00099 /* 00100 * Display the termination buttons 00101 */ 00102 static void 00103 print_buttons( WINDOW *dialog, int height, int width, int selected) 00104 { 00105 int x = width / 2 - 11; 00106 int y = height - 2; 00107 00108 print_button (dialog, "Select", y, x, selected == 0); 00109 print_button (dialog, " Help ", y, x + 14, selected == 1); 00110 00111 wmove(dialog, y, x+1 + 14*selected); 00112 wrefresh (dialog); 00113 } 00114 00115 /* 00116 * Display a dialog box with a list of options that can be turned on or off 00117 * The `flag' parameter is used to select between radiolist and checklist. 00118 */ 00119 int 00120 dialog_checklist (const char *title, const char *prompt, int height, int width, 00121 int list_height, int item_no, const char * const * items, int flag) 00122 00123 { 00124 int i, x, y, box_x, box_y; 00125 int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; 00126 WINDOW *dialog, *list; 00127 00128 checkflag = flag; 00129 00130 /* Allocate space for storing item on/off status */ 00131 if ((status = malloc (sizeof (int) * item_no)) == NULL) { 00132 endwin (); 00133 fprintf (stderr, 00134 "\nCan't allocate memory in dialog_checklist().\n"); 00135 exit (-1); 00136 } 00137 00138 /* Initializes status */ 00139 for (i = 0; i < item_no; i++) { 00140 status[i] = !strcasecmp (items[i * 3 + 2], "on"); 00141 if (!choice && status[i]) 00142 choice = i; 00143 } 00144 00145 max_choice = MIN (list_height, item_no); 00146 00147 /* center dialog box on screen */ 00148 x = (COLS - width) / 2; 00149 y = (LINES - height) / 2; 00150 00151 draw_shadow (stdscr, y, x, height, width); 00152 00153 dialog = newwin (height, width, y, x); 00154 keypad (dialog, TRUE); 00155 00156 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); 00157 wattrset (dialog, border_attr); 00158 mvwaddch (dialog, height-3, 0, ACS_LTEE); 00159 for (i = 0; i < width - 2; i++) 00160 waddch (dialog, ACS_HLINE); 00161 wattrset (dialog, dialog_attr); 00162 waddch (dialog, ACS_RTEE); 00163 00164 if (title != NULL && strlen(title) >= width-2 ) { 00165 /* truncate long title -- mec */ 00166 char * title2 = malloc(width-2+1); 00167 memcpy( title2, title, width-2 ); 00168 title2[width-2] = '\0'; 00169 title = title2; 00170 } 00171 00172 if (title != NULL) { 00173 wattrset (dialog, title_attr); 00174 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); 00175 waddstr (dialog, (char *)title); 00176 waddch (dialog, ' '); 00177 } 00178 00179 wattrset (dialog, dialog_attr); 00180 print_autowrap (dialog, prompt, width - 2, 1, 3); 00181 00182 list_width = width - 6; 00183 box_y = height - list_height - 5; 00184 box_x = (width - list_width) / 2 - 1; 00185 00186 /* create new window for the list */ 00187 list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1); 00188 00189 keypad (list, TRUE); 00190 00191 /* draw a box around the list items */ 00192 draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2, 00193 menubox_border_attr, menubox_attr); 00194 00195 /* Find length of longest item in order to center checklist */ 00196 check_x = 0; 00197 for (i = 0; i < item_no; i++) 00198 check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4); 00199 00200 check_x = (list_width - check_x) / 2; 00201 item_x = check_x + 4; 00202 00203 if (choice >= list_height) { 00204 scroll = choice - list_height + 1; 00205 choice -= scroll; 00206 } 00207 00208 /* Print the list */ 00209 for (i = 0; i < max_choice; i++) { 00210 print_item (list, items[(scroll+i) * 3 + 1], 00211 status[i+scroll], i, i == choice); 00212 } 00213 00214 print_arrows(dialog, choice, item_no, scroll, 00215 box_y, box_x + check_x + 5, list_height); 00216 00217 print_buttons(dialog, height, width, 0); 00218 00219 wnoutrefresh (list); 00220 wnoutrefresh (dialog); 00221 doupdate (); 00222 00223 while (key != ESC) { 00224 key = wgetch (dialog); 00225 00226 for (i = 0; i < max_choice; i++) 00227 if (toupper(key) == toupper(items[(scroll+i)*3+1][0])) 00228 break; 00229 00230 00231 if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || 00232 key == '+' || key == '-' ) { 00233 if (key == KEY_UP || key == '-') { 00234 if (!choice) { 00235 if (!scroll) 00236 continue; 00237 /* Scroll list down */ 00238 if (list_height > 1) { 00239 /* De-highlight current first item */ 00240 print_item (list, items[scroll * 3 + 1], 00241 status[scroll], 0, FALSE); 00242 scrollok (list, TRUE); 00243 wscrl (list, -1); 00244 scrollok (list, FALSE); 00245 } 00246 scroll--; 00247 print_item (list, items[scroll * 3 + 1], 00248 status[scroll], 0, TRUE); 00249 wnoutrefresh (list); 00250 00251 print_arrows(dialog, choice, item_no, scroll, 00252 box_y, box_x + check_x + 5, list_height); 00253 00254 wrefresh (dialog); 00255 00256 continue; /* wait for another key press */ 00257 } else 00258 i = choice - 1; 00259 } else if (key == KEY_DOWN || key == '+') { 00260 if (choice == max_choice - 1) { 00261 if (scroll + choice >= item_no - 1) 00262 continue; 00263 /* Scroll list up */ 00264 if (list_height > 1) { 00265 /* De-highlight current last item before scrolling up */ 00266 print_item (list, items[(scroll + max_choice - 1) * 3 + 1], 00267 status[scroll + max_choice - 1], 00268 max_choice - 1, FALSE); 00269 scrollok (list, TRUE); 00270 scroll (list); 00271 scrollok (list, FALSE); 00272 } 00273 scroll++; 00274 print_item (list, items[(scroll + max_choice - 1) * 3 + 1], 00275 status[scroll + max_choice - 1], 00276 max_choice - 1, TRUE); 00277 wnoutrefresh (list); 00278 00279 print_arrows(dialog, choice, item_no, scroll, 00280 box_y, box_x + check_x + 5, list_height); 00281 00282 wrefresh (dialog); 00283 00284 continue; /* wait for another key press */ 00285 } else 00286 i = choice + 1; 00287 } 00288 if (i != choice) { 00289 /* De-highlight current item */ 00290 print_item (list, items[(scroll + choice) * 3 + 1], 00291 status[scroll + choice], choice, FALSE); 00292 /* Highlight new item */ 00293 choice = i; 00294 print_item (list, items[(scroll + choice) * 3 + 1], 00295 status[scroll + choice], choice, TRUE); 00296 wnoutrefresh (list); 00297 wrefresh (dialog); 00298 } 00299 continue; /* wait for another key press */ 00300 } 00301 switch (key) { 00302 case 'H': 00303 case 'h': 00304 case '?': 00305 delwin (dialog); 00306 free (status); 00307 return 1; 00308 case TAB: 00309 case KEY_LEFT: 00310 case KEY_RIGHT: 00311 button = ((key == KEY_LEFT ? --button : ++button) < 0) 00312 ? 1 : (button > 1 ? 0 : button); 00313 00314 print_buttons(dialog, height, width, button); 00315 wrefresh (dialog); 00316 break; 00317 case 'S': 00318 case 's': 00319 case ' ': 00320 case '\n': 00321 if (!button) { 00322 if (flag == FLAG_CHECK) { 00323 status[scroll + choice] = !status[scroll + choice]; 00324 wmove (list, choice, check_x); 00325 wattrset (list, check_selected_attr); 00326 wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' '); 00327 } else { 00328 if (!status[scroll + choice]) { 00329 for (i = 0; i < item_no; i++) 00330 status[i] = 0; 00331 status[scroll + choice] = 1; 00332 for (i = 0; i < max_choice; i++) 00333 print_item (list, items[(scroll + i) * 3 + 1], 00334 status[scroll + i], i, i == choice); 00335 } 00336 } 00337 wnoutrefresh (list); 00338 wrefresh (dialog); 00339 00340 for (i = 0; i < item_no; i++) { 00341 if (status[i]) { 00342 if (flag == FLAG_CHECK) { 00343 fprintf (stderr, "\"%s\" ", items[i * 3]); 00344 } else { 00345 fprintf (stderr, "%s", items[i * 3]); 00346 } 00347 00348 } 00349 } 00350 } 00351 delwin (dialog); 00352 free (status); 00353 return button; 00354 case 'X': 00355 case 'x': 00356 key = ESC; 00357 case ESC: 00358 break; 00359 } 00360 00361 /* Now, update everything... */ 00362 doupdate (); 00363 } 00364 00365 00366 delwin (dialog); 00367 free (status); 00368 return -1; /* ESC pressed */ 00369 }

Generated on Thu Nov 20 11:49:48 2008 for RTAI API by doxygen 1.3.8