kconfig/lxdialog/checklist.c
author "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
Mon Apr 16 15:25:36 2012 +0200 (2012-04-16)
changeset 2941 13e40098fffc
parent 943 1cca90ce0481
permissions -rw-r--r--
cc/gcc: update Linaro GCC revisions to 2012.04

Update Linaro GCC with the latest available revisions.

The 4.7 revision is also released, but the infrastructure is not yet ready for
it in CT-NG.

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