2018-12-18 15:13:35 +03:00
// SPDX-License-Identifier: GPL-2.0+
2005-04-17 02:20:36 +04:00
/*
* checklist . c - - implements the checklist box
*
* ORIGINAL AUTHOR : Savio Lam ( lam836 @ cs . cuhk . hk )
* Stuart Herbert - S . Herbert @ sheffield . ac . uk : radiolist extension
* Alessandro Rubini - rubini @ ipvvis . unipv . it : merged the two
* MODIFIED FOR LINUX KERNEL CONFIG BY : William Roadcap ( roadcap @ cfw . com )
*/
# include "dialog.h"
2005-12-22 06:44:04 +03:00
static int list_width , check_x , item_x ;
2005-04-17 02:20:36 +04:00
/*
* Print list item
*/
2006-07-28 00:10:27 +04:00
static void print_item ( WINDOW * win , int choice , int selected )
2005-04-17 02:20:36 +04:00
{
2005-11-19 21:13:34 +03:00
int i ;
2010-06-03 11:24:57 +04:00
char * list_item = malloc ( list_width + 1 ) ;
strncpy ( list_item , item_str ( ) , list_width - item_x ) ;
list_item [ list_width - item_x ] = ' \0 ' ;
2005-11-19 21:13:34 +03:00
/* Clear 'residue' of last item */
2006-07-24 23:40:46 +04:00
wattrset ( win , dlg . menubox . atr ) ;
2005-11-19 21:13:34 +03:00
wmove ( win , choice , 0 ) ;
for ( i = 0 ; i < list_width ; i + + )
waddch ( win , ' ' ) ;
wmove ( win , choice , check_x ) ;
2006-07-24 23:40:46 +04:00
wattrset ( win , selected ? dlg . check_selected . atr
: dlg . check . atr ) ;
2009-02-16 00:15:16 +03:00
if ( ! item_is_tag ( ' : ' ) )
wprintw ( win , " (%c) " , item_is_tag ( ' X ' ) ? ' X ' : ' ' ) ;
2005-11-19 21:13:34 +03:00
2006-07-24 23:40:46 +04:00
wattrset ( win , selected ? dlg . tag_selected . atr : dlg . tag . atr ) ;
2010-06-03 11:24:57 +04:00
mvwaddch ( win , choice , item_x , list_item [ 0 ] ) ;
2006-07-24 23:40:46 +04:00
wattrset ( win , selected ? dlg . item_selected . atr : dlg . item . atr ) ;
2010-06-03 11:24:57 +04:00
waddstr ( win , list_item + 1 ) ;
2005-11-19 21:13:34 +03:00
if ( selected ) {
wmove ( win , choice , check_x + 1 ) ;
wrefresh ( win ) ;
}
2010-06-03 11:24:57 +04:00
free ( list_item ) ;
2005-04-17 02:20:36 +04:00
}
/*
* Print the scroll indicators .
*/
2005-11-19 23:56:20 +03:00
static void print_arrows ( WINDOW * win , int choice , int item_no , int scroll ,
2005-11-19 21:13:34 +03:00
int y , int x , int height )
2005-04-17 02:20:36 +04:00
{
2005-11-19 21:13:34 +03:00
wmove ( win , y , x ) ;
if ( scroll > 0 ) {
2006-07-24 23:40:46 +04:00
wattrset ( win , dlg . uarrow . atr ) ;
2005-11-19 21:13:34 +03:00
waddch ( win , ACS_UARROW ) ;
waddstr ( win , " (-) " ) ;
} else {
2006-07-24 23:40:46 +04:00
wattrset ( win , dlg . menubox . atr ) ;
2005-11-19 21:13:34 +03:00
waddch ( win , ACS_HLINE ) ;
waddch ( win , ACS_HLINE ) ;
waddch ( win , ACS_HLINE ) ;
waddch ( win , ACS_HLINE ) ;
}
y = y + height + 1 ;
wmove ( win , y , x ) ;
if ( ( height < item_no ) & & ( scroll + choice < item_no - 1 ) ) {
2006-07-24 23:40:46 +04:00
wattrset ( win , dlg . darrow . atr ) ;
2005-11-19 21:13:34 +03:00
waddch ( win , ACS_DARROW ) ;
waddstr ( win , " (+) " ) ;
} else {
2006-07-24 23:40:46 +04:00
wattrset ( win , dlg . menubox_border . atr ) ;
2005-11-19 21:13:34 +03:00
waddch ( win , ACS_HLINE ) ;
waddch ( win , ACS_HLINE ) ;
waddch ( win , ACS_HLINE ) ;
waddch ( win , ACS_HLINE ) ;
}
2005-04-17 02:20:36 +04:00
}
/*
* Display the termination buttons
*/
2005-11-19 21:13:34 +03:00
static void print_buttons ( WINDOW * dialog , int height , int width , int selected )
2005-04-17 02:20:36 +04:00
{
2005-11-19 21:13:34 +03:00
int x = width / 2 - 11 ;
int y = height - 2 ;
2005-04-17 02:20:36 +04:00
2018-05-22 22:36:12 +03:00
print_button ( dialog , " Select " , y , x , selected = = 0 ) ;
print_button ( dialog , " Help " , y , x + 14 , selected = = 1 ) ;
2005-04-17 02:20:36 +04:00
2005-11-19 21:13:34 +03:00
wmove ( dialog , y , x + 1 + 14 * selected ) ;
wrefresh ( dialog ) ;
2005-04-17 02:20:36 +04:00
}
/*
* Display a dialog box with a list of options that can be turned on or off
2005-12-22 06:44:04 +03:00
* in the style of radiolist ( only one option turned on at a time ) .
2005-04-17 02:20:36 +04:00
*/
2005-11-19 23:56:20 +03:00
int dialog_checklist ( const char * title , const char * prompt , int height ,
2006-07-28 00:10:27 +04:00
int width , int list_height )
2005-04-17 02:20:36 +04:00
{
2005-11-19 21:13:34 +03:00
int i , x , y , box_x , box_y ;
2006-07-28 00:10:27 +04:00
int key = 0 , button = 0 , choice = 0 , scroll = 0 , max_choice ;
2005-11-19 21:13:34 +03:00
WINDOW * dialog , * list ;
2006-07-28 00:10:27 +04:00
/* which item to highlight */
item_foreach ( ) {
if ( item_is_tag ( ' X ' ) )
choice = item_n ( ) ;
if ( item_is_selected ( ) ) {
choice = item_n ( ) ;
break ;
}
2005-11-19 21:13:34 +03:00
}
2006-07-30 00:48:57 +04:00
do_resize :
2013-06-15 13:07:35 +04:00
if ( getmaxy ( stdscr ) < ( height + CHECKLIST_HEIGTH_MIN ) )
2006-07-30 00:48:57 +04:00
return - ERRDISPLAYTOOSMALL ;
2013-06-15 13:07:35 +04:00
if ( getmaxx ( stdscr ) < ( width + CHECKLIST_WIDTH_MIN ) )
2006-07-30 00:48:57 +04:00
return - ERRDISPLAYTOOSMALL ;
2006-07-28 00:10:27 +04:00
max_choice = MIN ( list_height , item_count ( ) ) ;
2005-11-19 21:13:34 +03:00
/* center dialog box on screen */
2013-05-12 14:30:49 +04:00
x = ( getmaxx ( stdscr ) - width ) / 2 ;
y = ( getmaxy ( stdscr ) - height ) / 2 ;
2005-11-19 21:13:34 +03:00
draw_shadow ( stdscr , y , x , height , width ) ;
dialog = newwin ( height , width , y , x ) ;
keypad ( dialog , TRUE ) ;
2006-07-24 23:40:46 +04:00
draw_box ( dialog , 0 , 0 , height , width ,
dlg . dialog . atr , dlg . border . atr ) ;
wattrset ( dialog , dlg . border . atr ) ;
2005-11-19 21:13:34 +03:00
mvwaddch ( dialog , height - 3 , 0 , ACS_LTEE ) ;
for ( i = 0 ; i < width - 2 ; i + + )
waddch ( dialog , ACS_HLINE ) ;
2006-07-24 23:40:46 +04:00
wattrset ( dialog , dlg . dialog . atr ) ;
2005-11-19 21:13:34 +03:00
waddch ( dialog , ACS_RTEE ) ;
2005-11-20 01:38:06 +03:00
print_title ( dialog , title , width ) ;
2005-11-19 21:13:34 +03:00
2006-07-24 23:40:46 +04:00
wattrset ( dialog , dlg . dialog . atr ) ;
2005-11-19 21:13:34 +03:00
print_autowrap ( dialog , prompt , width - 2 , 1 , 3 ) ;
list_width = width - 6 ;
box_y = height - list_height - 5 ;
box_x = ( width - list_width ) / 2 - 1 ;
/* create new window for the list */
2005-11-19 23:56:20 +03:00
list = subwin ( dialog , list_height , list_width , y + box_y + 1 ,
2014-06-10 14:08:13 +04:00
x + box_x + 1 ) ;
2005-11-19 21:13:34 +03:00
keypad ( list , TRUE ) ;
/* draw a box around the list items */
draw_box ( dialog , box_y , box_x , list_height + 2 , list_width + 2 ,
2014-06-10 14:08:13 +04:00
dlg . menubox_border . atr , dlg . menubox . atr ) ;
2005-11-19 21:13:34 +03:00
/* Find length of longest item in order to center checklist */
check_x = 0 ;
2006-07-28 00:10:27 +04:00
item_foreach ( )
check_x = MAX ( check_x , strlen ( item_str ( ) ) + 4 ) ;
2010-06-03 11:24:39 +04:00
check_x = MIN ( check_x , list_width ) ;
2005-11-19 21:13:34 +03:00
check_x = ( list_width - check_x ) / 2 ;
item_x = check_x + 4 ;
if ( choice > = list_height ) {
scroll = choice - list_height + 1 ;
choice - = scroll ;
}
/* Print the list */
for ( i = 0 ; i < max_choice ; i + + ) {
2006-07-28 00:10:27 +04:00
item_set ( scroll + i ) ;
print_item ( list , i , i = = choice ) ;
2005-04-17 02:20:36 +04:00
}
2006-07-28 00:10:27 +04:00
print_arrows ( dialog , choice , item_count ( ) , scroll ,
2005-11-19 21:13:34 +03:00
box_y , box_x + check_x + 5 , list_height ) ;
print_buttons ( dialog , height , width , 0 ) ;
wnoutrefresh ( dialog ) ;
2006-04-12 04:21:25 +04:00
wnoutrefresh ( list ) ;
2005-11-19 21:13:34 +03:00
doupdate ( ) ;
2006-07-29 01:57:48 +04:00
while ( key ! = KEY_ESC ) {
2005-11-19 21:13:34 +03:00
key = wgetch ( dialog ) ;
2006-07-28 00:10:27 +04:00
for ( i = 0 ; i < max_choice ; i + + ) {
item_set ( i + scroll ) ;
if ( toupper ( key ) = = toupper ( item_str ( ) [ 0 ] ) )
2005-11-19 21:13:34 +03:00
break ;
2006-07-28 00:10:27 +04:00
}
2005-11-19 21:13:34 +03:00
if ( i < max_choice | | key = = KEY_UP | | key = = KEY_DOWN | |
key = = ' + ' | | key = = ' - ' ) {
if ( key = = KEY_UP | | key = = ' - ' ) {
if ( ! choice ) {
if ( ! scroll )
continue ;
/* Scroll list down */
if ( list_height > 1 ) {
/* De-highlight current first item */
2006-07-28 00:10:27 +04:00
item_set ( scroll ) ;
print_item ( list , 0 , FALSE ) ;
2005-11-19 21:13:34 +03:00
scrollok ( list , TRUE ) ;
wscrl ( list , - 1 ) ;
scrollok ( list , FALSE ) ;
}
scroll - - ;
2006-07-28 00:10:27 +04:00
item_set ( scroll ) ;
print_item ( list , 0 , TRUE ) ;
print_arrows ( dialog , choice , item_count ( ) ,
2005-11-19 23:56:20 +03:00
scroll , box_y , box_x + check_x + 5 , list_height ) ;
2005-11-19 21:13:34 +03:00
2006-04-12 04:21:25 +04:00
wnoutrefresh ( dialog ) ;
wrefresh ( list ) ;
2005-11-19 21:13:34 +03:00
continue ; /* wait for another key press */
} else
i = choice - 1 ;
} else if ( key = = KEY_DOWN | | key = = ' + ' ) {
if ( choice = = max_choice - 1 ) {
2006-07-28 00:10:27 +04:00
if ( scroll + choice > = item_count ( ) - 1 )
2005-11-19 21:13:34 +03:00
continue ;
/* Scroll list up */
if ( list_height > 1 ) {
/* De-highlight current last item before scrolling up */
2006-07-28 00:10:27 +04:00
item_set ( scroll + max_choice - 1 ) ;
print_item ( list ,
max_choice - 1 ,
FALSE ) ;
2005-11-19 21:13:34 +03:00
scrollok ( list , TRUE ) ;
wscrl ( list , 1 ) ;
scrollok ( list , FALSE ) ;
}
scroll + + ;
2006-07-28 00:10:27 +04:00
item_set ( scroll + max_choice - 1 ) ;
print_item ( list , max_choice - 1 , TRUE ) ;
2005-11-19 21:13:34 +03:00
2006-07-28 00:10:27 +04:00
print_arrows ( dialog , choice , item_count ( ) ,
2005-11-19 23:56:20 +03:00
scroll , box_y , box_x + check_x + 5 , list_height ) ;
2005-11-19 21:13:34 +03:00
2006-04-12 04:21:25 +04:00
wnoutrefresh ( dialog ) ;
wrefresh ( list ) ;
2005-11-19 21:13:34 +03:00
continue ; /* wait for another key press */
} else
i = choice + 1 ;
}
if ( i ! = choice ) {
/* De-highlight current item */
2006-07-28 00:10:27 +04:00
item_set ( scroll + choice ) ;
print_item ( list , choice , FALSE ) ;
2005-11-19 21:13:34 +03:00
/* Highlight new item */
choice = i ;
2006-07-28 00:10:27 +04:00
item_set ( scroll + choice ) ;
print_item ( list , choice , TRUE ) ;
2006-04-12 04:21:25 +04:00
wnoutrefresh ( dialog ) ;
wrefresh ( list ) ;
2005-11-19 21:13:34 +03:00
}
continue ; /* wait for another key press */
}
switch ( key ) {
case ' H ' :
case ' h ' :
case ' ? ' :
2006-07-28 00:10:27 +04:00
button = 1 ;
/* fall-through */
case ' S ' :
case ' s ' :
case ' ' :
case ' \n ' :
item_foreach ( )
item_set_selected ( 0 ) ;
item_set ( scroll + choice ) ;
item_set_selected ( 1 ) ;
delwin ( list ) ;
2005-11-19 21:13:34 +03:00
delwin ( dialog ) ;
2006-07-28 00:10:27 +04:00
return button ;
2005-11-19 21:13:34 +03:00
case TAB :
case KEY_LEFT :
case KEY_RIGHT :
button = ( ( key = = KEY_LEFT ? - - button : + + button ) < 0 )
? 1 : ( button > 1 ? 0 : button ) ;
print_buttons ( dialog , height , width , button ) ;
wrefresh ( dialog ) ;
break ;
case ' X ' :
case ' x ' :
2006-07-29 01:57:48 +04:00
key = KEY_ESC ;
break ;
case KEY_ESC :
key = on_key_esc ( dialog ) ;
2005-11-19 21:13:34 +03:00
break ;
2006-07-30 00:48:57 +04:00
case KEY_RESIZE :
delwin ( list ) ;
delwin ( dialog ) ;
on_key_resize ( ) ;
goto do_resize ;
2005-11-19 21:13:34 +03:00
}
/* Now, update everything... */
doupdate ( ) ;
}
2006-07-28 00:10:27 +04:00
delwin ( list ) ;
2005-11-19 21:13:34 +03:00
delwin ( dialog ) ;
2006-07-29 01:57:48 +04:00
return key ; /* ESC pressed */
2005-04-17 02:20:36 +04:00
}