diff options
Diffstat (limited to 'src/LYOptions.c')
-rw-r--r-- | src/LYOptions.c | 1896 |
1 files changed, 1640 insertions, 256 deletions
diff --git a/src/LYOptions.c b/src/LYOptions.c index b26ee2ad..774279d2 100644 --- a/src/LYOptions.c +++ b/src/LYOptions.c @@ -15,9 +15,25 @@ #include "LYrcFile.h" #include "HTAlert.h" #include "LYBookmark.h" +#include "GridText.h" #include "LYLeaks.h" +#ifndef BOXVERT +#ifdef ALT_CHAR_SET +#define BOXVERT 0 /* use alt char set for popup window vertical borders */ +#else +#define BOXVERT '*' /* character for popup window vertical borders */ +#endif +#endif +#ifndef BOXHORI +#ifdef ALT_CHAR_SET +#define BOXHORI 0 /* use alt char set for popup window horizontal borders */ +#else +#define BOXHORI '*' /* character for popup window horizontal borders */ +#endif +#endif + #define FREE(x) if (x) {free(x); x = NULL;} #ifdef VMS @@ -30,8 +46,18 @@ BOOLEAN term_options; PRIVATE void terminate_options PARAMS((int sig)); -PRIVATE int boolean_choice PARAMS((int status, int line, - int column, char **choices)); +PRIVATE int boolean_choice PARAMS(( + int status, + int line, + int column, + char ** choices)); +PRIVATE int popup_choice PARAMS(( + int cur_choice, + int line, + int column, + char ** choices, + int i_length, + int disabled)); #define MAXCHOICES 10 @@ -41,7 +67,7 @@ PRIVATE void option_statusline ARGS1( /* * Make sure we have a pointer to a string. */ - if (text == 0) + if (text == NULL) return; /* @@ -64,7 +90,9 @@ PUBLIC void options NOARGS int itmp; #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */ int response, ch; - /* if the user changes the display I need memory to put it in */ + /* + * If the user changes the display we need memory to put it in. + */ char display_option[256]; #ifndef VMS static char putenv_command[142]; @@ -72,6 +100,7 @@ PUBLIC void options NOARGS char *choices[MAXCHOICES]; int CurrentCharSet = current_char_set; BOOLEAN CurrentRawMode = LYRawMode; + BOOLEAN AddValueAccepted = FALSE; #ifdef DIRED_SUPPORT #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS @@ -132,7 +161,7 @@ draw_options: addstr((LYMultiBookmarks ? (LYMBMAdvanced ? "ADVANCED" : "STANDARD") - : "OFF")); + : "OFF ")); move(L_HOME, B_BOOK); if (LYMultiBookmarks) { addstr("review/edit B)ookmarks files"); @@ -143,10 +172,10 @@ draw_options: move(L_FTPSTYPE, 5); addstr("F)TP sort criteria : "); - addstr((HTfileSortMethod==FILE_BY_NAME ? "By Filename" : - (HTfileSortMethod==FILE_BY_SIZE ? "By Size" : - (HTfileSortMethod==FILE_BY_TYPE ? "By Type" : - "By Date")))); + addstr((HTfileSortMethod == FILE_BY_NAME ? "By Filename" : + (HTfileSortMethod == FILE_BY_SIZE ? "By Size " : + (HTfileSortMethod == FILE_BY_TYPE ? "By Type " : + "By Date ")))); move(L_MAIL_ADDRESS, 5); addstr("P)ersonal mail address : "); @@ -155,7 +184,7 @@ draw_options: move(L_SSEARCH, 5); addstr("S)earching type : "); - addstr(case_sensitive ? "CASE SENSITIVE" : "CASE INSENSITIVE"); + addstr(case_sensitive ? "CASE SENSITIVE " : "CASE INSENSITIVE"); move(L_CHARSET, 5); addstr("display (C)haracter set : "); @@ -163,7 +192,7 @@ draw_options: move(L_RAWMODE, 5); addstr("Raw 8-bit or CJK m(O)de : "); - addstr(LYRawMode ? "ON" : "OFF"); + addstr(LYRawMode ? "ON " : "OFF"); move(L_LANGUAGE, 5); addstr("preferred document lan(G)uage: "); @@ -175,24 +204,31 @@ draw_options: move(L_BOOL_A, B_VIKEYS); addstr("V)I keys: "); - addstr(vi_keys ? "ON" : "OFF"); + addstr(vi_keys ? "ON " : "OFF"); move(L_BOOL_A, B_EMACSKEYS); addstr("e(M)acs keys: "); - addstr(emacs_keys ? "ON" : "OFF"); + addstr(emacs_keys ? "ON " : "OFF"); move(L_BOOL_A, B_SHOW_DOTFILES); addstr("sho(W) dot files: "); - addstr((!no_dotfiles && show_dotfiles) ? "ON" : "OFF"); + addstr((!no_dotfiles && show_dotfiles) ? "ON " : "OFF"); - move(L_SELECT_POPUPS, 5); + move(L_BOOL_B, B_SELECT_POPUPS); addstr("popups for selec(T) fields : "); - addstr(LYSelectPopups ? "ON" : "OFF"); + addstr(LYSelectPopups ? "ON " : "OFF"); + + move(L_BOOL_B, B_SHOW_CURSOR); + addstr("show cursor (@) : "); + addstr(LYShowCursor ? "ON " : "OFF"); - move(L_KEYPAD, 5); - addstr("K)eypad mode : "); - addstr((keypad_mode == NUMBERS_AS_ARROWS) ? "Numbers act as arrows" : - "Links are numbered"); + move(L_KEYPAD, 5); + addstr("K)eypad mode : "); + addstr((keypad_mode == NUMBERS_AS_ARROWS) ? + "Numbers act as arrows " : + ((keypad_mode == LINKS_ARE_NUMBERED) ? + "Links are numbered " : + "Links and form fields are numbered")); move(L_LINEED, 5); addstr("li(N)e edit style : "); @@ -201,16 +237,16 @@ draw_options: #ifdef DIRED_SUPPORT move(L_DIRED, 5); addstr("l(I)st directory style : "); - addstr((dir_list_style == FILES_FIRST) ? "Files first " : - ((dir_list_style == MIXED_STYLE) ? "Mixed style " : - "Directories first ")); + addstr((dir_list_style == FILES_FIRST) ? "Files first " : + ((dir_list_style == MIXED_STYLE) ? "Mixed style " : + "Directories first")); #endif /* DIRED_SUPPORT */ move(L_USER_MODE, 5); addstr("U)ser mode : "); - addstr( (user_mode == NOVICE_MODE) ? "Novice" : + addstr( (user_mode == NOVICE_MODE) ? "Novice " : ((user_mode == INTERMEDIATE_MODE) ? "Intermediate" : - "Advanced")); + "Advanced ")); move(L_USER_AGENT, 5); addstr("user (A)gent : "); @@ -220,12 +256,12 @@ draw_options: move(L_EXEC, 5); addstr("local e(X)ecution links : "); #ifndef NEVER_ALLOW_REMOTE_EXEC - addstr( local_exec ? "ALWAYS ON" : + addstr( local_exec ? "ALWAYS ON " : (local_exec_on_local_files ? "FOR LOCAL FILES ONLY" : - "ALWAYS OFF")); + "ALWAYS OFF ")); #else addstr(local_exec_on_local_files ? "FOR LOCAL FILES ONLY" : - "ALWAYS OFF"); + "ALWAYS OFF "); #endif /* NEVER_ALLOW_REMOTE_EXEC */ #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */ @@ -252,121 +288,124 @@ draw_options: addstr(TO_RETURN_SEGMENT); while (TOUPPER(response) != 'R' && - !LYisNonAlnumKeyname(response, LYK_PREV_DOC) && + !LYisNonAlnumKeyname(response, LYK_PREV_DOC) && response != '>' && !term_options && response != 7 && response != 3) { + if (AddValueAccepted == TRUE) { + option_statusline(VALUE_ACCEPTED); + AddValueAccepted = FALSE; + } + move((LYlines - 2), 0); + lynx_start_prompt_color (); + addstr(COMMAND_PROMPT); + lynx_stop_prompt_color (); - move(LYlines-2, 0); - lynx_start_prompt_color (); - addstr(COMMAND_PROMPT); - lynx_stop_prompt_color (); - - refresh(); - response = LYgetch(); - if (term_options || response == 7 || response == 3) - response = 'R'; - if (LYisNonAlnumKeyname(response, LYK_REFRESH)) { - clearok(curscr, TRUE); - goto draw_options; - } - switch (response) { - case 'e': /* change the editor */ - case 'E': - if (no_editor) { - option_statusline(EDIT_DISABLED); - } else if (system_editor ) { - option_statusline(EDITOR_LOCKED); - } else { - if (editor && *editor) - strcpy(display_option, editor); - else { /* clear the NONE */ - move(L_EDITOR, COL_OPTION_VALUES); - addstr(" "); - *display_option = '\0'; - } - option_statusline(ACCEPT_DATA); - move(L_EDITOR, COL_OPTION_VALUES); - standout(); - ch = LYgetstr(display_option, VISIBLE, - sizeof(display_option), NORECALL); - standend(); - move(L_EDITOR, COL_OPTION_VALUES); - if (term_options || ch == -1) { - addstr((editor && *editor) ? - editor : "NONE"); - } else if (*display_option == '\0') { - FREE(editor); - addstr("NONE"); - } else { - StrAllocCopy(editor, display_option); - addstr(display_option); - } - clrtoeol(); - option_statusline(VALUE_ACCEPTED); - } - response = ' '; - break; + refresh(); + response = LYgetch(); + if (term_options || response == 7 || response == 3) + response = 'R'; + if (LYisNonAlnumKeyname(response, LYK_REFRESH)) { + clearok(curscr, TRUE); + goto draw_options; + } + switch (response) { + case 'e': /* Change the editor. */ + case 'E': + if (no_editor) { + option_statusline(EDIT_DISABLED); + } else if (system_editor ) { + option_statusline(EDITOR_LOCKED); + } else { + if (editor && *editor) + strcpy(display_option, editor); + else { /* clear the NONE */ + move(L_EDITOR, COL_OPTION_VALUES); + addstr(" "); + *display_option = '\0'; + } + option_statusline(ACCEPT_DATA); + move(L_EDITOR, COL_OPTION_VALUES); + standout(); + ch = LYgetstr(display_option, VISIBLE, + sizeof(display_option), NORECALL); + standend(); + move(L_EDITOR, COL_OPTION_VALUES); + if (term_options || ch == -1) { + addstr((editor && *editor) ? + editor : "NONE"); + } else if (*display_option == '\0') { + FREE(editor); + addstr("NONE"); + } else { + StrAllocCopy(editor, display_option); + addstr(display_option); + } + clrtoeol(); + option_statusline(VALUE_ACCEPTED); + } + response = ' '; + break; - case 'd': /* change the display */ - case 'D': - if (display && *display) { - strcpy(display_option, display); - } else { /* clear the NONE */ - move(L_DISPLAY, COL_OPTION_VALUES); - addstr(" "); - *display_option = '\0'; - } - option_statusline(ACCEPT_DATA); - move(L_DISPLAY, COL_OPTION_VALUES); - standout(); - ch = LYgetstr(display_option, VISIBLE, - sizeof(display_option), NORECALL); - standend(); - move(L_DISPLAY, COL_OPTION_VALUES); - if ((term_options || ch == -1) || - (display != NULL && + case 'd': /* Change the display. */ + case 'D': + if (display && *display) { + strcpy(display_option, display); + } else { /* clear the NONE */ + move(L_DISPLAY, COL_OPTION_VALUES); + addstr(" "); + *display_option = '\0'; + } + option_statusline(ACCEPT_DATA); + move(L_DISPLAY, COL_OPTION_VALUES); + standout(); + ch = LYgetstr(display_option, VISIBLE, + sizeof(display_option), NORECALL); + standend(); + move(L_DISPLAY, COL_OPTION_VALUES); + if ((term_options || ch == -1) || + (display != NULL && #ifdef VMS - 0 == strcasecomp(display, display_option))) + !strcasecomp(display, display_option))) #else - 0 == strcmp(display, display_option))) + !strcmp(display, display_option))) #endif /* VMS */ - { - /* - * Cancelled, or a non-NULL display string - * wasn't changed. - FM - */ - addstr((display && *display) ? display : "NONE"); - clrtoeol(); - option_statusline(VALUE_ACCEPTED); - response = ' '; - break; - } else if (*display_option == '\0') { - if ((display == NULL) || - (display != NULL && *display == '\0')) { - /* - * NULL or zero-length display string - * wasn't changed. - FM - */ - addstr("NONE"); - clrtoeol(); - option_statusline(VALUE_ACCEPTED); - response = ' '; - break; - } - } + { + /* + * Cancelled, or a non-NULL display string + * wasn't changed. - FM + */ + addstr((display && *display) ? display : "NONE"); + clrtoeol(); + option_statusline(VALUE_ACCEPTED); + response = ' '; + break; + } else if (*display_option == '\0') { + if ((display == NULL) || + (display != NULL && *display == '\0')) { /* - * Set the new DISPLAY variable. - FM + * NULL or zero-length display string + * wasn't changed. - FM */ + addstr("NONE"); + clrtoeol(); + option_statusline(VALUE_ACCEPTED); + response = ' '; + break; + } + } + /* + * Set the new DISPLAY variable. - FM + */ #ifdef VMS - { - int i; - for (i = 0; display_option[i]; i++) - display_option[i] = TOUPPER(display_option[i]); - Define_VMSLogical(DISPLAY, display_option); - } + { + int i; + for (i = 0; display_option[i]; i++) + display_option[i] = TOUPPER(display_option[i]); + Define_VMSLogical(DISPLAY, display_option); + } #else - sprintf(putenv_command, "DISPLAY=%s", display_option); - putenv(putenv_command); + sprintf(putenv_command, "DISPLAY=%s", display_option); + putenv(putenv_command); #endif /* VMS */ if ((display = getenv(DISPLAY)) != NULL && *display == '\0') { @@ -396,7 +435,7 @@ draw_options: response = ' '; break; - case 'l': + case 'l': /* Change multibookmarks option. */ case 'L': if (LYMBMBlocked) { option_statusline(MULTIBOOKMARKS_DISALLOWED); @@ -410,20 +449,38 @@ draw_options: choices[2] = NULL; StrAllocCopy(choices[2],"ADVANCED"); choices[3] = NULL; - LYMultiBookmarks = boolean_choice(LYMultiBookmarks * - (1 + LYMBMAdvanced), + if (!LYSelectPopups) { + LYMultiBookmarks = boolean_choice((LYMultiBookmarks * + (1 + LYMBMAdvanced)), L_HOME, C_MULTI, choices); - FREE(choices[0]); - FREE(choices[1]); - FREE(choices[2]); + } else { + LYMultiBookmarks = popup_choice((LYMultiBookmarks * + (1 + LYMBMAdvanced)), + L_HOME, (C_MULTI - 1), + choices, + 3, FALSE); + } if (LYMultiBookmarks == 2) { LYMultiBookmarks = TRUE; LYMBMAdvanced = TRUE; } else { LYMBMAdvanced = FALSE; } - +#if defined(VMS) || defined(USE_SLANG) + if (LYSelectPopups) { + move(L_HOME, C_MULTI); + clrtoeol(); + addstr(choices[(LYMultiBookmarks * (1 + LYMBMAdvanced))]); + } +#endif /* VMS || USE_SLANG */ + FREE(choices[0]); + FREE(choices[1]); + FREE(choices[2]); +#if !defined(VMS) && !defined(USE_SLANG) + if (!LYSelectPopups) +#endif /* !VMS && !USE_SLANG */ + { move(L_HOME, B_BOOK); clrtoeol(); if (LYMultiBookmarks) { @@ -433,13 +490,27 @@ draw_options: addstr((bookmark_page && *bookmark_page) ? bookmark_page : "NONE"); } + } response = ' '; + if (LYSelectPopups) { +#if !defined(VMS) || defined(USE_SLANG) + if (term_options) { + term_options = FALSE; + } else { + AddValueAccepted = TRUE; + } + goto draw_options; +#else + term_options = FALSE; +#endif /* !VMS || USE_SLANG */ + } break; - case 'b': /* change the bookmark page location */ + case 'b': /* Change the bookmark page location. */ case 'B': - /* anonymous users should not be allowed to - * change the bookmark page + /* + * Anonymous users should not be allowed to + * change the bookmark page. */ if (!no_bookmark) { if (LYMultiBookmarks) { @@ -447,9 +518,9 @@ draw_options: signal(SIGINT, terminate_options); goto draw_options; } - if (bookmark_page && *bookmark_page) + if (bookmark_page && *bookmark_page) { strcpy(display_option, bookmark_page); - else { /* clear the NONE */ + } else { /* clear the NONE */ move(L_HOME, C_DEFAULT); clrtoeol(); *display_option = '\0'; @@ -487,9 +558,11 @@ draw_options: response = ' '; break; - case 'f': - case 'F': - /* copy strings into choice array */ + case 'f': /* Change ftp directory sorting. */ + case 'F': /* (also local for non-DIRED) */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0],"By Filename"); choices[1] = NULL; @@ -499,19 +572,45 @@ draw_options: choices[3] = NULL; StrAllocCopy(choices[3],"By Date "); choices[4] = NULL; + if (!LYSelectPopups) { HTfileSortMethod = boolean_choice(HTfileSortMethod, - L_FTPSTYPE, -1, choices); + L_FTPSTYPE, -1, + choices); + } else { + HTfileSortMethod = popup_choice(HTfileSortMethod, + L_FTPSTYPE, -1, + choices, + 4, FALSE); +#if defined(VMS) || defined(USE_SLANG) + move(L_FTPSTYPE, COL_OPTION_VALUES); + clrtoeol(); + addstr(choices[HTfileSortMethod]); +#endif /* VMS || USE_SLANG */ + } FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); + FREE(choices[3]); response = ' '; + if (LYSelectPopups) { +#if !defined(VMS) || defined(USE_SLANG) + if (term_options) { + term_options = FALSE; + } else { + AddValueAccepted = TRUE; + } + goto draw_options; +#else + term_options = FALSE; +#endif /* !VMS || USE_SLANG */ + } break; - case 'p': /* change personal mail address for From headers */ + case 'p': /* Change personal mail address for From headers. */ case 'P': - if (personal_mail_address && *personal_mail_address) + if (personal_mail_address && *personal_mail_address) { strcpy(display_option, personal_mail_address); - else { /* clear the NONE */ + } else { /* clear the NONE */ move(L_MAIL_ADDRESS, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; @@ -539,9 +638,11 @@ draw_options: response = ' '; break; - case 's': + case 's': /* Change case sentitivity for searches. */ case 'S': - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0],"CASE INSENSITIVE"); choices[1] = NULL; @@ -554,10 +655,23 @@ draw_options: response = ' '; break; - case 'c': + case 'c': /* Change charset setting. */ case 'C': + if (!LYSelectPopups) { current_char_set = boolean_choice(current_char_set, - L_CHARSET, -1, LYchar_set_names); + L_CHARSET, -1, + LYchar_set_names); + } else { + current_char_set = popup_choice(current_char_set, + L_CHARSET, -1, + LYchar_set_names, + 0, FALSE); +#if defined(VMS) || defined(USE_SLANG) + move(L_CHARSET, COL_OPTION_VALUES); + clrtoeol(); + addstr(LYchar_set_names[current_char_set]); +#endif /* VMS || USE_SLANG */ + } /* * Set the raw 8-bit or CJK mode defaults and * character set if changed. - FM @@ -568,30 +682,47 @@ draw_options: HTMLUseCharacterSet(current_char_set); CurrentCharSet = current_char_set; CurrentRawMode = LYRawMode; +#if !defined(VMS) && !defined(USE_SLANG) + if (!LYSelectPopups) +#endif /* !VMS && !USE_SLANG */ + { move(L_RAWMODE, COL_OPTION_VALUES); clrtoeol(); addstr(LYRawMode ? "ON " : "OFF"); } + } response = ' '; + if (LYSelectPopups) { +#if !defined(VMS) || defined(USE_SLANG) + if (term_options) { + term_options = FALSE; + } else { + AddValueAccepted = TRUE; + } + goto draw_options; +#else + term_options = FALSE; +#endif /* !VMS || USE_SLANG */ + } break; - case 'o': + case 'o': /* Change raw mode setting. */ case 'O': - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; - LYRawMode = boolean_choice(LYRawMode, - L_RAWMODE, -1, choices); + LYRawMode = boolean_choice(LYRawMode, L_RAWMODE, -1, choices); /* * Set the LYUseDefaultRawMode value and character * handling if LYRawMode was changed. - FM */ if (CurrentRawMode != LYRawMode) { - HTMLSetUseDefaultRawMode(current_char_set, - LYRawMode); + HTMLSetUseDefaultRawMode(current_char_set, LYRawMode); HTMLSetCharacterHandling(current_char_set); CurrentRawMode = LYRawMode; } @@ -600,11 +731,11 @@ draw_options: response = ' '; break; - case 'g': /* change language preference */ + case 'g': /* Change language preference. */ case 'G': - if (language && *language) + if (language && *language) { strcpy(display_option, language); - else { /* clear the NONE */ + } else { /* clear the NONE */ move(L_LANGUAGE, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; @@ -631,11 +762,11 @@ draw_options: response = ' '; break; - case 'h': /* change character set preference */ + case 'h': /* Change charset preference. */ case 'H': - if (pref_charset && *pref_charset) + if (pref_charset && *pref_charset) { strcpy(display_option, pref_charset); - else { /* clear the NONE */ + } else { /* clear the NONE */ move(L_PREF_CHARSET, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; @@ -662,9 +793,11 @@ draw_options: response = ' '; break; - case 'v': + case 'v': /* Change VI keys setting. */ case 'V': - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0],"OFF"); choices[1] = NULL; @@ -673,18 +806,21 @@ draw_options: vi_keys = boolean_choice(vi_keys, L_BOOL_A, C_VIKEYS, choices); - if (vi_keys) + if (vi_keys) { set_vi_keys(); - else + } else { reset_vi_keys(); + } FREE(choices[0]); FREE(choices[1]); response = ' '; break; - case 'M': + case 'M': /* Change emacs keys setting. */ case 'm': - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0],"OFF"); choices[1] = NULL; @@ -693,21 +829,24 @@ draw_options: emacs_keys = boolean_choice(emacs_keys, L_BOOL_A, C_EMACSKEYS, choices); - if (emacs_keys) + if (emacs_keys) { set_emacs_keys(); - else + } else { reset_emacs_keys(); + } FREE(choices[0]); FREE(choices[1]); response = ' '; break; - case 'W': + case 'W': /* Change show dotfiles setting. */ case 'w': if (no_dotfiles) { option_statusline(DOTFILE_ACCESS_DISABLED); } else { - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0],"OFF"); choices[1] = NULL; @@ -723,52 +862,134 @@ draw_options: response = ' '; break; - case 't': + case 't': /* Change select popups setting. */ case 'T': - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; LYSelectPopups = boolean_choice(LYSelectPopups, - L_SELECT_POPUPS, -1, + L_BOOL_B, + C_SELECT_POPUPS, choices); FREE(choices[0]); FREE(choices[1]); response = ' '; break; - case 'k': + case '@': /* Change show cursor setting. */ + /* + * Copy strings into choice array. + */ + choices[0] = NULL; + StrAllocCopy(choices[0], "OFF"); + choices[1] = NULL; + StrAllocCopy(choices[1], "ON "); + choices[2] = NULL; + LYShowCursor = boolean_choice(LYShowCursor, + L_BOOL_B, + C_SHOW_CURSOR, + choices); + FREE(choices[0]); + FREE(choices[1]); + response = ' '; + break; + + case 'k': /* Change keypad mode. */ case 'K': - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; - StrAllocCopy(choices[0],"Numbers act as arrows"); + StrAllocCopy(choices[0], + "Numbers act as arrows "); choices[1] = NULL; - StrAllocCopy(choices[1],"Links are numbered "); + StrAllocCopy(choices[1], + "Links are numbered "); choices[2] = NULL; + StrAllocCopy(choices[2], + "Links and form fields are numbered"); + choices[3] = NULL; + if (!LYSelectPopups) { keypad_mode = boolean_choice(keypad_mode, - L_KEYPAD, -1, choices); - if (keypad_mode == NUMBERS_AS_ARROWS) + L_KEYPAD, -1, + choices); + } else { + keypad_mode = popup_choice(keypad_mode, + L_KEYPAD, -1, + choices, + 3, FALSE); +#if defined(VMS) || defined(USE_SLANG) + move(L_KEYPAD, COL_OPTION_VALUES); + clrtoeol(); + addstr(choices[keypad_mode]); +#endif /* VMS || USE_SLANG */ + } + if (keypad_mode == NUMBERS_AS_ARROWS) { set_numbers_as_arrows(); - else + } else { reset_numbers_as_arrows(); + } FREE(choices[0]); FREE(choices[1]); + FREE(choices[2]); response = ' '; + if (LYSelectPopups) { +#if !defined(VMS) || defined(USE_SLANG) + if (term_options) { + term_options = FALSE; + } else { + AddValueAccepted = TRUE; + } + goto draw_options; +#else + term_options = FALSE; +#endif /* !VMS || USE_SLANG */ + } break; - case 'n': + case 'n': /* Change line editor key bindings. */ case 'N': + if (!LYSelectPopups) { current_lineedit = boolean_choice(current_lineedit, - L_LINEED, -1, LYLineeditNames); + L_LINEED, -1, + LYLineeditNames); + } else { + current_lineedit = popup_choice(current_lineedit, + L_LINEED, -1, + LYLineeditNames, + 0, FALSE); +#if defined(VMS) || defined(USE_SLANG) + move(L_LINEED, COL_OPTION_VALUES); + clrtoeol(); + addstr(LYLineeditNames[current_lineedit]); +#endif /* VMS || USE_SLANG */ + } response = ' '; + if (LYSelectPopups) { +#if !defined(VMS) || defined(USE_SLANG) + if (term_options) { + term_options = FALSE; + } else { + AddValueAccepted = TRUE; + } + goto draw_options; +#else + term_options = FALSE; +#endif /* !VMS || USE_SLANG */ + } break; #ifdef DIRED_SUPPORT - case 'i': + case 'i': /* Change local directory sorting. */ case 'I': - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0],"Directories first"); choices[1] = NULL; @@ -776,18 +997,45 @@ draw_options: choices[2] = NULL; StrAllocCopy(choices[2],"Mixed style "); choices[3] = NULL; + if (!LYSelectPopups) { dir_list_style = boolean_choice(dir_list_style, - L_DIRED, -1, choices); + L_DIRED, -1, + choices); + } else { + dir_list_style = popup_choice(dir_list_style, + L_DIRED, -1, + choices, + 3, FALSE); +#if defined(VMS) || defined(USE_SLANG) + move(L_DIRED, COL_OPTION_VALUES); + clrtoeol(); + addstr(choices[dir_list_style]); +#endif /* VMS || USE_SLANG */ + } FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); response = ' '; + if (LYSelectPopups) { +#if !defined(VMS) || defined(USE_SLANG) + if (term_options) { + term_options = FALSE; + } else { + AddValueAccepted = TRUE; + } + goto draw_options; +#else + term_options = FALSE; +#endif /* !VMS || USE_SLANG */ + } break; #endif /* DIRED_SUPPORT */ - case 'u': + case 'u': /* Change user mode. */ case 'U': - /* copy strings into choice array */ + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0],"Novice "); choices[1] = NULL; @@ -795,24 +1043,50 @@ draw_options: choices[2] = NULL; StrAllocCopy(choices[2],"Advanced "); choices[3] = NULL; + if (!LYSelectPopups) { user_mode = boolean_choice(user_mode, - L_USER_MODE, -1, choices); + L_USER_MODE, -1, + choices); + } else { + user_mode = popup_choice(user_mode, + L_USER_MODE, -1, + choices, + 3, FALSE); +#if defined(VMS) || defined(USE_SLANG) + move(L_USER_MODE, COL_OPTION_VALUES); + clrtoeol(); + addstr(choices[user_mode]); +#endif /* VMS || USE_SLANG */ + } FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); - if(user_mode == NOVICE_MODE) - display_lines = LYlines-4; - else + if (user_mode == NOVICE_MODE) { + display_lines = (LYlines - 4); + } else { display_lines = LYlines-2; + } response = ' '; + if (LYSelectPopups) { +#if !defined(VMS) || defined(USE_SLANG) + if (term_options) { + term_options = FALSE; + } else { + AddValueAccepted = TRUE; + } + goto draw_options; +#else + term_options = FALSE; +#endif /* !VMS || USE_SLANG */ + } break; - case 'a': + case 'a': /* Change user agent string. */ case 'A': if (!no_useragent) { - if (LYUserAgent && *LYUserAgent) + if (LYUserAgent && *LYUserAgent) { strcpy(display_option, LYUserAgent); - else { /* clear the NONE */ + } else { /* clear the NONE */ move(L_HOME, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; @@ -852,22 +1126,29 @@ draw_options: break; #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS - case 'x': /* local exec */ + case 'x': /* Change local exec restriction. */ case 'X': - if (!exec_frozen) { + if (exec_frozen && !LYSelectPopups) { + option_statusline(CHANGE_OF_SETTING_DISALLOWED); + response = ' '; + break; + } #ifndef NEVER_ALLOW_REMOTE_EXEC if (local_exec) { itmp = 2; - } else { + } else #else { #endif /* NEVER_ALLOW_REMOTE_EXEC */ - if (local_exec_on_local_files) + if (local_exec_on_local_files) { itmp= 1; - else + } else { itmp = 0; } - /* copy strings into choice array */ + } + /* + * Copy strings into choice array. + */ choices[0] = NULL; StrAllocCopy(choices[0],"ALWAYS OFF "); choices[1] = NULL; @@ -877,57 +1158,79 @@ draw_options: StrAllocCopy(choices[2],"ALWAYS ON "); choices[3] = NULL; #endif /* NEVER_ALLOW_REMOTE_EXEC */ - itmp = boolean_choice(itmp, L_EXEC, -1, choices); - + if (!LYSelectPopups) { + itmp = boolean_choice(itmp, + L_EXEC, -1, + choices); + } else { + itmp = popup_choice(itmp, + L_EXEC, -1, + choices, + 0, (exec_frozen ? TRUE : FALSE)); +#if defined(VMS) || defined(USE_SLANG) + move(L_EXEC, COL_OPTION_VALUES); + clrtoeol(); + addstr(choices[itmp]); +#endif /* VMS || USE_SLANG */ + } FREE(choices[0]); FREE(choices[1]); #ifndef NEVER_ALLOW_REMOTE_EXEC FREE(choices[2]); #endif /* NEVER_ALLOW_REMOTE_EXEC */ + if (!exec_frozen) { switch(itmp) { case 0: local_exec = FALSE; local_exec_on_local_files = FALSE; - response = ' '; break; case 1: local_exec = FALSE; local_exec_on_local_files = TRUE; - response = ' '; break; #ifndef NEVER_ALLOW_REMOTE_EXEC case 2: local_exec = TRUE; local_exec_on_local_files = FALSE; - response = ' '; break; #endif /* NEVER_ALLOW_REMOTE_EXEC */ } /* end switch */ - } else { - option_statusline(CHANGE_OF_SETTING_DISALLOWED); } response = ' '; + if (LYSelectPopups) { +#if !defined(VMS) || defined(USE_SLANG) + if (exec_frozen || term_options) { + term_options = FALSE; + } else { + AddValueAccepted = TRUE; + } + goto draw_options; +#else + term_options = FALSE; +#endif /* !VMS || USE_SLANG */ + } break; #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */ - case '>': + case '>': /* Save current options to RC file. */ if (!no_option_save) { option_statusline(SAVING_OPTIONS); - if(save_rc()) + if (save_rc()) { option_statusline(OPTIONS_SAVED); - else + } else { HTAlert(OPTIONS_NOT_SAVED); - + } } else { option_statusline(R_TO_RETURN_TO_LYNX); - /* change response so that we don't exit - * the options menu + /* + * Change response so that we don't exit + * the options menu. */ response = ' '; } break; - case 'r': + case 'r': /* Return to document (quit options menu). */ case 'R': break; @@ -949,17 +1252,25 @@ draw_options: * and return it. */ PRIVATE int boolean_choice ARGS4( - int, status, + int, cur_choice, int, line, int, column, char **, choices) { int response = 0; - int respcmd; + int cmd = 0; int number = 0; int col = (column >= 0 ? column : COL_OPTION_VALUES); + int orig_choice = cur_choice; +#ifdef VMS + extern BOOLEAN HadVMSInterrupt; /* Flag from cleanup_sig() AST */ +#endif /* VMS */ - for (; choices[number] != NULL; number++) + /* + * Get the number of choices and then make + * number zero-based. + */ + for (number = 0; choices[number] != NULL; number++) ; /* empty loop body */ number--; @@ -970,11 +1281,13 @@ PRIVATE int boolean_choice ARGS4( option_statusline(ANY_KEY_CHANGE_RET_ACCEPT); /* - * Highlight the current selection. + * Highlight the current choice. */ move(line, col); standout(); - addstr(choices[status]); + addstr(choices[cur_choice]); + if (LYShowCursor) + move(line, (col - 1)); refresh(); /* @@ -983,37 +1296,63 @@ PRIVATE int boolean_choice ARGS4( * it can be changed, until the user accepts * the current choice. */ + term_options = FALSE; while (1) { move(line, col); + if (term_options == FALSE) { response = LYgetch(); - if (term_options || response == 7 || response == 3) + } + if (term_options || response == 7 || response == 3) { + /* + * Control-C or Control-G. + */ + response = '\n'; + term_options = TRUE; + cur_choice = orig_choice; + } +#ifdef VMS + if (HadVMSInterrupt) { + HadVMSInterrupt = FALSE; response = '\n'; - if (response != '\n' && response != '\r') { - respcmd = keymap[response+1]; -#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) - /* does this make sense here? dunno.. - kw */ - if (!respcmd && override[response+1] && !no_dired_support) - respcmd = override[response+1]; -#endif /* DIRED_SUPPORT && OK_OVERRIDE */ - switch (respcmd) { + term_options = TRUE; + cur_choice = orig_choice; + } +#endif /* VMS */ + if ((response != '\n' && response != '\r') && + (cmd = keymap[response+1]) != LYK_ACTIVATE) { + switch (cmd) { + case LYK_HOME: + cur_choice = 0; + break; + + case LYK_END: + cur_choice = number; + break; + + case LYK_REFRESH: + clearok(curscr, TRUE); + refresh(); + break; + + case LYK_QUIT: + case LYK_ABORT: + case LYK_PREV_DOC: + cur_choice = orig_choice; + term_options = TRUE; + break; + case LYK_PREV_PAGE: + case LYK_UP_HALF: case LYK_UP_TWO: case LYK_PREV_LINK: case LYK_UP_LINK: case LYK_LEFT_LINK: - case LYK_PREV_DOC: - if(status == 0) - status = number; /* go back to end */ + if(cur_choice == 0) + cur_choice = number; /* go back to end */ else - status--; - break; - case LYK_END: - status = number; + cur_choice--; break; - case LYK_HOME: - status = 0; - break; case LYK_1: case LYK_2: case LYK_3: @@ -1023,28 +1362,37 @@ PRIVATE int boolean_choice ARGS4( case LYK_7: case LYK_8: case LYK_9: - if((respcmd - LYK_1 + 1) <= number) { - status = respcmd -LYK_1 + 1; + if((cmd - LYK_1 + 1) <= number) { + cur_choice = cmd -LYK_1 + 1; break; } /* else fall through! */ default: - if (status == number) - status = 0; /* go over the top and around */ + if (cur_choice == number) + cur_choice = 0; /* go over the top and around */ else - status++; + cur_choice++; } /* end of switch */ - addstr(choices[status]); + addstr(choices[cur_choice]); + if (LYShowCursor) + move(line, (col - 1)); refresh(); } else { /* - * Unhighlight selection. + * Unhighlight choice. */ move(line, col); standend(); - addstr(choices[status]); + addstr(choices[cur_choice]); + if (term_options) { + term_options = FALSE; + option_statusline(CANCELLED); + sleep(InfoSecs); + option_statusline(""); + } else { option_statusline(VALUE_ACCEPTED); - return(status); + } + return(cur_choice); } } } @@ -1053,10 +1401,14 @@ PRIVATE void terminate_options ARGS1( int, sig) { term_options=TRUE; - /* Reassert the AST */ + /* + * Reassert the AST. + */ signal(SIGINT, terminate_options); #ifdef VMS - /* refresh the screen to get rid of the "interrupt" message */ + /* + * Refresh the screen to get rid of the "interrupt" message. + */ if (!dump_output_immediately) { clearok(curscr, TRUE); refresh(); @@ -1345,3 +1697,1035 @@ draw_bookmark_list: term_options = FALSE; signal(SIGINT, cleanup_sig); } + +/* +** This function prompts for a choice or page number. +** If a 'g' or 'p' suffix is included, that will be +** loaded into c. Otherwise, c is zeroed. - FM +*/ +PRIVATE int get_popup_choice_number ARGS1( + int *, c) +{ + char temp[120]; + + /* + * Load the c argument into the prompt buffer. + */ + temp[0] = *c; + temp[1] = '\0'; + option_statusline(OPTION_CHOICE_NUMBER); + + /* + * Get the number, possibly with a suffix, from the user. + */ + if (LYgetstr(temp, VISIBLE, sizeof(temp), NORECALL) < 0 || + *temp == 0 || term_options) { + option_statusline(CANCELLED); + sleep(InfoSecs); + *c = '\0'; + term_options = FALSE; + return(0); + } + + /* + * If we had a 'g' or 'p' suffix, load it into c. + * Otherwise, zero c. Then return the number. + */ + if (strchr(temp, 'g') != NULL || strchr(temp, 'G') != NULL) { + *c = 'g'; + } else if (strchr(temp, 'p') != NULL || strchr(temp, 'P') != NULL) { + *c = 'p'; + } else { + *c = '\0'; + } + return(atoi(temp)); +} + +/* + * This function offers the choices for values of an + * option via a popup window which functions like + * that for selection of options in a form. - FM + */ +PRIVATE int popup_choice ARGS6( + int, cur_choice, + int, line, + int, column, + char **, choices, + int, i_length, + int, disabled) +{ + int ly = line; + int lx = (column >= 0 ? column : (COL_OPTION_VALUES - 1)); + int c = 0, cmd = 0, i = 0, j = 0; + int orig_choice = cur_choice; +#ifndef USE_SLANG + WINDOW * form_window; +#endif /* !USE_SLANG */ + int num_choices = 0, top, bottom, length = -1, width = 0; + char ** Cptr = choices; + int window_offset = 0; + int DisplayLines = (LYlines - 2); + char Cnum[64]; + int Lnum; + int npages; +#ifdef VMS + extern BOOLEAN HadVMSInterrupt; /* Flag from cleanup_sig() AST */ +#endif /* VMS */ + static char prev_target[512]; /* Search string buffer */ + static char prev_target_buffer[512]; /* Next search buffer */ + static BOOL first = TRUE; + char *cp; + int ch = 0, recall; + int QueryTotal; + int QueryNum; + BOOLEAN FirstRecall = TRUE; + BOOLEAN ReDraw = FALSE; + int number; + char buffer[512]; + + /* + * Initialize the search string buffer. - FM + */ + if (first) { + *prev_target_buffer = '\0'; + first = FALSE; + } + *prev_target = '\0'; + QueryTotal = (search_queries ? HTList_count(search_queries) : 0); + recall = ((QueryTotal >= 1) ? RECALL : NORECALL); + QueryNum = QueryTotal; + + /* + * Count the number of choices to be displayed, where + * num_choices ranges from 0 to n, and set width to the + * longest choice string length. Also set Lnum to the + * length for the highest choice number, then decrement + * num_choices so as to be zero-based. The window width + * will be based on the sum of width and Lnum. - FM + */ + for (num_choices = 0; Cptr[num_choices] != NULL; num_choices++) { + if (strlen(Cptr[num_choices]) > width) { + width = strlen(Cptr[num_choices]); + } + } + sprintf(Cnum, "%d: ", num_choices); + Lnum = strlen(Cnum); + num_choices--; + + /* + * Let's assume for the sake of sanity that ly is the number + * corresponding to the line the option is on. + * Let's also assume that cur_choice is the number of the + * choice that should be initially selected, with 0 being + * the first choice. + * So what we have, is the top equal to the current screen line + * subtracting the cur_choice + 1 (the one must be for the top + * line we will draw in a box). If the top goes under 0, then + * consider it 0. + */ + top = ly - (cur_choice + 1); + if (top < 0) + top = 0; + + /* + * Check and see if we need to put the i_length parameter up to + * the number of real choices. + */ + if (i_length < 1) { + i_length = num_choices; + } else { + /* + * Otherwise, it is really one number too high. + */ + i_length--; + } + + /* + * The bottom is the value of the top plus the number of choices + * to view plus 3 (one for the top line, one for the bottom line, + * and one to offset the 0 counted in the num_choices). + */ + bottom = top + i_length + 3; + + /* + * Hmm... If the bottom goes beyond the number of lines available, + */ + if (bottom > DisplayLines) { + /* + * Position the window at the top if we have more + * choices than will fit in the window. + */ + if ((i_length + 3) > DisplayLines) { + top = 0; + bottom = (top + (i_length + 3)); + if (bottom > DisplayLines) + bottom = (DisplayLines + 1); + } else { + /* + * Try to position the window so that the selected choice will + * appear where the choice box currently is positioned. + * It could end up too high, at this point, but we'll move it + * down latter, if that has happened. + */ + top = (DisplayLines + 1) - (i_length + 3); + bottom = (DisplayLines + 1); + } + } + + /* + * This is really fun, when the length is 4, it means 0 to 4, or 5. + */ + length = (bottom - top) - 2; + + /* + * Move the window down if it's too high. + */ + if (bottom < ly + 2) { + bottom = ly + 2; + if (bottom > DisplayLines + 1) + bottom = DisplayLines + 1; + top = bottom - length - 2; + } + + /* + * Set up the overall window, including the boxing characters ('*'), + * if it all fits. Otherwise, set up the widest window possible. - FM + */ +#ifdef USE_SLANG + SLsmg_fill_region(top, lx - 1, bottom - top, (Lnum + width + 4), ' '); +#else + if (!(form_window = newwin(bottom - top, (Lnum + width + 4), + top, (lx - 1))) && + !(form_window = newwin(bottom - top, 0, top, 0))) { + option_statusline(POPUP_FAILED); + return(orig_choice); + } + scrollok(form_window, TRUE); +#endif /* USE_SLANG */ + + /* + * Clear the command line and write + * the popup statusline. - FM + */ + move((LYlines - 2), 0); + clrtoeol(); + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + + /* + * Set up the window_offset for choices. + * cur_choice ranges from 0...n + * length ranges from 0...m + */ + if (cur_choice >= length) { + window_offset = cur_choice - length + 1; + } + + /* + * Compute the number of popup window pages. - FM + */ + npages = ((num_choices + 1) > length) ? + (((num_choices + 1) + (length - 1))/(length)) + : 1; +/* + * OH! I LOVE GOTOs! hack hack hack + */ +redraw: + Cptr = choices; + + /* + * Display the boxed choices. + */ + for (i = 0; i <= num_choices; i++) { + if (i >= window_offset && i - window_offset < length) { + sprintf(Cnum, "%s%d: ", + ((num_choices > 8 && i < 9) ? + " " : ""), + (i + 1)); +#ifdef USE_SLANG + SLsmg_gotorc(top + ((i + 1) - window_offset), (lx - 1 + 2)); + addstr(Cnum); + SLsmg_write_nstring(Cptr[i], width); +#else + wmove(form_window, ((i + 1) - window_offset), 2); + wclrtoeol(form_window); + waddstr(form_window, Cnum); + waddstr(form_window, Cptr[i]); +#endif /* USE_SLANG */ + } + } +#ifdef USE_SLANG + SLsmg_draw_box(top, (lx - 1), (bottom - top), (Lnum + width + 4)); +#else +#ifdef VMS + VMSbox(form_window, (bottom - top), (Lnum + width + 4)); +#else + box(form_window, BOXVERT, BOXHORI); +#endif /* VMS */ + wrefresh(form_window); +#endif /* USE_SLANG */ + Cptr = NULL; + + /* + * Loop on user input. + */ + while (cmd != LYK_ACTIVATE) { + /* + * Unreverse cur choice. + */ + if (Cptr != NULL) { + sprintf(Cnum, "%s%d: ", + ((num_choices > 8 && i < 9) ? + " " : ""), + (i + 1)); +#ifdef USE_SLANG + SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); + addstr(Cnum); + SLsmg_write_nstring(Cptr[i], width); +#else + wmove(form_window, ((i + 1) - window_offset), 2); + waddstr(form_window, Cnum); + waddstr(form_window, Cptr[i]); +#endif /* USE_SLANG */ + } + Cptr = choices; + i = cur_choice; + sprintf(Cnum, "%s%d: ", + ((num_choices > 8 && i < 9) ? + " " : ""), + (i + 1)); +#ifdef USE_SLANG + SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); + addstr(Cnum); + SLsmg_set_color(2); + SLsmg_write_nstring(Cptr[i], width); + SLsmg_set_color(0); + /* + * If LYShowCursor is ON, move the cursor to the left + * of the current choice, so that blind users, who are + * most likely to have LYShowCursor ON, will have it's + * string spoken or passed to the braille interface as + * each choice is made current. Otherwise, move it to + * the bottom, right column of the screen, to "hide" + * the cursor as for the main document, and let sighted + * users rely on the current choice's highlighting or + * color without the distraction of a blinking cursor + * in the window. - FM + */ + if (LYShowCursor) + SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 1)); + else + SLsmg_gotorc((LYlines - 1), (LYcols - 1)); + SLsmg_refresh(); +#else + wmove(form_window, ((i + 1) - window_offset), 2); + waddstr(form_window, Cnum); + wstart_reverse(form_window); + waddstr(form_window, Cptr[i]); + wstop_reverse(form_window); + /* + * If LYShowCursor is ON, move the cursor to the left + * of the current choice, so that blind users, who are + * most likely to have LYShowCursor ON, will have it's + * string spoken or passed to the braille interface as + * each choice is made current. Otherwise, leave it to + * the right of the current choice, since we can't move + * it out of the window, and let sighted users rely on + * the highlighting of the current choice without the + * distraction of a blinking cursor preceding it. - FM + */ + if (LYShowCursor) + wmove(form_window, ((i + 1) - window_offset), 1); + wrefresh(form_window); +#endif /* USE_SLANG */ + + term_options = FALSE; + c = LYgetch(); + if (term_options || c == 3 || c == 7) { + /* + * Control-C or Control-G + */ + cmd = LYK_QUIT; + } else { + cmd = keymap[c+1]; + } +#ifdef VMS + if (HadVMSInterrupt) { + HadVMSInterrupt = FALSE; + cmd = LYK_QUIT; + } +#endif /* VMS */ + + switch(cmd) { + case LYK_F_LINK_NUM: + c = '\0'; + case LYK_1: + case LYK_2: + case LYK_3: + case LYK_4: + case LYK_5: + case LYK_6: + case LYK_7: + case LYK_8: + case LYK_9: + /* + * Get a number from the user, possibly with + * a 'g' or 'p' suffix (which will be loaded + * into c). - FM & LE + */ + number = get_popup_choice_number((int *)&c); + + /* + * Check for a 'p' suffix. - FM + */ + if (c == 'p') { + /* + * Treat 1 or less as the first page. - FM + */ + if (number <= 1) { + if (window_offset == 0) { + option_statusline(ALREADY_AT_CHOICE_BEGIN); + sleep(MessageSecs); + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + break; + } + window_offset = 0; + cur_choice = 0; + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + goto redraw; + } + + /* + * Treat a number equal to or greater than the + * number of pages as the last page. - FM + */ + if (number >= npages) { + if (window_offset >= ((num_choices - length) + 1)) { + option_statusline(ALREADY_AT_CHOICE_END); + sleep(MessageSecs); + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + break; + } + window_offset = ((npages - 1) * length); + if (window_offset > (num_choices - length)) { + window_offset = (num_choices - length + 1); + } + if (cur_choice < window_offset) + cur_choice = window_offset; + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + goto redraw; + } + + /* + * We want an intermediate page. - FM + */ + if (((number - 1) * length) == window_offset) { + sprintf(buffer, ALREADY_AT_CHOICE_PAGE, number); + option_statusline(buffer); + sleep(MessageSecs); + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + break; + } + cur_choice = window_offset = ((number - 1) * length); + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + goto redraw; + + } + + /* + * Check for a positive number, which signifies + * that a choice should be sought. - FM + */ + if (number > 0) { + /* + * Decrement the number so as to correspond + * with our cur_choice values. - FM + */ + number--; + + /* + * If the number is in range and had no legal + * suffix, select the indicated choice. - FM + */ + if (number <= num_choices && c == '\0') { + cur_choice = number; + cmd = LYK_ACTIVATE; + break; + } + + /* + * Verify that we had a 'g' suffix, + * and act on the number. - FM + */ + if (c == 'g') { + if (cur_choice == number) { + /* + * The choice already is current. - FM + */ + sprintf(buffer, + CHOICE_ALREADY_CURRENT, (number + 1)); + option_statusline(buffer); + sleep(MessageSecs); + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + break; + } + + if (number <= num_choices) { + /* + * The number is in range and had a 'g' + * suffix, so make it the current choice, + * scrolling if needed. - FM + */ + j = (number - cur_choice); + cur_choice = number; + if ((j > 0) && + (cur_choice - window_offset) >= length) { + window_offset += j; + if (window_offset > (num_choices - length + 1)) + window_offset = (num_choices - length + 1); + } else if ((cur_choice - window_offset) < 0) { + window_offset -= abs(j); + if (window_offset < 0) + window_offset = 0; + } + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + goto redraw; + } + + /* + * Not in range. - FM + */ + option_statusline(BAD_CHOICE_NUM_ENTERED); + sleep(MessageSecs); + } + } + + /* + * Restore the popup statusline. - FM + */ + if (disabled) { + option_statusline(CHOICE_LIST_UNM_MSG); + } else { + option_statusline(CHOICE_LIST_MESSAGE); + } + break; + + case LYK_PREV_LINK: + case LYK_UP_LINK: + + if (cur_choice > 0) + cur_choice--; + + /* + * Scroll the window up if necessary. + */ + if ((cur_choice - window_offset) < 0) { + window_offset--; + goto redraw; + } + break; + + case LYK_NEXT_LINK: + case LYK_DOWN_LINK: + if (cur_choice < num_choices) + cur_choice++; + + /* + * Scroll the window down if necessary + */ + if ((cur_choice - window_offset) >= length) { + window_offset++; + goto redraw; + } + break; + + case LYK_NEXT_PAGE: + /* + * Okay, are we on the last page of the choices list? + * If not then, + */ + if (window_offset != (num_choices - length + 1)) { + /* + * Modify the current choice to not be a + * coordinate in the list, but a coordinate + * on the item selected in the window. + */ + cur_choice -= window_offset; + + /* + * Page down the proper length for the list. + * If simply to far, back up. + */ + window_offset += length; + if (window_offset > (num_choices - length)) { + window_offset = (num_choices - length + 1); + } + + /* + * Readjust the current choice to be a choice + * list coordinate rather than window. + * Redraw this thing. + */ + cur_choice += window_offset; + goto redraw; + } + else if (cur_choice < num_choices) { + /* + * Already on last page of the choice list so + * just redraw it with the last item selected. + */ + cur_choice = num_choices; + } + break; + + case LYK_PREV_PAGE: + /* + * Are we on the first page of the choice list? + * If not then, + */ + if (window_offset != 0) { + /* + * Modify the current choice to not be a choice + * list coordinate, but a window coordinate. + */ + cur_choice -= window_offset; + + /* + * Page up the proper length. + * If too far, back up. + */ + window_offset -= length; + if (window_offset < 0) { + window_offset = 0; + } + + /* + * Readjust the current choice. + */ + cur_choice += window_offset; + goto redraw; + } else if (cur_choice > 0) { + /* + * Already on the first page so just + * back up to the first item. + */ + cur_choice = 0; + } + break; + + case LYK_HOME: + cur_choice = 0; + if (window_offset > 0) { + window_offset = 0; + goto redraw; + } + break; + + case LYK_END: + cur_choice = num_choices; + if (window_offset != (num_choices - length + 1)) { + window_offset = (num_choices - length + 1); + goto redraw; + } + break; + + case LYK_DOWN_TWO: + cur_choice += 2; + if (cur_choice > num_choices) + cur_choice = num_choices; + + /* + * Scroll the window down if necessary. + */ + if ((cur_choice - window_offset) >= length) { + window_offset += 2; + if (window_offset > (num_choices - length + 1)) + window_offset = (num_choices - length + 1); + goto redraw; + } + break; + + case LYK_UP_TWO: + cur_choice -= 2; + if (cur_choice < 0) + cur_choice = 0; + + /* + * Scroll the window up if necessary. + */ + if ((cur_choice - window_offset) < 0) { + window_offset -= 2; + if (window_offset < 0) + window_offset = 0; + goto redraw; + } + break; + + case LYK_DOWN_HALF: + cur_choice += (length/2); + if (cur_choice > num_choices) + cur_choice = num_choices; + + /* + * Scroll the window down if necessary. + */ + if ((cur_choice - window_offset) >= length) { + window_offset += (length/2); + if (window_offset > (num_choices - length + 1)) + window_offset = (num_choices - length + 1); + goto redraw; + } + break; + + case LYK_UP_HALF: + cur_choice -= (length/2); + if (cur_choice < 0) + cur_choice = 0; + + /* + * Scroll the window up if necessary. + */ + if ((cur_choice - window_offset) < 0) { + window_offset -= (length/2); + if (window_offset < 0) + window_offset = 0; + goto redraw; + } + break; + + case LYK_REFRESH: + clearok(curscr, TRUE); + refresh(); + break; + + case LYK_NEXT: + if (recall && *prev_target_buffer == '\0') { + /* + * We got a 'n'ext command with no prior query + * specified within the popup window. See if + * one was entered when the popup was retracted, + * and if so, assume that's what's wanted. Note + * that it will become the default within popups, + * unless another is entered within a popup. If + * the within popup default is to be changed at + * that point, use WHEREIS ('/') and enter it, + * or the up- or down-arrow keys to seek any of + * the previously entered queries, regardless of + * whether they were entered within or outside + * of a popup window. - FM + */ + if ((cp = (char *)HTList_objectAt(search_queries, + 0)) != NULL) { + strcpy(prev_target_buffer, cp); + QueryNum = 0; + FirstRecall = FALSE; + } + } + strcpy(prev_target, prev_target_buffer); + case LYK_WHEREIS: + if (*prev_target == '\0' ) { + option_statusline(ENTER_WHEREIS_QUERY); + if ((ch = LYgetstr(prev_target, VISIBLE, + sizeof(prev_target_buffer), + recall)) < 0) { + /* + * User cancelled the search via ^G. - FM + */ + option_statusline(CANCELLED); + sleep(InfoSecs); + goto restore_popup_statusline; + } + } + +check_recall: + if (*prev_target == '\0' && + !(recall && (ch == UPARROW || ch == DNARROW))) { + /* + * No entry. Simply break. - FM + */ + option_statusline(CANCELLED); + sleep(InfoSecs); + goto restore_popup_statusline; + } + + if (recall && ch == UPARROW) { + if (FirstRecall) { + /* + * Use the current string or + * last query in the list. - FM + */ + FirstRecall = FALSE; + if (*prev_target_buffer) { + for (QueryNum = (QueryTotal - 1); + QueryNum > 0; QueryNum--) { + if ((cp = (char *)HTList_objectAt( + search_queries, + QueryNum)) != NULL && + !strcmp(prev_target_buffer, cp)) { + break; + } + } + } else { + QueryNum = 0; + } + } else { + /* + * Go back to the previous query in the list. - FM + */ + QueryNum++; + } + if (QueryNum >= QueryTotal) + /* + * Roll around to the last query in the list. - FM + */ + QueryNum = 0; + if ((cp = (char *)HTList_objectAt(search_queries, + QueryNum)) != NULL) { + strcpy(prev_target, cp); + if (*prev_target_buffer && + !strcmp(prev_target_buffer, prev_target)) { + option_statusline(EDIT_CURRENT_QUERY); + } else if ((*prev_target_buffer && QueryTotal == 2) || + (!(*prev_target_buffer) && + QueryTotal == 1)) { + option_statusline(EDIT_THE_PREV_QUERY); + } else { + option_statusline(EDIT_A_PREV_QUERY); + } + if ((ch = LYgetstr(prev_target, VISIBLE, + sizeof(prev_target_buffer), recall)) < 0) { + /* + * User cancelled the search via ^G. - FM + */ + option_statusline(CANCELLED); + sleep(InfoSecs); + goto restore_popup_statusline; + } + goto check_recall; + } + } else if (recall && ch == DNARROW) { + if (FirstRecall) { + /* + * Use the current string or + * first query in the list. - FM + */ + FirstRecall = FALSE; + if (*prev_target_buffer) { + for (QueryNum = 0; + QueryNum < (QueryTotal - 1); QueryNum++) { + if ((cp = (char *)HTList_objectAt( + search_queries, + QueryNum)) != NULL && + !strcmp(prev_target_buffer, cp)) { + break; + } + } + } else { + QueryNum = (QueryTotal - 1); + } + } else { + /* + * Advance to the next query in the list. - FM + */ + QueryNum--; + } + if (QueryNum < 0) + /* + * Roll around to the first query in the list. - FM + */ + QueryNum = (QueryTotal - 1); + if ((cp = (char *)HTList_objectAt(search_queries, + QueryNum)) != NULL) { + strcpy(prev_target, cp); + if (*prev_target_buffer && + !strcmp(prev_target_buffer, prev_target)) { + option_statusline(EDIT_CURRENT_QUERY); + } else if ((*prev_target_buffer && + QueryTotal == 2) || + (!(*prev_target_buffer) && + QueryTotal == 1)) { + option_statusline(EDIT_THE_PREV_QUERY); + } else { + option_statusline(EDIT_A_PREV_QUERY); + } + if ((ch = LYgetstr(prev_target, VISIBLE, + sizeof(prev_target_buffer), + recall)) < 0) { + /* + * User cancelled the search via ^G. - FM + */ + option_statusline(CANCELLED); + sleep(InfoSecs); + goto restore_popup_statusline; + } + goto check_recall; + } + } + /* + * Replace the search string buffer with the new target. - FM + */ + strcpy(prev_target_buffer, prev_target); + HTAddSearchQuery(prev_target_buffer); + + /* + * Start search at the next choice. - FM + */ + for (j = 1; Cptr[i+j] != NULL; j++) { + sprintf(buffer, "%s%d: %s", + ((num_choices > 8 && (j + i) < 9) ? + " " : ""), + (i + j + 1), + Cptr[i+j]); + if (case_sensitive) { + if (strstr(buffer, prev_target_buffer) != NULL) + break; + } else { + if (LYstrstr(buffer, prev_target_buffer) != NULL) + break; + } + } + if (Cptr[i+j] != NULL) { + /* + * We have a hit, so make that choice the current. - FM + */ + cur_choice += j; + /* + * Scroll the window down if necessary. + */ + if ((cur_choice - window_offset) >= length) { + window_offset += j; + if (window_offset > (num_choices - length + 1)) + window_offset = (num_choices - length + 1); + ReDraw = TRUE; + } + goto restore_popup_statusline; + } + + /* + * If we started at the beginning, it can't be present. - FM + */ + if (cur_choice == 0) { + _user_message(STRING_NOT_FOUND, prev_target_buffer); + sleep(MessageSecs); + goto restore_popup_statusline; + } + + /* + * Search from the beginning to the current choice. - FM + */ + for (j = 0; j < cur_choice; j++) { + sprintf(buffer, "%s%d: %s", + ((num_choices > 8 && j < 9) ? + " " : ""), + (j + 1), + Cptr[j]); + if (case_sensitive) { + if (strstr(buffer, prev_target_buffer) != NULL) + break; + } else { + if (LYstrstr(buffer, prev_target_buffer) != NULL) + break; + } + } + if (j < cur_choice) { + /* + * We have a hit, so make that choice the current. - FM + */ + j = (cur_choice - j); + cur_choice -= j; + /* + * Scroll the window up if necessary. + */ + if ((cur_choice - window_offset) < 0) { + window_offset -= j; + if (window_offset < 0) + window_offset = 0; + ReDraw = TRUE; + } + goto restore_popup_statusline; + } + + /* + * Didn't find it in the preceding choices either. - FM + */ + _user_message(STRING_NOT_FOUND, prev_target_buffer); + sleep(MessageSecs); + +restore_popup_statusline: + /* + * Restore the popup statusline and + * reset the search variables. - FM + */ + if (disabled) + option_statusline(CHOICE_LIST_UNM_MSG); + else + option_statusline(CHOICE_LIST_MESSAGE); + *prev_target = '\0'; + QueryTotal = (search_queries ? HTList_count(search_queries) + : 0); + recall = ((QueryTotal >= 1) ? RECALL : NORECALL); + QueryNum = QueryTotal; + if (ReDraw == TRUE) { + ReDraw = FALSE; + goto redraw; + } + break; + + case LYK_QUIT: + case LYK_ABORT: + case LYK_PREV_DOC: + cur_choice = orig_choice; + term_options = TRUE; + option_statusline(CANCELLED); + sleep(MessageSecs); + cmd = LYK_ACTIVATE; /* to exit */ + break; + } + } +#ifndef USE_SLANG + delwin(form_window); +#endif /* !USE_SLANG */ + + if (disabled || term_options) { + option_statusline(""); + return(orig_choice); + } else { + option_statusline(VALUE_ACCEPTED); + return(cur_choice); + } +} |