int mutt_yesorno (const char *msg, int def) { event_t ch; unsigned char *yes = (unsigned char *) _("yes"); unsigned char *no = (unsigned char *) _("no"); CLEARLINE(LINES-1); printw("%s ([%c]/%c): ", msg, def ? *yes : *no, def ? *no : *yes); FOREVER { mutt_refresh (); ch = mutt_getch (); if (ch.ch == -1) return(-1); if (CI_is_return (ch.ch)) break; else if (tolower(ch.ch) == tolower(*yes)) { def = 1; break; } else if (tolower(ch.ch) == tolower(*no)) { def = 0; break; } else { BEEP(); } } addstr ((char *) (def ? yes : no)); mutt_refresh (); return (def); }
int mutt_multi_choice (char *prompt, char *letters) { event_t ch; int choice; char *p; mvaddstr (LINES - 1, 0, prompt); clrtoeol (); FOREVER { mutt_refresh (); ch = mutt_getch (); if (ch.ch == -1 || CI_is_return (ch.ch)) { choice = -1; break; } else { p = strchr (letters, ch.ch); if (p) { choice = p - letters + 1; break; } else if (ch.ch <= '9' && ch.ch > '0') { choice = ch.ch - '0'; if (choice <= mutt_strlen (letters)) break; } } BEEP (); } CLEARLINE (LINES - 1); mutt_refresh (); return choice; }
/** * mutt_multi_choice - Offer the user a multiple choice question * @param prompt Message prompt * @param letters Allowable selection keys * @retval >=0 0-based user selection * @retval -1 Selection aborted */ int mutt_multi_choice(const char *prompt, const char *letters) { struct Event ch; int choice; bool redraw = true; int prompt_lines = 1; char *p = NULL; while (true) { if (redraw || SigWinch) { redraw = false; if (SigWinch) { SigWinch = 0; mutt_resize_screen(); clearok(stdscr, TRUE); mutt_menu_current_redraw(); } if (MuttMessageWindow->cols) { prompt_lines = (mutt_strwidth(prompt) + MuttMessageWindow->cols - 1) / MuttMessageWindow->cols; prompt_lines = MAX(1, MIN(3, prompt_lines)); } if (prompt_lines != MuttMessageWindow->rows) { mutt_window_reflow_message_rows(prompt_lines); mutt_menu_current_redraw(); } SETCOLOR(MT_COLOR_PROMPT); mutt_window_mvaddstr(MuttMessageWindow, 0, 0, prompt); NORMAL_COLOR; mutt_window_clrtoeol(MuttMessageWindow); } mutt_refresh(); /* SigWinch is not processed unless timeout is set */ mutt_getch_timeout(30 * 1000); ch = mutt_getch(); mutt_getch_timeout(-1); if (ch.ch == -2) continue; /* (ch.ch == 0) is technically possible. Treat the same as < 0 (abort) */ if ((ch.ch <= 0) || CI_is_return(ch.ch)) { choice = -1; break; } else { p = strchr(letters, ch.ch); if (p) { choice = p - letters + 1; break; } else if ((ch.ch <= '9') && (ch.ch > '0')) { choice = ch.ch - '0'; if (choice <= mutt_str_strlen(letters)) break; } } BEEP(); } if (MuttMessageWindow->rows != 1) { mutt_window_reflow_message_rows(1); mutt_menu_current_redraw(); } else mutt_window_clearline(MuttMessageWindow, 0); mutt_refresh(); return choice; }
/** * mutt_yesorno - Ask the user a Yes/No question * @param msg Prompt * @param def Default answer, see #QuadOption * @retval num Selection made, see #QuadOption */ enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def) { struct Event ch; char *yes = _("yes"); char *no = _("no"); char *answer_string = NULL; int answer_string_wid, msg_wid; size_t trunc_msg_len; bool redraw = true; int prompt_lines = 1; char *expr = NULL; regex_t reyes; regex_t reno; char answer[2]; answer[1] = '\0'; bool reyes_ok = (expr = nl_langinfo(YESEXPR)) && (expr[0] == '^') && (REGCOMP(&reyes, expr, REG_NOSUB) == 0); bool reno_ok = (expr = nl_langinfo(NOEXPR)) && (expr[0] == '^') && (REGCOMP(&reno, expr, REG_NOSUB) == 0); /* In order to prevent the default answer to the question to wrapped * around the screen in the even the question is wider than the screen, * ensure there is enough room for the answer and truncate the question * to fit. */ safe_asprintf(&answer_string, " ([%s]/%s): ", (def == MUTT_YES) ? yes : no, (def == MUTT_YES) ? no : yes); answer_string_wid = mutt_strwidth(answer_string); msg_wid = mutt_strwidth(msg); while (true) { if (redraw || SigWinch) { redraw = false; if (SigWinch) { SigWinch = 0; mutt_resize_screen(); clearok(stdscr, TRUE); mutt_menu_current_redraw(); } if (MuttMessageWindow->cols) { prompt_lines = (msg_wid + answer_string_wid + MuttMessageWindow->cols - 1) / MuttMessageWindow->cols; prompt_lines = MAX(1, MIN(3, prompt_lines)); } if (prompt_lines != MuttMessageWindow->rows) { mutt_window_reflow_message_rows(prompt_lines); mutt_menu_current_redraw(); } /* maxlen here is sort of arbitrary, so pick a reasonable upper bound */ trunc_msg_len = mutt_wstr_trunc( msg, 4 * prompt_lines * MuttMessageWindow->cols, prompt_lines * MuttMessageWindow->cols - answer_string_wid, NULL); mutt_window_move(MuttMessageWindow, 0, 0); SETCOLOR(MT_COLOR_PROMPT); addnstr(msg, trunc_msg_len); addstr(answer_string); NORMAL_COLOR; mutt_window_clrtoeol(MuttMessageWindow); } mutt_refresh(); /* SigWinch is not processed unless timeout is set */ mutt_getch_timeout(30 * 1000); ch = mutt_getch(); mutt_getch_timeout(-1); if (ch.ch == -2) continue; if (CI_is_return(ch.ch)) break; if (ch.ch < 0) { def = MUTT_ABORT; break; } answer[0] = ch.ch; if (reyes_ok ? (regexec(&reyes, answer, 0, 0, 0) == 0) : (tolower(ch.ch) == 'y')) { def = MUTT_YES; break; } else if (reno_ok ? (regexec(&reno, answer, 0, 0, 0) == 0) : (tolower(ch.ch) == 'n')) { def = MUTT_NO; break; } else { BEEP(); } } FREE(&answer_string); if (reyes_ok) regfree(&reyes); if (reno_ok) regfree(&reno); if (MuttMessageWindow->rows != 1) { mutt_window_reflow_message_rows(1); mutt_menu_current_redraw(); } else mutt_window_clearline(MuttMessageWindow, 0); if (def != MUTT_ABORT) { addstr((char *) ((def == MUTT_YES) ? yes : no)); mutt_refresh(); } else { /* when the users cancels with ^G, clear the message stored with * mutt_message() so it isn't displayed when the screen is refreshed. */ mutt_clear_error(); } return def; }