source: debwrt/trunk/config/mconf/lxdialog/checklist.c @ 1

Last change on this file since 1 was 1, checked in by amain, 13 years ago

Initial import of the build environment for DebWrt

File size: 8.6 KB
Line 
1/*
2 *  checklist.c -- implements the checklist box
3 *
4 *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
6 *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
7 *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
8 *
9 *  This program is free software; you can redistribute it and/or
10 *  modify it under the terms of the GNU General Public License
11 *  as published by the Free Software Foundation; either version 2
12 *  of the License, or (at your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "dialog.h"
25
26static int list_width, check_x, item_x;
27
28/*
29 * Print list item
30 */
31static void print_item(WINDOW * win, const char *item, int status, int choice,
32                       int selected)
33{
34        int i;
35
36        /* Clear 'residue' of last item */
37        wattrset(win, menubox_attr);
38        wmove(win, choice, 0);
39        for (i = 0; i < list_width; i++)
40                waddch(win, ' ');
41
42        wmove(win, choice, check_x);
43        wattrset(win, selected ? check_selected_attr : check_attr);
44        wprintw(win, "(%c)", status ? 'X' : ' ');
45
46        wattrset(win, selected ? tag_selected_attr : tag_attr);
47        mvwaddch(win, choice, item_x, item[0]);
48        wattrset(win, selected ? item_selected_attr : item_attr);
49        waddstr(win, (char *)item + 1);
50        if (selected) {
51                wmove(win, choice, check_x + 1);
52                wrefresh(win);
53        }
54}
55
56/*
57 * Print the scroll indicators.
58 */
59static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
60             int y, int x, int height)
61{
62        wmove(win, y, x);
63
64        if (scroll > 0) {
65                wattrset(win, uarrow_attr);
66                waddch(win, ACS_UARROW);
67                waddstr(win, "(-)");
68        } else {
69                wattrset(win, menubox_attr);
70                waddch(win, ACS_HLINE);
71                waddch(win, ACS_HLINE);
72                waddch(win, ACS_HLINE);
73                waddch(win, ACS_HLINE);
74        }
75
76        y = y + height + 1;
77        wmove(win, y, x);
78
79        if ((height < item_no) && (scroll + choice < item_no - 1)) {
80                wattrset(win, darrow_attr);
81                waddch(win, ACS_DARROW);
82                waddstr(win, "(+)");
83        } else {
84                wattrset(win, menubox_border_attr);
85                waddch(win, ACS_HLINE);
86                waddch(win, ACS_HLINE);
87                waddch(win, ACS_HLINE);
88                waddch(win, ACS_HLINE);
89        }
90}
91
92/*
93 *  Display the termination buttons
94 */
95static void print_buttons(WINDOW * dialog, int height, int width, int selected)
96{
97        int x = width / 2 - 11;
98        int y = height - 2;
99
100        print_button(dialog, "Select", y, x, selected == 0);
101        print_button(dialog, " Help ", y, x + 14, selected == 1);
102
103        wmove(dialog, y, x + 1 + 14 * selected);
104        wrefresh(dialog);
105}
106
107/*
108 * Display a dialog box with a list of options that can be turned on or off
109 * in the style of radiolist (only one option turned on at a time).
110 */
111int dialog_checklist(const char *title, const char *prompt, int height,
112                     int width, int list_height, int item_no,
113                     const char *const *items)
114{
115        int i, x, y, box_x, box_y;
116        int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
117        WINDOW *dialog, *list;
118
119        /* Allocate space for storing item on/off status */
120        if ((status = malloc(sizeof(int) * item_no)) == NULL) {
121                endwin();
122                fprintf(stderr,
123                        "\nCan't allocate memory in dialog_checklist().\n");
124                exit(-1);
125        }
126
127        /* Initializes status */
128        for (i = 0; i < item_no; i++) {
129                status[i] = !strcasecmp(items[i * 3 + 2], "on");
130                if ((!choice && status[i])
131                    || !strcasecmp(items[i * 3 + 2], "selected"))
132                        choice = i + 1;
133        }
134        if (choice)
135                choice--;
136
137        max_choice = MIN(list_height, item_no);
138
139        /* center dialog box on screen */
140        x = (COLS - width) / 2;
141        y = (LINES - height) / 2;
142
143        draw_shadow(stdscr, y, x, height, width);
144
145        dialog = newwin(height, width, y, x);
146        keypad(dialog, TRUE);
147
148        draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
149        wattrset(dialog, border_attr);
150        mvwaddch(dialog, height - 3, 0, ACS_LTEE);
151        for (i = 0; i < width - 2; i++)
152                waddch(dialog, ACS_HLINE);
153        wattrset(dialog, dialog_attr);
154        waddch(dialog, ACS_RTEE);
155
156        print_title(dialog, title, width);
157
158        wattrset(dialog, dialog_attr);
159        print_autowrap(dialog, prompt, width - 2, 1, 3);
160
161        list_width = width - 6;
162        box_y = height - list_height - 5;
163        box_x = (width - list_width) / 2 - 1;
164
165        /* create new window for the list */
166        list = subwin(dialog, list_height, list_width, y + box_y + 1,
167                      x + box_x + 1);
168
169        keypad(list, TRUE);
170
171        /* draw a box around the list items */
172        draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
173                 menubox_border_attr, menubox_attr);
174
175        /* Find length of longest item in order to center checklist */
176        check_x = 0;
177        for (i = 0; i < item_no; i++)
178                check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
179
180        check_x = (list_width - check_x) / 2;
181        item_x = check_x + 4;
182
183        if (choice >= list_height) {
184                scroll = choice - list_height + 1;
185                choice -= scroll;
186        }
187
188        /* Print the list */
189        for (i = 0; i < max_choice; i++) {
190                print_item(list, items[(scroll + i) * 3 + 1],
191                           status[i + scroll], i, i == choice);
192        }
193
194        print_arrows(dialog, choice, item_no, scroll,
195                     box_y, box_x + check_x + 5, list_height);
196
197        print_buttons(dialog, height, width, 0);
198
199        wnoutrefresh(list);
200        wnoutrefresh(dialog);
201        doupdate();
202
203        while (key != ESC) {
204                key = wgetch(dialog);
205
206                for (i = 0; i < max_choice; i++)
207                        if (toupper(key) ==
208                            toupper(items[(scroll + i) * 3 + 1][0]))
209                                break;
210
211                if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
212                    key == '+' || key == '-') {
213                        if (key == KEY_UP || key == '-') {
214                                if (!choice) {
215                                        if (!scroll)
216                                                continue;
217                                        /* Scroll list down */
218                                        if (list_height > 1) {
219                                                /* De-highlight current first item */
220                                                print_item(list, items[scroll * 3 + 1],
221                                                           status[scroll], 0, FALSE);
222                                                scrollok(list, TRUE);
223                                                wscrl(list, -1);
224                                                scrollok(list, FALSE);
225                                        }
226                                        scroll--;
227                                        print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
228                                        wnoutrefresh(list);
229
230                                        print_arrows(dialog, choice, item_no,
231                                                     scroll, box_y, box_x + check_x + 5, list_height);
232
233                                        wrefresh(dialog);
234
235                                        continue;       /* wait for another key press */
236                                } else
237                                        i = choice - 1;
238                        } else if (key == KEY_DOWN || key == '+') {
239                                if (choice == max_choice - 1) {
240                                        if (scroll + choice >= item_no - 1)
241                                                continue;
242                                        /* Scroll list up */
243                                        if (list_height > 1) {
244                                                /* De-highlight current last item before scrolling up */
245                                                print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
246                                                           status[scroll + max_choice - 1],
247                                                           max_choice - 1, FALSE);
248                                                scrollok(list, TRUE);
249                                                wscrl(list, 1);
250                                                scrollok(list, FALSE);
251                                        }
252                                        scroll++;
253                                        print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
254                                                   status[scroll + max_choice - 1], max_choice - 1, TRUE);
255                                        wnoutrefresh(list);
256
257                                        print_arrows(dialog, choice, item_no,
258                                                     scroll, box_y, box_x + check_x + 5, list_height);
259
260                                        wrefresh(dialog);
261
262                                        continue;       /* wait for another key press */
263                                } else
264                                        i = choice + 1;
265                        }
266                        if (i != choice) {
267                                /* De-highlight current item */
268                                print_item(list, items[(scroll + choice) * 3 + 1],
269                                           status[scroll + choice], choice, FALSE);
270                                /* Highlight new item */
271                                choice = i;
272                                print_item(list, items[(scroll + choice) * 3 + 1],
273                                           status[scroll + choice], choice, TRUE);
274                                wnoutrefresh(list);
275                                wrefresh(dialog);
276                        }
277                        continue;       /* wait for another key press */
278                }
279                switch (key) {
280                case 'H':
281                case 'h':
282                case '?':
283                        fprintf(stderr, "%s", items[(scroll + choice) * 3]);
284                        delwin(dialog);
285                        free(status);
286                        return 1;
287                case TAB:
288                case KEY_LEFT:
289                case KEY_RIGHT:
290                        button = ((key == KEY_LEFT ? --button : ++button) < 0)
291                            ? 1 : (button > 1 ? 0 : button);
292
293                        print_buttons(dialog, height, width, button);
294                        wrefresh(dialog);
295                        break;
296                case 'S':
297                case 's':
298                case ' ':
299                case '\n':
300                        if (!button) {
301                                if (!status[scroll + choice]) {
302                                        for (i = 0; i < item_no; i++)
303                                                status[i] = 0;
304                                        status[scroll + choice] = 1;
305                                        for (i = 0; i < max_choice; i++)
306                                                print_item(list, items[(scroll + i) * 3 + 1],
307                                                           status[scroll + i], i, i == choice);
308                                }
309                                wnoutrefresh(list);
310                                wrefresh(dialog);
311
312                                for (i = 0; i < item_no; i++)
313                                        if (status[i])
314                                                fprintf(stderr, "%s", items[i * 3]);
315                        } else
316                                fprintf(stderr, "%s", items[(scroll + choice) * 3]);
317                        delwin(dialog);
318                        free(status);
319                        return button;
320                case 'X':
321                case 'x':
322                        key = ESC;
323                case ESC:
324                        break;
325                }
326
327                /* Now, update everything... */
328                doupdate();
329        }
330
331        delwin(dialog);
332        free(status);
333        return -1;              /* ESC pressed */
334}
Note: See TracBrowser for help on using the repository browser.