📄 lyoptions.c
字号:
} /* end for */ } /* end while */ 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);#ifdef PDCURSES keypad(form_window, TRUE);#endif /* PDCURSES */#ifdef NCURSES LYsubwindow(form_window);#endif#if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */ wbkgd(form_window, getbkgd(stdscr)); wbkgdset(form_window, getbkgd(stdscr));#endif#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 LYbox(form_window, FALSE);#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, C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -