home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
- *
- * selection mode menu
- */
-
- #include "config.h"
- #include "articles.h"
- #include "term.h"
- #include "keymap.h"
- #include "menu.h"
- #include "regexp.h"
-
- import char *news_lib_directory;
-
- export int preview_window = 0; /* size of preview window */
- export int fmt_linenum = 1; /* menu line format */
- export int fmt_rptsubj = 0; /* repeat identical subjects if !0 */
- export int novice = 1; /* novice mode -- use extended prompts */
- export int long_menu = 0; /* don't put empty lines around menu lines */
- export int delay_redraw = 0; /* prompt again if :-command clears screen */
- export int slow_mode = 0; /* mark selected articles with *s */
- export int re_layout = 0; /* Re: format presentation on menus */
- export int collapse_subject = 25; /* collapse long subjects at position */
- export int conf_group_entry = 0; /* ask whether group should be entered */
- export int conf_entry_limit = 0; /* ask only if more than .. unread */
-
- export int auto_preview_mode = 0; /* preview rather than select */
- export int preview_continuation = 12; /* what to do after preview */
- export int preview_mark_read = 1; /* previewed articles are A_READ */
- export int select_on_sender = 0; /* + command selects on sender */
-
- export char delayed_msg[100] = ""; /* give to msg() after redraw */
-
- export int flush_typeahead = 0;
-
- import int also_read_articles;
- import int merged_menu;
- import int case_fold_search;
-
- extern group_completion();
-
- static regexp *regular_expr = NULL;
-
- static int firstl; /* first menu line */
-
- static article_number firsta; /* first article on menu (0 based) */
- static article_number nexta; /* first article on next menu */
- static int cura; /* current article */
- static int next_cura; /* article to become cura if >= 0 */
- static int numa; /* no of articles on menu - 1 */
- static attr_type last_attr;
-
- #define INTERVAL1 ('z' - 'a' + 1)
- #define INTERVAL2 ('9' - '0' + 1)
-
- char ident[] = "abcdefghijklmnopqrstuvwxyz0123456789";
-
- char attributes[30] = " .,+=#! **"; /* Corresponds to A_XXXX in data.h */
-
- static prt_replies(level)
- {
- int re;
-
- if (level == 0) return 0;
- re = level & 0x80;
- level &= 0x7f;
-
- switch (re_layout) {
- case 1:
- if (!re) return 0;
- so_printf(">");
- return 1;
- case 2:
- so_printf("%d>", level);
- return level < 10 ? 2 : 3;
- case 3:
- so_printf("Re: ");
- return 4;
- }
-
- if (level < 10) {
- so_printf("%-.*s", level, ">>>>>>>>>");
- return level;
- }
-
- so_printf(">>>%3d >>>>", level);
- return 11;
- }
-
- static mark()
- {
- register article_header *ah;
- int lno, lnum, lsubj, lname;
-
- ah = articles[firsta + cura];
- last_attr = ah->attr;
-
- if (last_attr == ah->disp_attr) return;
- if (cura < 0 || cura > numa) return;
-
- lno = firstl + cura;
- if (ah->disp_attr == A_NOT_DISPLAYED) {
- gotoxy(0, lno);
- putchar(ident[cura]);
- goto print_line;
- }
-
- /* A_AUTO_SELECT will not occur here! */
-
- if (!slow_mode)
- if (last_attr == A_SELECT) {
- if ((ah->disp_attr & A_SELECT) == 0) goto print_line;
- } else {
- if (ah->disp_attr & A_SELECT) goto print_line;
- }
-
- gotoxy(1, lno);
- putchar(attributes[ah->attr]);
- goto out;
-
- print_line:
- /* menu line formats:
- 1 3 8 10 20 22 xx
- : : : : : : :
- -1 id name:8 subject
- 0 id name subject +lines
- 1 id name lines subject
- 2 id lines subject
- 3 id subject
- 4 id subject (or as 1 if short subject)
- */
-
- if (fmt_linenum > 4) fmt_linenum = 1;
-
- if (!slow_mode && (ah->attr & A_SELECT)) {
- if (so_gotoxy(1, lno, 1) == 0)
- putchar(attributes[A_SELECT]);
- } else {
- gotoxy(1, lno);
- putchar(attributes[ah->attr]);
- }
-
- if (ah->lines < 10) lnum = 1; else
- if (ah->lines < 100) lnum = 2; else
- if (ah->lines < 1000) lnum = 3; else
- if (ah->lines < 10000) lnum = 4; else lnum = 5;
-
- lsubj = Columns - cookie_size - 2; /* ident char + space */
-
- switch (fmt_linenum) {
-
- case -1:
- lsubj -= 9;
- so_printf("%-8.8s ", ah->sender);
- break;
-
- case 0:
- lsubj -= NAME_LENGTH + 1 + 2 + lnum; /* name. .subj. +.lines */
- so_printf("%-*s ", NAME_LENGTH, ah->sender);
- break;
-
- case 4:
- if (ah->subj_length > (lsubj - NAME_LENGTH - 5))
- if (fmt_rptsubj || lno == firstl || (ah->flag & A_SAME) == 0) {
- so_printf(" ");
- lsubj -= 2;
- break;
- }
- /* else use layout 1, so fall thru */
-
- case 1:
- lsubj -= NAME_LENGTH + 5;
- /* name.lines. .subj (name may be shortened) */
- lname = NAME_LENGTH + 2 - lnum;
- so_printf("%-*.*s ", lname, lname, ah->sender);
- so_printf(ah->lines >= 0 ? "%d " : "? ", ah->lines);
- break;
-
- case 2:
- lsubj -= 6;
- so_printf("%5d ", ah->lines);
- break;
-
- case 3:
- break;
- }
-
- if (!fmt_rptsubj && lno > firstl && ah->flag & A_SAME) {
- if (ah->replies == 0 || prt_replies(ah->replies) == 0)
- so_printf("-");
- } else {
- lsubj -= prt_replies(ah->replies);
- if (lsubj >= ah->subj_length)
- so_printf("%s", ah->subject);
- else
- if (collapse_subject < 0)
- so_printf("%-.*s", lsubj, ah->subject);
- else {
- if (collapse_subject > 0)
- so_printf("%-.*s", collapse_subject, ah->subject);
- lsubj -= 2 + collapse_subject;
- so_printf("<>%s", ah->subject + ah->subj_length - lsubj);
- }
- }
-
- if (fmt_linenum == 0)
- so_printf(ah->lines >= 0 ? " +%d" : " +?", ah->lines);
-
- so_end();
-
- out:
- ah->disp_attr = last_attr;
- return;
- }
-
- static new_mark(how)
- attr_type how;
- {
- articles[firsta + cura]->attr = how;
- mark();
- }
-
- static toggle()
- {
- last_attr = articles[firsta + cura]->attr =
- articles[firsta + cura]->attr & A_SELECT ? 0 : A_SELECT;
- }
-
- static do_auto_kill()
- {
- register article_number i;
- register article_header *ah, **ahp;
- int any = 0;
-
- for (i = 0, ahp = articles; i < n_articles; i++, ahp++) {
- ah = *ahp;
- if (auto_select_article(ah, 0)) {
- ah->attr = A_KILL;
- any = 1;
- }
- }
- return any;
- }
-
- /*
- * perform auto selections that are not already selected
- * if article is in range firsta..firsta+numa (incl) mark article
- */
-
- static do_auto_select(re, mode)
- regexp *re;
- int mode;
- {
- register article_number i;
- register article_header *ah, **ahp;
- int count = 0, o_cura;
-
- o_cura = cura;
-
- for (i = 0, ahp = articles; i < n_articles; i++, ahp++) {
- ah = *ahp;
- if (re != NULL) {
- if (!regexec_cf(re, select_on_sender ? ah->sender : ah->subject)) continue;
- } else
- if (!auto_select_article(ah, mode)) continue;
-
- count++;
- if (ah->attr & A_SELECT) continue;
- if (firsta <= i && i <= (firsta+numa)) {
- cura = i - firsta;
- new_mark(A_SELECT);
- } else
- ah->attr = A_SELECT;
- }
-
- if (count)
- msg("Selected %d article%s", count, plural((long)count));
- else
- msg("No selections");
-
- cura = o_cura;
- }
-
- static quit_preview(cmd)
- int cmd;
- {
- int op;
-
- if ((firsta + cura) >= n_articles) return 1;
- op = preview_continuation;
- if (cmd == MC_PREVIEW_NEXT) op /= 10;
- op %= 10;
- switch (op) {
- case 0:
- return 1;
- case 1:
- return 0;
- case 2:
- return (articles[firsta+cura]->flag & (A_SAME | A_ALMOST_SAME)) == 0;
- }
- return 0;
- }
-
-
- static show_articles()
- {
- register article_number cur, next, temp;
- register article_header *ah;
- article_number elim_list[1];
- register int mode;
- int cmd, prev = -1, again;
- attr_type o_attr;
-
- do {
- for (cur = 0; cur < n_articles; cur++) {
- if (articles[cur]->attr & A_SELECT) break;
- }
-
- while (cur < n_articles) {
-
- for (next = cur+1; next < n_articles; next++) {
- if (articles[next]->attr & A_SELECT) break;
- }
-
- show:
- ah = articles[cur];
- o_attr = ah->attr;
- ah->attr = 0;
-
- mode = 0;
- if (prev >= 0) mode |= MM_PREVIOUS;
- if (next == n_articles) mode |= MM_LAST_SELECTED;
- if ((cur + 1) >= n_articles) mode |= MM_LAST_ARTICLE;
- if (cur == 0) mode |= MM_FIRST_ARTICLE;
-
- cmd = more(ah, mode, 0);
-
- switch (cmd) {
-
- case MC_DO_KILL:
- if (do_auto_kill()) {
- elim_list[0] = next;
- elim_articles(elim_list, 1);
- cur = elim_list[0];
- /* if next was n_articles, cur will be 0 */
- if (cur >= n_articles || cur < 0
- || (articles[cur]->attr & A_SELECT) == 0)
- cur = n_articles;
- continue;
- }
- break;
-
- case MC_DO_SELECT:
- for (temp = cur+1; temp < n_articles; temp++) {
- if (auto_select_article(ah = articles[temp], 2)) {
- ah->attr = A_SELECT;
- if (temp < next) next = temp;
- }
- }
- break;
-
- case MC_PREV:
- if (prev == next) break;
-
- ah->attr = o_attr;
- next = cur; cur = prev; prev = next;
- goto show;
-
- case MC_NEXTSUBJ:
- ah->attr = A_READ;
- for (next = cur+1; next < n_articles; next++) {
- if (((ah = articles[next])->flag & (A_SAME | A_ALMOST_SAME)) == 0) break;
- ah->attr = A_READ;
- }
- for (; next < n_articles; next++) {
- if (articles[next]->attr & A_SELECT) break;
- }
- break;
-
- case MC_ALLSUBJ:
- for (next = cur+1; next < n_articles; next++) {
- ah = articles[next];
- if ((ah->flag & (A_SAME | A_ALMOST_SAME)) == 0) break;
- ah->attr = A_SELECT;
- }
- for (next = cur+1; next < n_articles; next++)
- if (articles[next]->attr & A_SELECT) break;
- break;
-
- case MC_MENU:
- ah->attr = o_attr;
- if (nexta - firsta < n_articles)
- if ((firsta = cur - 5) < 0) firsta = 0;
- next_cura = cur - firsta;
-
- return MC_MENU;
-
- case MC_NEXT:
- if (ah->attr == 0) /* Not set by more (sufficient ???) */
- ah->attr = A_READ;
- break;
-
- case MC_BACK_ART:
- ah->attr = o_attr ? o_attr : A_SEEN;
- next = cur - 1;
- break;
-
- case MC_FORW_ART:
- ah->attr = o_attr ? o_attr : A_SEEN;
- next = cur + 1;
- break;
-
- case MC_NEXTGROUP:
- case MC_REENTER_GROUP:
- case MC_QUIT:
- ah->attr = o_attr;
- return cmd;
-
- case MC_READGROUP:
- return cmd;
- }
-
- prev = cur; cur = next;
- }
-
- for (cur = 0; cur < n_articles; cur++)
- if (articles[cur]->attr & A_SELECT) break;
- if (cur < n_articles) continue;
-
- again = 0;
- for (cur = 0; cur < n_articles; cur++) {
- ah = articles[cur];
- if (ah->attr == A_LEAVE) {
- if (again == 0) {
- prompt("Show left over articles again now? ");
- if (yes(0) <= 0) break;
- }
- ah->attr = A_SELECT;
- again++;
- }
- }
-
- if (again > 1)
- sprintf(delayed_msg, "Showing %ld articles again", again);
- } while (again);
-
- return MC_READGROUP;
- }
-
- static int article_id;
- static int cur_key;
-
- static int get_k_cmd()
- {
- extern int any_message;
- register int c, map;
-
- if (flush_typeahead) flush_input();
-
- loop:
-
- article_id = -1;
-
- if ((c = get_c()) & GETC_COMMAND) {
- cur_key = K_interrupt;
- map = c & ~GETC_COMMAND;
- } else {
- cur_key = c;
- map = menu_key_map[c];
- }
- if (s_hangup) map = K_QUIT;
-
- if (map & K_MACRO) {
- m_invoke(map & ~K_MACRO);
- goto loop;
- }
-
- if (map & K_ARTICLE_ID) {
- article_id = map & ~K_ARTICLE_ID;
- map = K_ARTICLE_ID;
-
- if (article_id < 0 || article_id > numa) {
- ding();
- goto loop;
- }
- }
-
- if (any_message) clrmsg(-1);
- return map;
- }
-
-
- char *pct(start, end, first, last)
- long start, end, first, last;
- {
- long n = end - start;
- static char buf[16];
- char *fmt;
-
- if (first <= start || n <= 0)
- if (last >= end || n <= 0)
- return "All";
- else
- fmt = "Top %d%%";
- else
- if (last >= end)
- return "Bot";
- else
- fmt = "%d%%";
-
- sprintf(buf, fmt, ((last - start) * 100)/n);
- return buf;
- }
-
- static repl_attr(first, last, old, new, update)
- register article_number first, last;
- register attr_type old, new;
- int update;
- {
- int any;
-
- if (new == old) return 0;
- if (new == A_KILL) update = 0;
-
- any = 0;
- while (first < last) {
- if (old == A_KILL || articles[first]->attr == old) {
- articles[first]->attr = new;
- if (update) {
- cura = first-firsta;
- mark();
- }
- any = 1;
- }
-
- first++;
- }
- return any;
- }
-
-
- static repl_attr_all(old, new, update)
- attr_type old, new;
- int update;
- {
- return repl_attr((article_number)0, n_articles, old, new, update);
- }
-
- static get_purpose(purpose)
- char *purpose;
- {
- #ifdef NNTP
- return; /* newsgroups file is not available */
- #else
- FILE *f;
- char line[256], group[80];
- register char *cp, *pp;
- register int len;
-
- f = open_file(relative(news_lib_directory, "newsgroups"), OPEN_READ);
- if (f == NULL) return;
-
- sprintf(group, "%s\t", current_group->group_name);
- len = current_group->group_name_length + 1;
-
- while (fgets(line, 256, f) != NULL) {
- if (strncmp(line, group, len)) continue;
- cp = line + len;
- while (*cp && isspace(*cp)) cp++;
- for (pp = purpose, len = 76; --len >= 0 && *cp && *cp != NL; )
- *pp++ = *cp++;
- *pp = NUL;
- }
-
- fclose(f);
- #endif
- }
-
-
- menu(print_header)
- fct_type print_header;
- {
- register k_cmd, cur_k_cmd;
- register article_header *ah;
- int last_k_cmd;
- int menu_cmd, temp;
- int save_selected;
- article_number last_save;
- attr_type orig_attr, junk_attr;
- int doing_unshar, did_unshar, junk_prompt;
- char *fname, *savemode, *init_save();
- int maxa; /* max no of articles per menu page */
- int o_firsta, o_mode; /* for recursive calls */
- static menu_level = 0;
- char purpose[80], pr_fmt[60];
- extern int enable_stop, file_completion();
- extern int alt_cmd_key, in_menu_mode;
- article_number elim_list[3];
- int entry_check;
-
- #define menu_return(cmd) \
- { menu_cmd = (cmd); goto menu_exit; }
-
- flush_input();
-
- o_firsta = firsta;
- o_mode = in_menu_mode;
- in_menu_mode = 1;
-
- menu_level++;
-
- entry_check = menu_level == 1 && conf_group_entry &&
- current_group->unread_count > conf_entry_limit;
-
- sprintf(pr_fmt,
- menu_level == 1 ?
- "\1\2-- SELECT %s-----%%s-----\1" :
- "\1\2-- SELECT %s-----%%s-----<%s%d>--\1",
- novice ? "-- help:? " : "",
- novice ? "level " : "",
- menu_level);
-
- purpose[0] = NUL;
- if (!merged_menu && current_group->group_flag & G_NEW)
- get_purpose(purpose);
-
- firsta = 0;
- while (firsta < n_articles && articles[firsta]->attr == A_SEEN)
- firsta++;
-
- if (firsta == n_articles) firsta = 0;
-
- next_cura = -1;
- cur_k_cmd = K_UNBOUND;
-
- #ifdef HAVE_JOBCONTROL
- #define REDRAW_CHECK if (s_redraw) goto do_redraw
-
- do_redraw:
- /* safe to clear here, because we are going to redraw anyway */
- s_redraw = 0;
- #else
- #define REDRAW_CHECK
- #endif
-
- redraw:
- s_keyboard = 0;
-
- empty_menu_hack: /* do: "s_keyboard=1; goto empty_menu_hack;" */
- if (!slow_mode) s_keyboard = 0;
-
- nexta = firsta;
-
- clrdisp();
-
- firstl = CALL(print_header)();
-
- if (entry_check && menu_level == 1) {
- /* we do it here to avoid redrawing the group header */
- entry_check = 0;
- prompt_line = firstl;
- prompt("\1Enter?\1 ");
- if ((temp = yes(0)) <= 0) {
- if (temp < 0) {
- prompt("\1Mark as read?\1 ");
- if ((temp = yes(0)) < 0) menu_return(ME_QUIT);
- if (temp > 0) repl_attr_all(A_KILL, A_READ, 0);
- }
- menu_return(ME_NEXT);
- }
-
- gotoxy(0, firstl);
- clrline();
- }
-
- maxa = Lines - preview_window - firstl - 2;
- if (!long_menu) firstl++, maxa -= 2;
-
- if (maxa > (INTERVAL1 + INTERVAL2))
- maxa = INTERVAL1 + INTERVAL2;
-
- nextmenu:
-
- no_raw();
- gotoxy(0, firstl);
- clrpage(firstl);
-
- if (nexta > 0) {
- firsta = nexta;
- } else
- if (purpose[0]) {
- msg(purpose);
- }
-
- firsta = nexta;
- numa = Lines; /* for mark; is set correctly below */
- cura = 0;
-
- REDRAW_CHECK;
-
- if (!s_keyboard)
- while (nexta < n_articles && cura < maxa) {
- REDRAW_CHECK;
-
- articles[firsta+cura]->disp_attr = A_NOT_DISPLAYED;
- mark();
- nexta++; cura++;
- }
-
- fl;
- s_keyboard = 0;
-
- prompt_line = firstl + cura;
- if (!long_menu || cura < maxa) prompt_line++;
-
- numa = nexta - firsta - 1;
- if (numa < 0) prompt_line++;
-
- if (next_cura >= 0) {
- cura = next_cura;
- next_cura = -1;
- } else {
- cura = 0;
- for (article_id = firsta; cura < numa; article_id++, cura++)
- if ((articles[article_id]->attr & A_SELECT) == 0) break; /*???*/
- }
-
- build_prompt:
-
- raw();
-
- Prompt:
-
- prompt(pr_fmt,
- pct(0L, (long)(n_articles-1), (long)firsta, (long)(firsta+numa)));
-
- if (delayed_msg[0] != NUL) {
- msg(delayed_msg);
- delayed_msg[0] = NUL;
- }
-
- same_prompt:
-
- if (cura < 0 || cura > numa) cura = 0;
-
- if (numa >= 0) {
- gotoxy(0, firstl + cura);
- fl; /* place cursor at current article id */
- save_xy();
- }
-
- last_k_cmd = cur_k_cmd;
- k_cmd = get_k_cmd();
-
- alt_key:
-
- switch (cur_k_cmd = k_cmd) {
-
- case K_UNBOUND:
- ding();
- flush_input();
- case K_INVALID:
- goto same_prompt;
-
- case K_REDRAW:
- next_cura = cura;
- goto redraw;
-
- case K_LAST_MESSAGE:
- msg((char *)NULL);
- goto same_prompt;
-
- case K_HELP:
- if (numa < 0) goto nextmenu; /* give specific help here */
- display_help("menu");
- goto redraw;
-
- case K_SHELL:
- if (group_file_name) *group_file_name = NUL;
- if (shell_escape()) goto redraw;
- goto Prompt;
-
- case K_VERSION:
- prompt(P_VERSION);
- goto same_prompt;
-
- case K_EXTENDED_CMD:
- switch (alt_command()) {
-
- case AC_UNCHANGED:
- goto same_prompt;
-
- case AC_QUIT:
- menu_return( ME_QUIT );
-
- case AC_PROMPT:
- goto Prompt;
-
- case AC_REORDER:
- firsta = 0;
- /* fall thru */
- case AC_REDRAW:
- goto redraw;
-
- case AC_KEYCMD:
- k_cmd = alt_cmd_key;
- goto alt_key;
-
- case AC_REENTER_GROUP:
- menu_return(ME_REENTER_GROUP);
- }
-
- case K_QUIT:
- menu_return(ME_QUIT);
-
- case K_CANCEL:
- savemode = "Cancel";
- fname = "";
- goto cancel1;
-
- case K_SAVE_NO_HEADER:
- case K_SAVE_SHORT_HEADER:
- case K_SAVE_FULL_HEADER:
- case K_PRINT:
- case K_UNSHAR:
- case K_PATCH:
- case K_UUDECODE:
-
- if (numa < 0) goto nextmenu;
-
- fname = init_save(k_cmd, &savemode);
- if (fname == NULL) goto Prompt;
-
- cancel1:
- enable_stop = 0;
- save_selected = 0;
- doing_unshar = k_cmd == K_UNSHAR || k_cmd == K_PATCH;
- did_unshar = 0;
-
- m_startinput();
-
- if (novice)
- msg(" * selected articles on this page, + all selected articles");
-
- while (!save_selected && !did_unshar) {
- prompt("\1%s\1 %.*s Article (* +): ",
- savemode, Columns - 25, fname);
-
- k_cmd = get_k_cmd();
-
- if (k_cmd == K_SELECT_SUBJECT) {
- save_selected = 1;
- cura = 0;
- article_id = firsta;
- last_save = firsta + numa;
- } else
- if (k_cmd == K_AUTO_SELECT) {
- save_selected = 2;
- cura = -firsta;
- article_id = 0;
- last_save = n_articles - 1;
- } else
- if (k_cmd == K_ARTICLE_ID) {
- cura = article_id;
- article_id += firsta;
- last_save = article_id;
- } else
- break;
-
- for ( ; article_id <= last_save ; article_id++, cura++) {
- ah = articles[article_id];
- if (save_selected && (ah->attr & A_SELECT) == 0) continue;
-
- if (cur_k_cmd == K_CANCEL) {
- if (current_group->group_flag & G_FOLDER) {
- if (ah->attr != A_CANCEL) fcancel(ah);
- } else
- switch (cancel(ah)) {
- case -1:
- did_unshar = 1;
- continue;
- case 0:
- ah->attr = A_CANCEL;
- break;
- default:
- continue;
- }
-
- if (!did_unshar)
- mark();
-
- continue;
- }
-
- if (doing_unshar) {
- did_unshar++;
- } else
- if (ah->subject != NULL)
- prompt("Processing '%.50s'...", ah->subject);
- else if (cura >= 0 && cura <= numa)
- prompt("Processing %c...", ident[cura]);
- else
- prompt("Processing entry %d...", article_id);
-
- if (save(ah)) {
- ah->attr = A_READ;
- if (doing_unshar) continue;
-
- if (cura >= 0 && cura <= numa)
- mark();
- }
- }
- }
-
- if (save_selected) cura = 0;
-
- m_endinput();
-
- enable_stop = 1;
- if (cur_k_cmd != K_CANCEL)
- end_save();
-
- if (did_unshar) {
- printf("\r\n");
- any_key(0);
- goto redraw;
- }
- goto Prompt;
-
- case K_FOLLOW_UP:
- #ifdef NNTP_POST
- if (use_nntp && nntp_no_post()) goto same_prompt;
- #endif
- case K_REPLY:
- if (numa < 0) goto nextmenu;
-
- prompt(k_cmd == K_REPLY ?
- "\1Reply to author\1 of article: " :
- "\1Follow Up\1 to article: ");
-
- if (get_k_cmd() == K_ARTICLE_ID)
- if (answer(articles[firsta+article_id], k_cmd, -1))
- goto redraw;
-
- goto Prompt;
-
- case K_POST:
-
- #ifdef NNTP_POST
- if (use_nntp && nntp_no_post())
- goto same_prompt;
- #endif
- if (post_menu()) goto redraw;
- goto Prompt;
-
- case K_MAIL_OR_FORWARD:
- if (numa < 0) goto nextmenu;
-
- prompt("\1Article to be forwarded\1 (SP if none): ");
-
- if ((k_cmd = get_k_cmd()) == K_ARTICLE_ID) {
- if (answer(articles[firsta+article_id], K_MAIL_OR_FORWARD, 1))
- goto redraw;
- } else
- if (k_cmd == K_CONTINUE)
- if (answer((article_header *)NULL, K_MAIL_OR_FORWARD, 0))
- goto redraw;
-
- goto Prompt;
- /*
- case K_CANCEL:
- if (numa < 0) goto nextmenu;
-
- if (current_group->group_flag & G_FOLDER) {
- prompt("\1Cancel Folder\1 Article: ");
- if (get_k_cmd() == K_ARTICLE_ID) {
- cura = article_id;
- fcancel(articles[firsta+article_id]);
- mark();
- }
- goto Prompt;
- }
-
- prompt("\1Cancel\1 Article: ");
-
- if (get_k_cmd() == K_ARTICLE_ID)
- if (cancel(articles[firsta+article_id]) & 1) goto redraw;
- goto Prompt;
- */
- case K_UNSUBSCRIBE:
- if (unsubscribe(current_group)) {
- if (current_group->group_flag & G_UNSUBSCRIBED)
- menu_return(ME_NEXT);
- home();
- CALL(print_header)();
- }
- goto Prompt;
-
- case K_GROUP_OVERVIEW:
- group_overview(-1);
- goto redraw;
-
- case K_KILL_HANDLING:
- switch (kill_menu((article_header *)NULL)) {
- case 0: /* select */
- do_auto_select((regexp *)NULL, 2);
- break;
- case 1: /* kill */
- if (!do_auto_kill()) break;
- goto junk_killed_articles;
- default:
- break;
- }
- goto Prompt;
-
- case K_CONTINUE: /* goto next menu page or show the articles */
- repl_attr(firsta, nexta, 0, A_SEEN, 0);
- /* fall thru */
- case K_CONTINUE_NO_MARK: /* but don't mark unselected articles */
- if (nexta < n_articles) goto nextmenu;
- break;
-
- case K_READ_GROUP_UPDATE:
- repl_attr_all(0, A_SEEN, 0);
- break;
-
- case K_READ_GROUP_THEN_SAME:
- break;
-
- case K_NEXT_GROUP_NO_UPDATE:
- menu_return(ME_NEXT);
-
- case K_PREVIOUS:
- menu_return(ME_PREV);
-
- case K_ADVANCE_GROUP:
- case K_BACK_GROUP:
- if (merged_menu) {
- msg("No possible on merged menu");
- goto same_prompt;
- }
- /* FALL THRU */
-
- case K_GOTO_GROUP:
-
- switch (goto_group(k_cmd, (article_header *)NULL, (flag_type)0)) {
-
- case ME_REDRAW:
- firsta = 0;
- goto redraw;
-
- case ME_NO_ARTICLES:
- msg("No selections made.");
-
- case ME_NO_REDRAW:
- goto Prompt;
-
- case ME_QUIT:
- menu_return( ME_QUIT );
-
- case ME_PREV:
- goto redraw;
-
- case ME_NEXT:
- s_keyboard = 1;
- goto empty_menu_hack;
- }
-
- case K_LEAVE_NEXT:
- case K_JUNK_ARTICLES:
- junk_prompt = cur_k_cmd == K_JUNK_ARTICLES ? 1 : 5;
-
- for (;;) {
- switch (junk_prompt) {
- case 1:
- if (novice) msg("Use J repeatedly to select other functions");
- prompt("\1Mark read\1 S)een U)nmarked A)ll *+)selected a-z . [LN]");
- junk_attr = A_READ;
- break;
- case 2:
- prompt("\1Unmark\1 S)een R)ead a-z [*+LAN.J] ");
- junk_attr = 0;
- break;
- case 3:
- prompt("\1Select\1 L)eft-over, N(leave-next) [USRa-z.J]");
- junk_attr = A_SELECT;
- break;
- case 4:
- prompt("\1Kill\1 R)ead S)een [LANU*+a-z.J]");
- junk_attr = A_KILL;
- break;
- case 5:
- prompt("\1Leave\1 a-z .,/ * + U)nmarked [LANRSJ]");
- junk_attr = A_LEAVE_NEXT;
- break;
- default:
- junk_prompt = 1;
- continue;
- }
-
- junk_another:
- if (cura < 0 || cura > numa) cura = 0;
- gotoxy(0, firstl + cura); fl;
-
- switch (get_k_cmd()) {
- case K_JUNK_ARTICLES:
- junk_prompt++; /* can be 0 */
- continue;
-
- case K_ARTICLE_ID:
- cura = article_id;
- case K_SELECT:
- if (junk_attr == A_KILL) junk_attr = A_READ;
- articles[firsta + cura]->attr = junk_attr;
- mark();
- cura++;
- goto junk_another;
-
- case K_NEXT_LINE:
- cura++;
- goto junk_another;
-
- case K_PREV_LINE:
- --cura;
- goto junk_another;
-
- case K_SELECT_SUBJECT:
- if (junk_attr == A_KILL) junk_attr = A_READ;
- repl_attr(firsta, nexta, A_AUTO_SELECT, A_SELECT, 0);
- repl_attr(firsta, nexta, A_SELECT, junk_attr, 1);
- goto Prompt;
-
- case K_AUTO_SELECT:
- repl_attr_all(A_AUTO_SELECT, A_SELECT, 0);
- orig_attr = A_SELECT;
- break;
-
- default:
- switch (cur_key) {
- case 'S':
- orig_attr = A_SEEN;
- break;
-
- case 'U':
- orig_attr = 0;
- break;
-
- case 'L':
- if (junk_attr == A_KILL) junk_attr = A_READ;
- orig_attr = A_LEAVE;
- break;
-
- case 'A':
- orig_attr = A_KILL;
- break;
-
- case 'N':
- orig_attr = A_LEAVE_NEXT;
- break;
-
- case 'R': /* kill read articles */
- orig_attr = A_READ;
- break;
-
- default:
- goto Prompt;
- }
- break;
- }
- break;
- }
- if (nexta - firsta < n_articles) {
- prompt("On all menu pages? ");
- switch (yes(1)) {
- case -1:
- goto Prompt;
- case 0:
- if (!repl_attr(firsta, nexta, orig_attr, junk_attr, 1))
- goto Prompt;
- break;
- case 1:
- if (!repl_attr_all(orig_attr, junk_attr, 1))
- goto Prompt;
- break;
- }
- } else
- if (!repl_attr(firsta, nexta, orig_attr, junk_attr, 1))
- goto Prompt;
-
- if (junk_attr != A_KILL) goto Prompt;
-
- junk_killed_articles:
- elim_list[0] = firsta;
- elim_list[1] = firsta + cura;
- elim_list[2] = nexta;
- if (elim_articles(elim_list, 3)) {
- firsta = elim_list[0];
- goto redraw;
- }
- firsta = elim_list[0];
- cura = elim_list[1] - firsta;
- nexta = elim_list[2];
- goto Prompt;
-
- case K_ARTICLE_ID:
- if (numa < 0) goto nextmenu;
-
- if (auto_preview_mode) goto auto_preview;
-
- cura = article_id;
- toggle();
- mark();
- cura++;
-
- goto same_prompt;
-
- case K_SELECT_INVERT:
- if (numa < 0) goto nextmenu;
-
- temp = cura;
-
- no_raw(); /* for x-on/x-off */
- for (cura = 0; cura <= numa; cura++) {
- toggle();
- mark();
- }
- fl;
-
- REDRAW_CHECK;
- raw();
-
- cura = temp;
- goto same_prompt;
-
-
- case K_SELECT:
- if (numa < 0) goto nextmenu;
-
- toggle();
- mark();
- cura++;
- goto same_prompt;
-
- case K_UNSELECT_ALL:
- if (last_k_cmd == K_UNSELECT_ALL)
- repl_attr_all(A_SELECT, 0, 1);
- else
- repl_attr_all(A_AUTO_SELECT, 0, 1);
- fl;
- cura = 0;
- goto same_prompt;
-
- case K_NEXT_LINE:
- if (numa < 0) goto nextmenu;
-
- cura++;
- goto same_prompt;
-
- case K_PREV_LINE:
- if (numa < 0) goto nextmenu;
-
- if (--cura < 0) cura = numa;
- goto same_prompt;
-
- case K_SELECT_SUBJECT:
- if (numa < 0) goto nextmenu;
-
- if (last_k_cmd != K_ARTICLE_ID && last_k_cmd != K_SELECT)
- toggle();
-
- while (firsta+cura > 0 &&
- (articles[firsta+cura]->flag & (A_SAME | A_ALMOST_SAME)))
- cura--;
-
- do {
- new_mark(last_attr);
- cura++;
- if (firsta+cura >= n_articles) break;
- } while (articles[firsta+cura]->flag & (A_SAME | A_ALMOST_SAME));
-
- goto same_prompt;
-
- case K_SELECT_RANGE:
- if (numa < 0) goto nextmenu;
-
- if (last_k_cmd == K_ARTICLE_ID || last_k_cmd == K_SELECT) {
- cura--;
- if (cura < 0) cura = numa;
- } else
- last_attr = (articles[firsta+cura]->attr & A_SELECT) ? 0 : A_SELECT;
-
- range_again:
-
- prompt("\1%select range\1 %c-", last_attr ? "S" : "Des", ident[cura]);
-
- k_cmd = get_k_cmd();
- if (k_cmd == K_SELECT_RANGE) {
- last_attr = last_attr ? 0 : A_SELECT;
- goto range_again;
- }
-
- if (k_cmd != K_ARTICLE_ID) goto Prompt;
-
- if (last_k_cmd != K_ARTICLE_ID && last_k_cmd != K_SELECT)
- new_mark(last_attr);
-
- if (article_id <= cura) {
- while (cura >= article_id) {
- new_mark(last_attr);
- cura--;
- }
- if (cura < 0) cura = 0;
- } else {
- while (cura <= article_id) {
- new_mark(last_attr);
- cura++;
- }
- if (cura > numa) cura = numa;
- }
- goto Prompt;
-
- case K_AUTO_SELECT:
- do_auto_select((regexp *)NULL, 1);
- goto same_prompt;
-
- case K_GOTO_MATCH:
- prompt("\1Select regexp\1 ");
- if ((fname = get_s(NONE, NONE, NONE, NULL_FCT)) == NULL)
- goto Prompt;
-
- if (*fname != NUL) {
- if (regular_expr) freeobj(regular_expr);
- if (case_fold_search) fold_string(fname);
- regular_expr = regcomp(fname);
- }
-
- if (regular_expr == NULL)
- msg("No previous expression");
- else
- do_auto_select(regular_expr, 2);
-
- goto Prompt;
-
- case K_NEXT_PAGE:
- if (nexta < n_articles) goto nextmenu;
- if (firsta == 0) goto same_prompt;
-
- nexta = 0;
- goto nextmenu;
-
- case K_PREV_PAGE:
- if (firsta == 0 && nexta == n_articles) goto same_prompt;
-
- nexta = (firsta > 0 ? firsta : n_articles) - maxa;
- if (nexta <= 1) nexta = 0;
- goto nextmenu;
-
- case K_FIRST_PAGE:
- if (firsta == 0) goto same_prompt;
-
- nexta = 0;
- goto nextmenu;
-
- case K_LAST_PAGE:
- if (nexta == n_articles) goto same_prompt;
-
- nexta = n_articles - maxa;
- if (nexta <= 1) nexta = 0;
- goto nextmenu;
-
- case K_PREVIEW:
- if (numa < 0) goto nextmenu;
-
- preview_other:
-
- prompt("\1Preview article\1");
- k_cmd = get_k_cmd();
-
- if (k_cmd != K_ARTICLE_ID) {
- if (k_cmd != K_PREVIEW)
- goto Prompt;
- article_id = cura;
- }
-
- auto_preview:
- temp = prompt_line;
-
- preview_next:
- cura = article_id;
- ah = articles[firsta+cura];
-
- no_raw();
- ah->attr = 0;
- menu_cmd = more(ah, MM_PREVIEW, prompt_line);
- if (menu_cmd == MC_MENU) {
- next_cura = cura;
- if (prompt_line < 0) goto redraw;
- mark();
- prompt_line = temp;
- goto build_prompt;
- }
-
- if (preview_mark_read && ah->attr == 0) ah->attr = A_READ;
- if (prompt_line >= 0)
- mark();
- next_cura = ++cura;
-
- switch (menu_cmd) {
-
- case MC_DO_KILL:
- if (!do_auto_kill()) break;
- elim_list[0] = firsta;
- elim_list[1] = firsta + cura;
- elim_articles(elim_list, 2);
- firsta = elim_list[0];
- next_cura = elim_list[1] - firsta;
- goto redraw;
-
- case MC_DO_SELECT:
- if (prompt_line >= 0) { /* not redrawn */
- do_auto_select((regexp *)NULL, 2);
- break;
- }
- numa = -1;
- do_auto_select((regexp *)NULL, 2);
- /* FALL THRU */
-
- case MC_QUIT:
- menu_return( ME_QUIT );
-
- case MC_REENTER_GROUP:
- menu_return( ME_REENTER_GROUP );
-
- case MC_NEXT:
- case MC_PREVIEW_NEXT:
- if (prompt_line < 0) { /* redrawn screen ! */
- if (quit_preview(menu_cmd)) goto redraw;
- prompt_line = Lines;
- } else {
- /* if (ah->attr == A_LEAVE || ah->attr == A_LEAVE_NEXT) {
- cura--;
- mark();
- cura++;
- }
- */ if (quit_preview(menu_cmd)) break;
- prompt_line = temp;
- }
- article_id = cura;
- goto preview_next;
-
- case MC_PREVIEW_OTHER:
- prompt_line = temp;
- raw();
- goto preview_other;
-
- default:
- if (prompt_line < 0) goto redraw;
- break;
- }
-
- prompt_line = temp;
- goto build_prompt;
-
- case K_LAYOUT:
- if (++fmt_linenum > 4) fmt_linenum = 0;
- goto redraw;
-
- default:
- msg("Command %d not supported", k_cmd);
- goto same_prompt;
- }
-
- no_raw();
-
- switch (show_articles()) {
-
- case MC_MENU:
- goto redraw;
-
- case MC_READGROUP:
- if (k_cmd == K_READ_GROUP_THEN_SAME || also_read_articles) goto redraw;
- case MC_NEXTGROUP:
- menu_cmd = ME_NEXT;
- break;
-
- case MC_REENTER_GROUP:
- menu_cmd = ME_REENTER_GROUP;
- break;
-
- case MC_QUIT:
- menu_cmd = ME_QUIT;
- break;
-
- default:
- sys_error("show_articles returned improper value");
- }
-
- menu_exit:
-
- firsta = o_firsta;
- in_menu_mode = o_mode;
- menu_level--;
-
- no_raw();
- return menu_cmd;
- }
-
-
- /*
- * return article header for article on menu
- */
-
- article_header *get_menu_article()
- {
- register article_header *ah;
-
- fputs(" from article: ", stdout); fl;
-
- if (get_k_cmd() == K_ARTICLE_ID) {
- ah = articles[firsta + article_id];
- if (ah->a_group) init_group(ah->a_group);
- return ah;
- }
-
- return NULL;
- }
-
-
-
- /*
- * read command from command line
- */
-
- alt_command()
- {
- int ok_val, macro_cmd;
- char *cmd, brkchars[10];
- extern key_type erase_key;
- extern int get_from_macro;
- extern int alt_completion();
-
- if (get_from_macro)
- ok_val = AC_UNCHANGED;
- else {
- prompt(":");
- ok_val = AC_PROMPT;
- }
-
- again:
-
- sprintf(brkchars, "?%c ", erase_key);
-
- cmd = get_s(NONE, NONE, brkchars, alt_completion);
- if (cmd == NULL ||
- *cmd == NUL || *cmd == SP || *cmd == erase_key)
- return ok_val;
-
- macro_cmd = get_from_macro;
-
- if (*cmd == '?') {
- display_file("help.extended", CLEAR_DISPLAY);
- ok_val = AC_REDRAW;
- goto new_prompt;
- }
-
- ok_val = parse_command(cmd, ok_val, (FILE *)NULL);
- if (ok_val != AC_REDRAW || !delay_redraw) return ok_val;
-
- new_prompt:
- if (macro_cmd) return ok_val;
-
- prompt_line = -1;
- printf("\n\r:");
- fl;
- goto again;
- }
-