static char rcsid[] = "@(#)$Id: extended.c,v 1.8 2006/06/25 10:41:05 hurtta Exp $"; /****************************************************************************** * The Elm (ME+) Mail System - $Revision: 1.8 $ $State: Exp $ * * Author: Kari Hurtta * or Kari Hurtta *****************************************************************************/ #include "def_elm.h" #include "s_me.h" DEBUG_VAR(Debug,__FILE__,"ELM"); #if ANSI_C struct command_selection; #define S_(x) static x; #else #define S_(x) #endif typedef void run_command P_((struct MailboxView *mailbox, struct AliasView *aview, struct menu_context *parent_page, struct menu_context *old_prompt)); typedef void run_command_post P_((struct MailboxView *mailbox, struct AliasView *aview, struct menu_context *page, struct screen_parts *LOC)); S_(run_command_post h_nopost_redraw) static void h_nopost_redraw P_((struct MailboxView *mailbox, struct AliasView *aview, struct menu_context *page, struct screen_parts *LOC)); static void h_nopost_redraw(mailbox,aview,page,LOC) struct MailboxView *mailbox; struct AliasView *aview; struct menu_context *page; struct screen_parts *LOC; { } S_(run_command dummy_quit) static void dummy_quit P_((struct MailboxView *mailbox, struct AliasView *aview, struct menu_context *page, struct menu_context *prompt)); static void dummy_quit(mailbox,aview,page,prompt) struct MailboxView *mailbox; struct AliasView *aview; struct menu_context *page; struct menu_context *prompt; { menu_Write_to_screen(prompt, CATGETS(elm_msg_cat, MeSet, MeExtendedQuit, "Quit")); FlushBuffer(); } S_(run_command h_duplicate_removal) static void h_duplicate_removal P_((struct MailboxView *mailbox, struct AliasView *aview, struct menu_context *page, struct menu_context *prompt)); static void h_duplicate_removal(mailbox,aview,page,prompt) struct MailboxView *mailbox; struct AliasView *aview; struct menu_context *page; struct menu_context *prompt; { menu_Write_to_screen(prompt, CATGETS(elm_msg_cat, MeSet, MeExtendedDuplicateRemoval, "Duplicate removal mode")); FlushBuffer(); ViewRemoveDuplicate(mailbox,aview,page); } S_(run_command h_open_mailbox) static void h_open_mailbox P_((struct MailboxView *mailbox, struct AliasView *aview, struct menu_context *page, struct menu_context *prompt)); static void h_open_mailbox(mailbox,aview,page,prompt) struct MailboxView *mailbox; struct AliasView *aview; struct menu_context *page; struct menu_context *prompt; { menu_Write_to_screen(prompt, CATGETS(elm_msg_cat, MeSet, MeExtendedOpenMailbox, "Open mailbox to current view")); FlushBuffer(); OpenMailbox(mailbox,aview,page); } S_(run_command_post h_open_mailbox_post) static void h_open_mailbox_post P_((struct MailboxView *mailbox, struct AliasView *aview, struct menu_context *page, struct screen_parts *LOC)); static void h_open_mailbox_post(mailbox,aview,page,LOC) struct MailboxView *mailbox; struct AliasView *aview; struct menu_context *page; struct screen_parts *LOC; { OpenMailboxPost(mailbox,page,LOC); } S_(run_command h_view_threads) static void h_view_threads P_((struct MailboxView *mailbox, struct AliasView *aview, struct menu_context *page, struct menu_context *prompt)); static void h_view_threads(mailbox,aview,page,prompt) struct MailboxView *mailbox; struct AliasView *aview; struct menu_context *page; struct menu_context *prompt; { menu_Write_to_screen(prompt, CATGETS(elm_msg_cat, MeSet, MeExtendedViewThreads, "View threads")); FlushBuffer(); ViewThreads(mailbox,aview,page); } static struct command_selection { int cmd; int nls_code; char * default_line; run_command * f_command; run_command_post * f_post; } commands[] = { { 'd', MeExtendedMenuDeplicateRemoval, "d)uplicate removal mode", h_duplicate_removal, h_nopost_redraw }, { 'o', MeExtendedMenuOpenMailbox, "o)pen mailbox to current view", h_open_mailbox, h_open_mailbox_post }, { 't', MeExtendedMenuViewThreads, "view t)hreads", h_view_threads, h_nopost_redraw }, { 'q', MeExtendedMenuQuit, "q)uit extended command", dummy_quit, h_nopost_redraw } }; static CONST int commands_len = sizeof (commands) / sizeof (commands[0]); S_(header_line_redraw extended_show_header) static void extended_show_header P_((struct menu_context *ptr, struct menu_param *list, int line_number, int index, int is_current)); static void extended_show_header(ptr,list,line_number,index,is_current) struct menu_context *ptr; struct menu_param *list; int line_number; int index; int is_current; { int LINES, COLUMNS; menu_get_sizes(ptr, &LINES, &COLUMNS); menu_ClearLine(ptr,line_number); menu_MoveCursor(ptr,line_number,0); if (is_current) { if (has_highlighting && ! arrow_cursor) { menu_StartXX(ptr,pg_INVERSE); menu_PutLine0(ptr,line_number,0," "); } else { menu_PutLine0(ptr,line_number,0,"-> "); } } else menu_PutLine0(ptr,line_number,0," "); if (index >= 0 && index < commands_len) { char * msg = catgets(elm_msg_cat, MeSet, commands[index].nls_code, commands[index].default_line); if (COLUMNS > 3) menu_PutLineX(ptr,line_number,3,FRM("%-*.*s"), COLUMNS-3,COLUMNS-3,msg); } if (is_current) { if (has_highlighting && ! arrow_cursor) { menu_EndXX(ptr,pg_INVERSE); } } menu_Writechar(ptr,'\r'); menu_Writechar(ptr,'\n'); } S_(header_line_redraw extended_show_current) static void extended_show_current P_((struct menu_context *ptr, struct menu_param *list, int line_number, int index, int is_current)); static void extended_show_current(ptr,list,line_number,index,is_current) struct menu_context *ptr; struct menu_param *list; int line_number; int index; int is_current; { if (has_highlighting && ! arrow_cursor) { extended_show_header(ptr,list,line_number,index,is_current); } else { if (!is_current) menu_PutLine0(ptr,line_number,0," "); /* remove old pointer... */ else menu_PutLine0(ptr,line_number,0,"->"); } } S_(subpage_simple_redraw sb_update_extended_title) static int sb_update_extended_title(ptr,list) struct menu_context *ptr; struct menu_param *list; { menu_ClearScreen(ptr); menu_print_format_center(ptr,0, CATGETS(elm_msg_cat, MeSet, MeExtendedTitle, "Extended command selection")); return 1; /* title completed */ } S_(subpage_simple_redraw sb_update_extended_menu) static int sb_update_extended_menu(ptr,list) struct menu_context *ptr; struct menu_param *list; { menu_ClearScreen(ptr); menu_print_format_center(ptr,0, CATGETS(elm_msg_cat, MeSet, MeExtendedMenuLine1, "To select command, press . j = move down, k = move up")); menu_print_format_center(ptr,1, CATGETS(elm_msg_cat, MeSet, MeExtendedMenuLine2, "Or select letter from command line.")); return 1; } static void set_extended_screen P_((struct menu_context *page, struct screen_parts *LOC, struct menu_param *LIST)); static void set_extended_screen(page,LOC, LIST) struct menu_context *page; struct screen_parts *LOC; struct menu_param *LIST; { int LINES, COLUMNS; int headers_per_page; menu_get_sizes(page,&LINES, &COLUMNS); /* 1) Title part */ if (! LOC->title_page) LOC->title_page = new_menu_subpage(page,0,2,sb_update_extended_title, LIST); else menu_subpage_relocate(LOC->title_page,page,0,2); /* 2) selection part */ headers_per_page = LINES-8; if (headers_per_page < 1) { headers_per_page = 1; } if (! LOC->header_page) LOC->header_page = new_menu_header(page,2, headers_per_page, extended_show_header, extended_show_current, null_header_param_changed, extended_show_current, LIST); else menu_header_relocate(LOC->header_page,page, 2,headers_per_page); /* 3) Menu part */ if (LOC->menu_page) menu_subpage_relocate(LOC->menu_page,page,LINES-6,2); else LOC->menu_page = new_menu_subpage(page,LINES-6,2, sb_update_extended_menu,LIST); /* 4) Prompt part */ if (LOC->prompt_page) menu_subpage_relocate(LOC->prompt_page,page,LINES-4,4); else LOC->prompt_page = new_menu_subpage(page,LINES-4,4, subpage_simple_noredraw,LIST); } static void check_extended_screen P_((struct screen_parts *LOC, struct menu_param *list)); static void check_extended_screen(LOC,list) struct screen_parts *LOC; struct menu_param *list; { /* Title area */ if (menu_resized(LOC->title_page)) { DPRINT(Debug,1, (&Debug, "title page resized\n")); } if (menu_need_redraw(LOC->title_page)) { DPRINT(Debug,1, (&Debug, "title page redraw???\n")); sb_update_extended_title(LOC->title_page,list); } /* Menu area */ if (menu_resized(LOC->menu_page)) { DPRINT(Debug,1, (&Debug, "menu page resized\n")); } if (menu_need_redraw(LOC->menu_page)) { DPRINT(Debug,1, (&Debug, "menu page redraw\n")); sb_update_extended_menu(LOC->menu_page,list); } /* Prompt area */ if (menu_resized(LOC->prompt_page)) { DPRINT(Debug,1, (&Debug, "prompt page resized\n")); } if (menu_need_redraw(LOC->prompt_page)) { DPRINT(Debug,7, (&Debug, "prompt page redraw\n")); menu_ClearScreen(LOC->prompt_page); show_last_error(); /* for those operations that have to * clear the footer except for a message. */ } if (menu_resized(LOC->header_page)) { DPRINT(Debug,1, (&Debug, "selection page resized\n")); menu_trigger_redraw(LOC->header_page); } if (menu_need_redraw(LOC->header_page)) { DPRINT(Debug,1, (&Debug, "selection page redraw\n")); menu_ClearScreen(LOC->header_page); } } static void first_item P_((void)); static void first_item() { lib_error(CATGETS(elm_msg_cat, MeSet, MeNoMoreCommandsAbove, "No more commands above.")); } static void last_item P_((void)); static void last_item() { lib_error(CATGETS(elm_msg_cat, MeSet, MeNoMoreCommandsBelow, "No more commands below.")); } static struct move_messages M = { first_item, last_item }; void extended_command(mailbox,aview,parent_page,parent_LOC) struct MailboxView *mailbox; struct AliasView *aview; struct menu_context *parent_page; struct screen_parts *parent_LOC; { run_command_post * postpage = h_nopost_redraw; struct menu_context *old_prompt = parent_LOC ? parent_LOC->prompt_page : NULL; int ch = 0; int update = 0; int screen_initialized = 0; struct menu_context *page = NULL; struct screen_parts LOC = { NULL, NULL, NULL, NULL }; struct menu_context *this_page = NULL; struct menu_context *this_prompt = NULL; /* Make possible type two character commands without printing of selection screen .. this waits a second for command */ if (old_prompt) { int lin,col; this_page = parent_page; this_prompt = old_prompt; menu_Write_to_screen(old_prompt,FRM(": ")); menu_GetXYLocation(old_prompt,&lin,&col); menu_CleartoEOS(old_prompt); show_last_error(); menu_MoveCursor(old_prompt,lin,col); ch = menu_ReadCh(old_prompt, REDRAW_MARK|READCH_CURSOR|READCH_resize| READCH_sig_char|READCH_poll); if (ch == EOF || ch == TERMCH_interrupt_char) goto OUT; if (ch != TIMEOUT_MARK) goto peek_key; } for (;;) { int i; if (! screen_initialized) { page = new_menu_context(); set_extended_screen(page,&LOC,NULL /* PARAM */); this_page = page; this_prompt = LOC.prompt_page; screen_initialized = 1; } if (update || menu_need_redraw(page)) { menu_ClearScreen(page); /* Call refresh routines of children */ menu_redraw_children(page); update = 0; show_last_error(); } check_extended_screen(&LOC,NULL /* PARAM */); { int lin,col; menu_ClearLine(LOC.prompt_page,0); menu_PutLineX (LOC.prompt_page,0, 0, CATGETS(elm_msg_cat, MeSet, MeExtendedPrompt, "Extended command: ")); menu_GetXYLocation(LOC.prompt_page,&lin,&col); menu_CleartoEOS(LOC.prompt_page); show_last_error(); menu_MoveCursor(LOC.prompt_page,lin,col); ch = menu_ReadCh(LOC.prompt_page, REDRAW_MARK|READCH_CURSOR|READCH_resize| READCH_sig_char); menu_CleartoEOS(LOC.prompt_page); set_error(""); /* clear error buffer */ } ch = do_movement(LOC.header_page,ch,commands_len,&M); switch (ch) { int cur; case 0: continue; case '\n': cur = menu_header_get(LOC.header_page,header_current); if (cur >= 0 && cur < commands_len) { commands[cur].f_command(mailbox,aview,this_page,this_prompt); postpage = commands[cur].f_post; goto OUT; } continue; } peek_key: for (i = 0; i < commands_len; i++) { if (ch == commands[i].cmd) { commands[i].f_command(mailbox,aview,this_page,this_prompt); postpage = commands[i].f_post; goto OUT; } } switch (ch) { case RESIZE_MARK: DPRINT(Debug,4, (&Debug, " ... resizing\n")); continue; case ctrl('L'): case REDRAW_MARK: DPRINT(Debug,4, (&Debug, " ... redrawing\n")); menu_ClearScreen(this_page); /* Clear possible redraw mark */ /* Call refresh routines of children */ menu_redraw_children(this_page); if (menu_need_redraw(this_prompt)) menu_ClearScreen(this_prompt); /* Clear redraw mark from prompt_area*/ update = 1; continue; case 'i': menu_Write_to_screen(this_prompt, CATGETS(elm_msg_cat, MeSet, MeExtendedGoIndex, "Go to index")); FlushBuffer(); /* FALLTHRU */ case 'q': case 'x': case TERMCH_interrupt_char: goto OUT; case EOF: goto OUT; default: lib_error(CATGETS(elm_msg_cat, MeSet, MeExtendedUnknownCommand, "Unknown command: %c"), ch); continue; } } OUT: error_wait(); if (screen_initialized) { free_mailbox_screen(&LOC); erase_menu_context(&page); /* Force default return to parent page ... */ menu_set_default(parent_page); menu_trigger_redraw(parent_page); } else if (old_prompt) menu_trigger_redraw(old_prompt); if (parent_LOC) postpage(mailbox,aview,parent_page,parent_LOC); } /* * Local Variables: * mode:c * c-basic-offset:4 * buffer-file-coding-system: iso-8859-1 * End: */