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 }