00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dialog.h"
00025
00026 static int list_width, check_x, item_x, checkflag;
00027
00028
00029
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
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 }
00055
00056
00057
00058
00059 static void
00060 print_arrows (WINDOW * win, int choice, int item_no, int scroll,
00061 int y, int x, int height)
00062 {
00063 wmove(win, y, x);
00064
00065 if (scroll > 0) {
00066 wattrset (win, uarrow_attr);
00067 waddch (win, ACS_UARROW);
00068 waddstr (win, "(-)");
00069 }
00070 else {
00071 wattrset (win, menubox_attr);
00072 waddch (win, ACS_HLINE);
00073 waddch (win, ACS_HLINE);
00074 waddch (win, ACS_HLINE);
00075 waddch (win, ACS_HLINE);
00076 }
00077
00078 y = y + height + 1;
00079 wmove(win, y, x);
00080
00081 if ((height < item_no) && (scroll + choice < item_no - 1)) {
00082 wattrset (win, darrow_attr);
00083 waddch (win, ACS_DARROW);
00084 waddstr (win, "(+)");
00085 }
00086 else {
00087 wattrset (win, menubox_border_attr);
00088 waddch (win, ACS_HLINE);
00089 waddch (win, ACS_HLINE);
00090 waddch (win, ACS_HLINE);
00091 waddch (win, ACS_HLINE);
00092 }
00093 }
00094
00095
00096
00097
00098 static void
00099 print_buttons( WINDOW *dialog, int height, int width, int selected)
00100 {
00101 int x = width / 2 - 11;
00102 int y = height - 2;
00103
00104 print_button (dialog, "Select", y, x, selected == 0);
00105 print_button (dialog, " Help ", y, x + 14, selected == 1);
00106
00107 wmove(dialog, y, x+1 + 14*selected);
00108 wrefresh (dialog);
00109 }
00110
00111
00112
00113
00114
00115 int
00116 dialog_checklist (const char *title, const char *prompt, int height, int width,
00117 int list_height, int item_no, const char * const * items, int flag)
00118
00119 {
00120 int i, x, y, box_x, box_y;
00121 int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
00122 WINDOW *dialog, *list;
00123
00124 checkflag = flag;
00125
00126
00127 if ((status = malloc (sizeof (int) * item_no)) == NULL) {
00128 endwin ();
00129 fprintf (stderr,
00130 "\nCan't allocate memory in dialog_checklist().\n");
00131 exit (-1);
00132 }
00133
00134
00135 for (i = 0; i < item_no; i++) {
00136 status[i] = !strcasecmp (items[i * 3 + 2], "on");
00137 if (!choice && status[i])
00138 choice = i;
00139 }
00140
00141 max_choice = MIN (list_height, item_no);
00142
00143
00144 x = (COLS - width) / 2;
00145 y = (LINES - height) / 2;
00146
00147 draw_shadow (stdscr, y, x, height, width);
00148
00149 dialog = newwin (height, width, y, x);
00150 keypad (dialog, TRUE);
00151
00152 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
00153 wattrset (dialog, border_attr);
00154 mvwaddch (dialog, height-3, 0, ACS_LTEE);
00155 for (i = 0; i < width - 2; i++)
00156 waddch (dialog, ACS_HLINE);
00157 wattrset (dialog, dialog_attr);
00158 waddch (dialog, ACS_RTEE);
00159
00160 if (title != NULL && strlen(title) >= width-2 ) {
00161
00162 char * title2 = malloc(width-2+1);
00163 memcpy( title2, title, width-2 );
00164 title2[width-2] = '\0';
00165 title = title2;
00166 }
00167
00168 if (title != NULL) {
00169 wattrset (dialog, title_attr);
00170 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
00171 waddstr (dialog, (char *)title);
00172 waddch (dialog, ' ');
00173 }
00174
00175 wattrset (dialog, dialog_attr);
00176 print_autowrap (dialog, prompt, width - 2, 1, 3);
00177
00178 list_width = width - 6;
00179 box_y = height - list_height - 5;
00180 box_x = (width - list_width) / 2 - 1;
00181
00182
00183 list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
00184
00185 keypad (list, TRUE);
00186
00187
00188 draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
00189 menubox_border_attr, menubox_attr);
00190
00191
00192 check_x = 0;
00193 for (i = 0; i < item_no; i++)
00194 check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4);
00195
00196 check_x = (list_width - check_x) / 2;
00197 item_x = check_x + 4;
00198
00199 if (choice >= list_height) {
00200 scroll = choice - list_height + 1;
00201 choice -= scroll;
00202 }
00203
00204
00205 for (i = 0; i < max_choice; i++) {
00206 print_item (list, items[(scroll+i) * 3 + 1],
00207 status[i+scroll], i, i == choice);
00208 }
00209
00210 wnoutrefresh (list);
00211
00212 print_arrows(dialog, choice, item_no, scroll,
00213 box_y, box_x + check_x + 5, list_height);
00214
00215 print_buttons(dialog, height, width, 0);
00216
00217 while (key != ESC) {
00218 key = wgetch (dialog);
00219
00220 for (i = 0; i < max_choice; i++)
00221 if (toupper(key) == toupper(items[(scroll+i)*3+1][0]))
00222 break;
00223
00224
00225 if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
00226 key == '+' || key == '-' ) {
00227 if (key == KEY_UP || key == '-') {
00228 if (!choice) {
00229 if (!scroll)
00230 continue;
00231
00232 if (list_height > 1) {
00233
00234 print_item (list, items[scroll * 3 + 1],
00235 status[scroll], 0, FALSE);
00236 scrollok (list, TRUE);
00237 wscrl (list, -1);
00238 scrollok (list, FALSE);
00239 }
00240 scroll--;
00241 print_item (list, items[scroll * 3 + 1],
00242 status[scroll], 0, TRUE);
00243 wnoutrefresh (list);
00244
00245 print_arrows(dialog, choice, item_no, scroll,
00246 box_y, box_x + check_x + 5, list_height);
00247
00248 wrefresh (dialog);
00249
00250 continue;
00251 } else
00252 i = choice - 1;
00253 } else if (key == KEY_DOWN || key == '+') {
00254 if (choice == max_choice - 1) {
00255 if (scroll + choice >= item_no - 1)
00256 continue;
00257
00258 if (list_height > 1) {
00259
00260 print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
00261 status[scroll + max_choice - 1],
00262 max_choice - 1, FALSE);
00263 scrollok (list, TRUE);
00264 scroll (list);
00265 scrollok (list, FALSE);
00266 }
00267 scroll++;
00268 print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
00269 status[scroll + max_choice - 1],
00270 max_choice - 1, TRUE);
00271 wnoutrefresh (list);
00272
00273 print_arrows(dialog, choice, item_no, scroll,
00274 box_y, box_x + check_x + 5, list_height);
00275
00276 wrefresh (dialog);
00277
00278 continue;
00279 } else
00280 i = choice + 1;
00281 }
00282 if (i != choice) {
00283
00284 print_item (list, items[(scroll + choice) * 3 + 1],
00285 status[scroll + choice], choice, FALSE);
00286
00287 choice = i;
00288 print_item (list, items[(scroll + choice) * 3 + 1],
00289 status[scroll + choice], choice, TRUE);
00290 wnoutrefresh (list);
00291 wrefresh (dialog);
00292 }
00293 continue;
00294 }
00295 switch (key) {
00296 case 'H':
00297 case 'h':
00298 case '?':
00299 delwin (dialog);
00300 free (status);
00301 return 1;
00302 case TAB:
00303 case KEY_LEFT:
00304 case KEY_RIGHT:
00305 button = ((key == KEY_LEFT ? --button : ++button) < 0)
00306 ? 1 : (button > 1 ? 0 : button);
00307
00308 print_buttons(dialog, height, width, button);
00309 wrefresh (dialog);
00310 break;
00311 case 'S':
00312 case 's':
00313 case ' ':
00314 case '\n':
00315 if (!button) {
00316 if (flag == FLAG_CHECK) {
00317 status[scroll + choice] = !status[scroll + choice];
00318 wmove (list, choice, check_x);
00319 wattrset (list, check_selected_attr);
00320 wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
00321 } else {
00322 if (!status[scroll + choice]) {
00323 for (i = 0; i < item_no; i++)
00324 status[i] = 0;
00325 status[scroll + choice] = 1;
00326 for (i = 0; i < max_choice; i++)
00327 print_item (list, items[(scroll + i) * 3 + 1],
00328 status[scroll + i], i, i == choice);
00329 }
00330 }
00331 wnoutrefresh (list);
00332 wrefresh (dialog);
00333
00334 for (i = 0; i < item_no; i++) {
00335 if (status[i]) {
00336 if (flag == FLAG_CHECK) {
00337 fprintf (stderr, "\"%s\" ", items[i * 3]);
00338 } else {
00339 fprintf (stderr, "%s", items[i * 3]);
00340 }
00341
00342 }
00343 }
00344 }
00345 delwin (dialog);
00346 free (status);
00347 return button;
00348 case 'X':
00349 case 'x':
00350 key = ESC;
00351 case ESC:
00352 break;
00353 }
00354 }
00355
00356 delwin (dialog);
00357 free (status);
00358 return -1;
00359 }