/* view.c */ #include "ml.h" /* * These MUST correspond with the Representation_Type * enum in structures.h */ MLRepresentation Representation[] = { { "Normal", NULL, XtNpresentNormal, }, { "Reverse", NULL, XtNpresentReverse, }, { "Sender", NULL, XtNpresentSender, }, { "Subject", NULL, XtNpresentSubject, }, { "Thread", NULL, XtNpresentThread, }, { "Size", NULL, XtNpresentSize, }, { NULL, NULL, NULL, }, }; #ifdef __STDC__ void init_representation(void) #else void init_representation() #endif { int i; for(i = 0; Representation[i].name != NULL; i ++) Representation[i].localized = MLGetLocalized(Representation[i].resource,Representation[i].name); return; } MLFlag Flags[] = { { "deleted", NULL, XtNflagDeleted, "\\Deleted", TRUE }, { "seen", NULL, XtNflagSeen, "\\Seen" , TRUE }, { "flagged", NULL, XtNflagFlagged, "\\Flagged", TRUE }, { "answered", NULL, XtNflagAnswered, "\\Answered", TRUE }, { "draft", NULL, XtNflagDraft, "\\Draft", TRUE }, { "recent", NULL, XtNflagRecent, "\\Recent", FALSE }, { NULL, NULL, NULL, NULL, FALSE }, }; #ifdef __STDC__ void init_flags(void) #else void init_flags() #endif { int i; for(i = 0; Flags[i].name != NULL; i ++) Flags[i].localized = MLGetLocalized(Flags[i].resource,Flags[i].name); return; } Menu view_lview_menu[] = { { NULL, "dismiss", NUL_TERM, view_lview_dismiss, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "save", NUL_TERM, view_lview_save, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "filter", NUL_TERM, view_filter, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "detach", NUL_TERM, view_lview_detach, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "hide", NUL_TERM, view_lview_hide, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "HELP", NUL_TERM, view_lview_help, NULL, 0, NULL, NULL, BTN_ON }, }; Menu view_save_menu[] = { { NULL, "fullhead", NUL_TERM, view_savefull, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, { NULL, "parthead", NUL_TERM, view_savepart, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, { NULL, "nonehead", NUL_TERM, view_savenone, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, }; Menu view_pipe_menu[] = { { NULL, "fullhead", NUL_TERM, view_execfull, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, { NULL, "parthead", NUL_TERM, view_execpart, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, { NULL, "nonehead", NUL_TERM, view_execnone, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, }; Menu view_print_menu[] = { { NULL, "fullhead", NUL_TERM, view_printfull, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, { NULL, "parthead", NUL_TERM, view_printpart, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, { NULL, "nonehead", NUL_TERM, view_printnone, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN}, }; Menu main_message_menu[] = { { NULL, "read_selected", NUL_TERM, view_read_selected, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "read_selected_newwin", NUL_TERM, view_read_selected_newwin, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "select_messages", NUL_TERM, view_select_messages, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "select_new_messages", NUL_TERM, view_select_new_messages, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "select_unseen_messages", NUL_TERM, view_select_unseen_messages, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "unselect_messages", NUL_TERM, view_unselect_messages, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "find_messages", NUL_TERM, view_find, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, }; Menu view_file_menu[] = { { NULL, "copy", NUL_TERM, view_copy, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "print_menu", NUL_TERM, NULL, view_print_menu, XtNumber(view_print_menu), NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "save_menu", NUL_TERM, NULL, view_save_menu, XtNumber(view_save_menu), NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "pipe_menu", NUL_TERM, NULL, view_pipe_menu, XtNumber(view_pipe_menu), NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, }; Menu view_setflags_menu[] = { { NULL, "set_deleted", NUL_TERM, view_set_deleted, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "set_seen", NUL_TERM, view_set_seen, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "set_flagged", NUL_TERM, view_set_flagged, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "set_answered", NUL_TERM, view_set_answered, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, }; Menu view_clearflags_menu[] = { { NULL, "clear_deleted", NUL_TERM, view_clear_deleted, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "clear_seen", NUL_TERM, view_clear_seen, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "clear_flagged", NUL_TERM, view_clear_flagged, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "clear_answered", NUL_TERM, view_clear_answered, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, }; Menu sort_menu[] = { { NULL, "sort_normal", NUL_TERM, view_sort_normal, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "sort_reverse", NUL_TERM, view_sort_reverse, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "sort_subject", NUL_TERM, view_sort_subject, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "sort_sender", NUL_TERM, view_sort_sender, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "sort_size", NUL_TERM, view_sort_size, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, }; Menu view_edit_menu[] = { { NULL, "setflags_menu", NUL_TERM, NULL, view_setflags_menu, XtNumber(view_setflags_menu), NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "clearflags_menu", NUL_TERM, NULL, view_clearflags_menu, XtNumber(view_clearflags_menu), NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "sort_menu", NUL_TERM, NULL, sort_menu, XtNumber(sort_menu), NULL, NULL, BTN_NOMAILBOXESOPEN }, }; Menu view_options_menu[] = { { NULL, "configure", NUL_TERM, view_configure, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "preferences", NUL_TERM, main_preferences, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "more_preferences", NUL_TERM, main_more_preferences, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "address_book", NUL_TERM, main_address_book, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "note_book", NUL_TERM, main_note_book, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "show_log", NUL_TERM, main_logwin, NULL, 0, NULL, NULL, BTN_ON }, }; Menu view_reply_submenu[] = { { NULL, "reply_sender", NUL_TERM, view_reply_sender, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "reply_all", NUL_TERM, view_reply_all, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, }; Menu view_forward_submenu[] = { { NULL, "forward", NUL_TERM, view_forward, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "forward_attach", NUL_TERM, view_forward_attach, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, }; Menu view_send_menu[] = { { NULL, "compose_new", NUL_TERM, main_compose, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "reply_menu", NUL_TERM, NULL, view_reply_submenu, XtNumber(view_reply_submenu), NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "forward_menu", NUL_TERM, NULL, view_forward_submenu, XtNumber(view_forward_submenu), NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, { NULL, "remail", NUL_TERM, view_remail, NULL, 0, NULL, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN }, }; Menu view_main_mailbox_menu[] = { { NULL, "listwin", NUL_TERM, view_lview_window, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "new", NUL_TERM, view_new, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "open_mailbox", NUL_TERM, view_open, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "check_mailbox", NUL_TERM, view_check_mailbox, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "expunge_messages", NUL_TERM, view_expunge_messages, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "no_update", NUL_TERM, view_no_update, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN|BTN_ISMAIL }, { NULL, "stopload_mailbox", NUL_TERM, view_stopload_mailbox, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "contload_mailbox", NUL_TERM, view_contload_mailbox, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "close_mailbox", NUL_TERM, view_close_mailbox, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "close", NUL_TERM, main_close, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "exit", NUL_TERM, bye, NULL, 0, NULL, NULL, BTN_ON }, }; Menu view_sub_mailbox_menu[] = { { NULL, "listwin", NUL_TERM, view_lview_window, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "new", NUL_TERM, view_new, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "open_mailbox", NUL_TERM, view_open, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "check_mailbox", NUL_TERM, view_check_mailbox, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "expunge_messages", NUL_TERM, view_expunge_messages, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "no_update", NUL_TERM, view_no_update, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN|BTN_ISMAIL }, { NULL, "stopload_mailbox", NUL_TERM, view_stopload_mailbox, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "contload_mailbox", NUL_TERM, view_contload_mailbox, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, { NULL, "close_mailbox", NUL_TERM, view_close_mailbox, NULL, 0, NULL, NULL, BTN_NOMAILBOXESOPEN }, }; Menu view_help_menu[] = { { NULL, "tophelp", NUL_TERM, main_help, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "window_help", NUL_TERM, view_window_help, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "keyboard_help", NUL_TERM, main_keyboard_help, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "config_help", NUL_TERM, main_config_help, NULL, 0, NULL, NULL, NUL_TERM }, { NULL, "resources_help", NUL_TERM, main_resources_help, NULL, 0, NULL, NULL, NUL_TERM }, { NULL, "intl_help", NUL_TERM, main_intl_help, NULL, 0, NULL, NULL, NUL_TERM }, { NULL, "version_help", NUL_TERM, main_version_help, NULL, 0, NULL, NULL, BTN_ON }, { NULL, "action_help", NUL_TERM, view_action_help, NULL, 0, NULL, NULL, BTN_ON }, }; Menu view_menu[] = { { NULL, "mailbox_menu", NUL_TERM, NULL, view_main_mailbox_menu, XtNumber(view_main_mailbox_menu), NULL, NULL, BTN_ON }, { NULL, "message_menu", NUL_TERM, NULL, main_message_menu, XtNumber(main_message_menu), NULL, NULL, BTN_ON }, { NULL, "file_menu", NUL_TERM, NULL, view_file_menu, XtNumber(view_file_menu), NULL, NULL, BTN_ON }, { NULL, "edit_menu", NUL_TERM, NULL, view_edit_menu, XtNumber(view_edit_menu), NULL, NULL, BTN_ON }, { NULL, "option_menu", NUL_TERM, NULL, view_options_menu, XtNumber(view_options_menu), NULL, NULL, BTN_ON }, { NULL, "send_menu", NUL_TERM, NULL, view_send_menu, XtNumber(view_send_menu), NULL, NULL, BTN_ON }, { NULL, "HELP_menu", NUL_TERM, NULL, view_help_menu, XtNumber(view_help_menu), NULL, NULL, BTN_ON }, }; Menu view_secondmenu[] = { { NULL, "mailbox_menu", NUL_TERM, NULL, view_sub_mailbox_menu, XtNumber(view_sub_mailbox_menu), NULL, NULL, BTN_ON }, { NULL, "message_menu", NUL_TERM, NULL, main_message_menu, XtNumber(main_message_menu), NULL, NULL, BTN_ON }, { NULL, "file_menu", NUL_TERM, NULL, view_file_menu, XtNumber(view_file_menu), NULL, NULL, BTN_ON }, { NULL, "edit_menu", NUL_TERM, NULL, view_edit_menu, XtNumber(view_edit_menu), NULL, NULL, BTN_ON }, { NULL, "option_menu", NUL_TERM, NULL, view_options_menu, XtNumber(view_options_menu), NULL, NULL, BTN_ON }, { NULL, "send_menu", NUL_TERM, NULL, view_send_menu, XtNumber(view_send_menu), NULL, NULL, BTN_ON }, { NULL, "HELP_menu", NUL_TERM, NULL, view_help_menu, XtNumber(view_help_menu), NULL, NULL, BTN_ON }, }; Button_Menu second_buttons[] = { { "view_read_selected_btn",view_read_selected, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN, NULL }, { "view_read_selectednew_btn",view_read_selected_newwin, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN, NULL }, { "view_set_deleted_btn", view_set_deleted, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN, NULL }, { "view_expunge_btn", view_expunge_messages, NULL, BTN_NOMAILBOXESOPEN, NULL }, { "view_copy_btn", view_copy, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN, NULL }, { "view_save_btn", view_savepart, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN, NULL }, { "view_reply_btn", view_reply_sender, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN, NULL }, { "view_replyall_btn", view_reply_all, NULL, BTN_NOSELECTION|BTN_NOMAILBOXESOPEN, NULL }, }; #ifdef __STDC__ void view_check_buttons(void) #else void view_check_buttons() #endif { ButtonState state; MainWindow *mwin; for(mwin = session->mwin; mwin; mwin = mwin->next) { if(mwin->destroyed) continue; state = (mwin->current) ? mwin->current->buttonstate : BTN_ON; update_buttons(mwin->buttonlist, session->buttonstate | state); XtVaSetValues(mwin->action_button, XmNsensitive, (session->buttonstate & BTN_NOMAILBOXESOPEN) ? FALSE : TRUE, NULL); } return; } #ifdef __STDC__ Mailbox *new_mailbox(void) #else Mailbox *new_mailbox() #endif { Mailbox *mailbox = (Mailbox *) fs_get(sizeof(Mailbox)); mailbox->mailstream = NULL; mailbox->host = NULL; mailbox->port = 0L; mailbox->auth_type = 0L; mailbox->ispop = FALSE; mailbox->imap_protocol = 0; mailbox->server = NULL; mailbox->mailboxname = NULL; mailbox->imapname = NULL; mailbox->type = MAILBOX_TYPE_MAIL; mailbox->fetched = FALSE; mailbox->auto_scan = FALSE; mailbox->no_update = FALSE; mailbox->bg_timer = (XtIntervalId) 0; mailbox->first_fetch = 0L; mailbox->has_new_mail = FALSE; mailbox->nmsgs = 0L; mailbox->found = NULL; mailbox->flags_changed = 0L; mailbox->update_needed = 0; mailbox->refresh_needed = 0; mailbox->timer = (XtIntervalId) 0; mailbox->next = NULL; mailbox->prev = NULL; return(mailbox); } #ifdef __STDC__ void free_mailbox(Mailbox *mailbox) #else void free_mailbox(mailbox) Mailbox *mailbox; #endif { if(mailbox != NULL) { if(mailbox->host) fs_give((void **) &mailbox->host); if(mailbox->mailboxname) fs_give((void **) &mailbox->mailboxname); if(mailbox->imapname) fs_give((void **) &mailbox->imapname); if(mailbox->found) free_message_list(mailbox->found,TRUE,FALSE); fs_give((void **) &mailbox); } return; } #ifdef __STDC__ Lview *new_lview(void) #else Lview *new_lview() #endif { Lview *lview = (Lview *) fs_get(sizeof(Lview)); lview->title = NULL; lview->mailstream = NULL; lview->mailbox = NULL; lview->message_list = NULL; lview->count = 0L; lview->pruned = 0L; lview->prune_happened = FALSE; lview->num_selected = 0L; lview->has_new = FALSE; lview->selected = FALSE; lview->number = 0L; lview->buttonstate = BTN_ON; lview->level = 0; lview->representation = REP_ASCENDING; lview->scripting = FALSE; lview->script_arg = NULL; lview->script_header = HEADER_UNKNOWN; lview->filter = NULL; lview->parent = NULL; lview->next = NULL; lview->prev = NULL; return(lview); } #ifdef __STDC__ void free_lview(Lview *lview) #else void free_lview(lview) Lview *lview; #endif { if(lview) { if(lview->title) fs_give((void **) &lview->title); if(lview->script_arg) fs_give((void **) &lview->script_arg); fs_give((void **) &lview); } return; } #ifdef __STDC__ Filter *new_filter(void) #else Filter *new_filter() #endif { Filter *filter = (Filter *) fs_get(sizeof(Filter)); filter->mailboxname = NULL; filter->name = NULL; filter->text = NULL; filter->action = NULL; filter->search_tree = NULL; filter->search_types = 0L; filter->archived = FALSE; filter->filter_type = FILTER_TYPE_UNKNOWN; filter->representation = REP_ASCENDING; filter->number = 0L; filter->next = NULL; filter->prev = NULL; return(filter); } #ifdef __STDC__ void free_filter(Filter *filter) #else void free_filter(filter) Filter *filter; #endif { if(filter) { if(filter->mailboxname) fs_give((void **) &filter->mailboxname); if(filter->name) fs_give((void **) &filter->name); if(filter->action) fs_give((void **) &filter->action); if(filter->text) fs_give((void **) &filter->text); cut_down_the_tree(filter->search_tree); fs_give((void **) &filter); } return; } #ifdef __STDC__ Message_List *new_message_list(void) #else Message_List *new_message_list() #endif { Message_List *message_list = (Message_List *) fs_get(sizeof(Message_List)); message_list->message = NULL; message_list->selected = FALSE; message_list->number = 0L; message_list->level = 0; message_list->prev = NULL; message_list->next = NULL; return(message_list); } #ifdef __STDC__ Message *new_message(void) #else Message *new_message() #endif { Message *message = (Message *) fs_get(sizeof(Message)); message->mailbox = NULL; message->mailstream = NULL; message->envelope = NULL; message->body = NULL; message->longcache = NULL; message->msgno = 0L; message->viewline = NULL; message->sender = NULL; message->subject = NULL; message->references = NULL; message->message_id = NULL; message->thread_parent = NULL; message->thread_child = FALSE; message->in_view = FALSE; message->fetched = FALSE; return(message); } #ifdef __STDC__ void free_message(Message *message) #else void free_message(message) Message *message; #endif { if(message == NULL) return; if(message->viewline) XmStringFree(message->viewline); if(message->sender) fs_give((void **) &message->sender); if(message->subject) fs_give((void **) &message->subject); if(message->references) fs_give((void **) &message->references); if(message->message_id != NULL) fs_give((void **) &message->message_id); fs_give((void **) &message); return; } #ifdef __STDC__ Filter_Map *new_filter_map(void) #else Filter_Map *new_filter_map() #endif { Filter_Map *filter_map = (Filter_Map *) fs_get(sizeof(Filter_Map)); filter_map->mailboxname = NULL; filter_map->filename = NULL; filter_map->sequence = 0; filter_map->next = NULL; return(filter_map); } #ifdef __STDC__ Filter_Map *get_filter_map(Lview *lview) #else Filter_Map *get_filter_map(lview) Lview *lview; #endif { Filter_Map *filter_map = NULL; if((lview == NULL) || (lview->mailbox == NULL) || (lview->mailbox->imapname == NULL)) return(NULL); for(filter_map = session->filter_map; filter_map; filter_map = filter_map->next) { if((strcmp(filter_map->mailboxname, lview->mailbox->imapname)) == STRMATCH) return(filter_map); } return(NULL); } #ifdef __STDC__ Filter_Map *generate_filter_map(Lview *lview) #else Filter_Map *generate_filter_map(lview) Lview *lview; #endif { char buffer[MAXPATHLEN]; Filter_Map *prev = NULL; Filter_Map *filter_map = new_filter_map(); filter_map->mailboxname = cpystr(lview->mailbox->imapname); if(session->filter_map == NULL) { session->filter_map = filter_map; sprintf(buffer,"%s/%s.1", session->cachedir,FILTERFILE); filter_map->sequence = 1; filter_map->filename = cpystr(buffer); } else { for(prev = session->filter_map; prev->next; prev = prev->next) ; filter_map->sequence = prev->sequence + 1; sprintf(buffer,"%s/%s.%d",session->cachedir, FILTERFILE, filter_map->sequence); filter_map->filename = cpystr(buffer); prev->next = filter_map; } (void) save_defaults(); return(filter_map); } #ifdef __STDC__ void free_message_list(Message_List *message_list, Boolean recurse, Boolean free_messages) #else void free_message_list(message_list, recurse, free_messages) Message_List *message_list; Boolean recurse; Boolean free_messages; #endif { if(message_list == NULL) return; if(recurse) free_message_list(message_list->next, recurse, free_messages); if(free_messages) free_message(message_list->message); fs_give((void **) &message_list); return; } #ifdef __STDC__ MainWindow *create_main_window(MainWindow *mainwin) #else MainWindow *create_main_window(mainwin) MainWindow *mainwin; #endif { Arg args[ARGLISTSIZE]; int n = 0; XtTranslations translations; MainWindow *mwin; MainWindow *curr; Boolean is_main = FALSE; if(mainwin) { mwin = mainwin; mwin->next = mwin->prev = NULL; mwin->is_main = is_main = TRUE; mwin->destroyed = FALSE; mwin->serialno = 1; } else { for(curr = session->mwin; curr; curr = curr->next) if(curr->destroyed == TRUE) break; if(curr) { curr->destroyed = FALSE; view_context_switch(curr, NULL, NULL); XtPopup(curr->shell,XtGrabNone); curr->lview = curr->current = NULL; view_check_buttons(); return(curr); } mwin = (MainWindow *) fs_get(sizeof(MainWindow)); mwin->is_main = FALSE; mwin->destroyed = FALSE; for(curr = session->mwin; curr->next; curr = curr->next) ; mwin->serialno = curr->serialno + 1; curr->next = mwin; mwin->prev = curr; mwin->next = NULL; if(preferences.autoPlace == TRUE) { XtSetArg(args[n], XtNx, -1000); n ++; XtSetArg(args[n], XtNy, -1000); n ++; } XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n++; mwin->shell = XtCreatePopupShell("mainwindow", topLevelShellWidgetClass, session->shell, args, n); n = 0; AddDestroyCallback (mwin->shell); } mwin->lview = mwin->current = NULL; mwin->listwin = (ListWindow *) fs_get(sizeof(ListWindow)); mwin->listwin->is_realized = FALSE; mwin->listwin->hide_empty = preferences.hide_empty; mwin->buttonlist = NULL; setup_editres(mwin->shell); if(view_icon != (Pixmap) None) XtVaSetValues(mwin->shell, XmNiconPixmap,view_icon, NULL); mwin->form = XmCreateForm(mwin->shell,"form",args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++; mwin->menubar = XmCreateMenuBar(mwin->form,"menubar", args, n); n = 0; XtManageChild(mwin->menubar); if(mwin->is_main) make_buttons(&mwin->buttonlist, NULL, mwin->menubar, view_menu, XtNumber(view_menu), BTN_NOSELECTION|BTN_NOMAILBOXESOPEN|BTN_NOPREV|BTN_NONEXT, (XtPointer) mwin, ROOTMENULEVEL); else make_buttons(&mwin->buttonlist, NULL, mwin->menubar, view_secondmenu, XtNumber(view_secondmenu), BTN_NOSELECTION|BTN_NOMAILBOXESOPEN|BTN_NOPREV|BTN_NONEXT, (XtPointer) mwin, ROOTMENULEVEL); XtSetArg(args[n], XmNadjustMargin, FALSE); n ++; XtSetArg(args[n], XmNmarginWidth, 0); n ++; XtSetArg(args[n], XmNborderWidth, 0); n ++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++; XtSetArg(args[n], XmNtopWidget, mwin->menubar); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n ++; XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n ++; mwin->rowcol = XmCreateRowColumn(mwin->form, "rowcol", args, n); n = 0; make_secondbuttons(mwin->buttonlist, mwin->rowcol, second_buttons, XtNumber(second_buttons), BTN_NOSELECTION|BTN_NOMAILBOXESOPEN, (XtPointer) mwin); XtManageChild(mwin->rowcol); XtSetArg(args[n], XmNborderWidth, 0); n ++; XtSetArg(args[n], XmNtraversalOn, FALSE); n ++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNtopWidget, mwin->rowcol); n ++; XtSetArg(args[n], XmNsensitive, FALSE); n ++; mwin->action_button = XmCreatePushButton(mwin->form,"action_button", args, n); n = 0; XtAddCallback(mwin->action_button,XmNactivateCallback, (XtCallbackProc) view_do_actions, mwin); XtManageChild(mwin->action_button); XtSetArg(args[n], XmNborderWidth, 0 ); n ++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET ); n ++; XtSetArg(args[n], XmNtopWidget, mwin->rowcol ); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM ); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET ); n ++; XtSetArg(args[n], XmNleftWidget, mwin->action_button ); n ++; mwin->action = XmCreateTextField(mwin->form, "action_textfld", args, n); n = 0; XtManageChild(mwin->action); translations = XtParseTranslationTable(GLOBAL_text_field_translations); XtOverrideTranslations(mwin->action,translations); translations = XtParseTranslationTable(GLOBAL_terminal_text_field_translations); XtOverrideTranslations(mwin->action,translations); XtAddCallback(mwin->action, XmNactivateCallback, (XtCallbackProc) view_do_actions, mwin); XtAddCallback(mwin->action, XmNmodifyVerifyCallback, (XtCallbackProc) text_field_edit, NULL); XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNtopWidget, mwin->action); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNtraversalOn, FALSE); n ++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n ++; XtSetArg(args[n], XmNvalue, 100); n ++; mwin->slider = XmCreateScale(mwin->form, "slider", args, n); n = 0; XtManageChild(mwin->slider); XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++; XtSetArg(args[n], XmNtopWidget, mwin->slider); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n ++; XtSetArg(args[n], XmNselectionPolicy, XmEXTENDED_SELECT); n ++; XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n ++; mwin->list = XmCreateScrolledList(mwin->form,"list",args,n); n = 0; XtAddCallback(mwin->list, XmNextendedSelectionCallback, (XtCallbackProc) view_set_select_messages, session); XtAddCallback(mwin->list, XmNdefaultActionCallback, (XtCallbackProc) view_read_message, session); translations = XtParseTranslationTable(GLOBAL_lview_pop_translations); XtOverrideTranslations(mwin->list,translations); XtManageChild(mwin->list); XtManageChild(mwin->form); if(is_main) XtRealizeWidget(mwin->shell); else { XtAddCallback(mwin->shell, XmNdestroyCallback, (XtCallbackProc) mwin_destroy, mwin); XtManageChild(mwin->shell); XtPopup(mwin->shell, XtGrabNone); position_popup_widget(mwin->shell, FALSE); } XmProcessTraversal(mwin->list, XmTRAVERSE_CURRENT); return(mwin); } /* * Window was destroyed. Possibly by a window manager. * Be nice and close the mailboxes. We have no control over * this or it would be nicer to ask first. It's quite possible * this happened by mistake. */ #ifdef __STDC__ void mwin_destroy(Tool w, MainWindow *mwin, XtPointer xp) #else void mwin_destroy(w, mwin, xp) Tool w; MainWindow *mwin; XtPointer xp; #endif { MainWindow *curr; Lview *lview; Boolean found; if(mwin->is_main == TRUE) return; if(mwin->prev == NULL) /* shouldn't happen */ session->mwin = mwin->next; if(mwin->next) mwin->next->prev = mwin->prev; if(mwin->prev) mwin->prev->next = mwin->next; do { found = FALSE; if((lview = mwin->lview) != NULL) { close_mailbox(lview->mailbox); found = TRUE; } } while(found == TRUE); free_buttonlist(mwin->buttonlist); fs_give((void **) &mwin); return; } #ifdef __STDC__ MainWindow *find_main_window(Mailbox *mailbox) #else MainWindow *find_main_window(mailbox) Mailbox *mailbox; #endif { MainWindow *curr; Lview *lview; for(curr = session->mwin; curr; curr = curr->next) { if(curr->destroyed) continue; for(lview = curr->lview; lview; lview = lview->prev) if(lview->mailbox == mailbox) return(curr); } return(NULL); } #ifdef __STDC__ void mwin_cancel(MainWindow *mwin) #else void mwin_cancel(mwin) MainWindow *mwin; #endif { if((mwin) && (mwin->lview == NULL) && (mwin->is_main == FALSE)) { XtPopdown(mwin->shell); mwin->destroyed = TRUE; if(mwin->listwin->is_realized) XtPopdown(mwin->listwin->shell); } return; } #ifdef __STDC__ void view_select_from_read(Lview *lview, Message *message) #else void view_select_from_read(lview,message) Lview *lview; Message *message; #endif { MainWindow *mwin; Message_List *ml = NULL; Lview *lv; Boolean found = FALSE; Boolean found_view = FALSE; if(message == NULL) return; for(mwin = session->mwin; mwin; mwin = mwin->next) { for(lv = mwin->lview; lv; lv = lv->prev) { if(lv == lview) { found_view = TRUE; break; } } if(found_view == TRUE) break; } if((mwin == NULL) || (lv == NULL)) return; if(lv == mwin->current) XmListDeselectAllItems(mwin->list); for(ml = lv->message_list; ml; ml = ml->next) { if(ml->selected == TRUE) ml->selected = FALSE; if(ml->message == message) { found = TRUE; if(lv == mwin->current) XmListSelectPos(mwin->list,ml->number,FALSE); ml->selected = TRUE; lv->buttonstate &= ~(BTN_NOSELECTION); } } if(found == FALSE) lv->buttonstate |= BTN_NOSELECTION; view_check_buttons(); return; } /* * Used in the do_action function for scripting flag settings. * IMAP flags have a preceding backslash. User flags don't. * Here we see if it's an IMAP flag, and return a pointer to * the flag name (which has the backslash). Otherwise, return * the original pointer; which is then assumed to be a user flag. */ #ifdef __STDC__ char *sys_flagname(char *flag) #else char *sys_flagname(flag) char *flag; #endif { int i; if(flag) { for(i = 0; Flags[i].name != NULL; i ++) if((strcasecmp(flag,Flags[i].localized)) == STRMATCH) return(Flags[i].protocol); } return(flag); } #ifdef __STDC__ Widget new_list_widget(MainWindow *mwin) #else Widget new_list_widget(mwin) MainWindow *mwin; #endif { Arg args[ARGLISTSIZE]; int n = 0; Widget list; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++; XtSetArg(args[n], XmNtopWidget, mwin->slider); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n ++; XtSetArg(args[n], XmNselectionPolicy,XmEXTENDED_SELECT); n ++; XtSetArg(args[n], XmNlistSizePolicy,XmCONSTANT); n ++; list = XmCreateScrolledList(mwin->form,"list",args,n); n = 0; XtAddCallback(list, XmNextendedSelectionCallback, (XtCallbackProc) view_set_select_messages, mwin); XtAddCallback(list, XmNdefaultActionCallback, (XtCallbackProc) view_read_message, mwin); return(list); } #ifdef __STDC__ void view_open(Widget w, MainWindow *mwin, XtPointer xp) #else void view_open(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { mailboxes(mwin,FALSE); return; } #ifdef __STDC__ void view_configure(Widget w, void *xp, XtPointer cb) #else void view_configure(w,xp,cb) Widget w; void *xp; XtPointer cb; #endif { create_host_window(session->shell, NULL); return; } #ifdef __STDC__ void view_new(Widget w, MainWindow *mwin, XtPointer xp) #else void view_new(w, mwin, xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { MainWindow *new_win = create_main_window(NULL); mailboxes(new_win,FALSE); return; } #ifdef __STDC__ void view_action_help(Widget w, MainWindow *mwin, XtPointer xp) #else void view_action_help(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { help(mwin->shell, VIEWACTIONHELPFILE); return; } #ifdef __STDC__ void view_window_help(Widget w, MainWindow *mwin, XtPointer xp) #else void view_window_help(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { help(mwin->shell, VIEWWINDOWHELPFILE); return; } #ifdef __STDC__ void view_do_actions(Widget w, MainWindow *mwin, XtPointer xp) #else void view_do_actions(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { char **parsed_actions; char *raw_action = NULL; char *clean_action = NULL; int n; char * ptr; ACTIONREC * a; HEADERREC * h; Lview *lview; char warn[FILEBUFFLEN]; lview = mwin->current; raw_action = GetTextField(mwin->action); if((lview == NULL) || (raw_action == NULL)) return; if(*raw_action == NUL_TERM) { fs_give((void **) &raw_action); return; } clean_action = clean_and_parse_action(raw_action); raw_action = NULL; parsed_actions = get_actions(clean_action); fs_give((void **) &clean_action); if(parsed_actions == NULL) return; for(n = 0; parsed_actions[n]; n ++ ) { if(lview->script_arg) fs_give((void **) &lview->script_arg); lview->script_arg = NULL; a = find_action(parsed_actions[n]); if(a == NULL) { sprintf(warn,MLGetLocalized(XtNmsgUnknownAction,MsgUnknownAction), parsed_actions[n]); mm_log(warn,WARN); break; } ptr = &parsed_actions[n][strlen(a->localized) + 1]; if(a->option == TRUE) { h = get_hdrlist(ptr); if(h != NULL) { lview->script_header = h->hdrtype; ptr += strlen(h->name) + 1; } } if(a->arg == TRUE) lview->script_arg = unquote(ptr); lview->scripting = TRUE; switch(a->action) { case DELETE_ACT: view_set_deleted(w,mwin,xp); break; case EXPUNGE_ACT: view_expunge_messages(w,mwin,xp); break; case COPY_ACT: view_copy(w,mwin,xp); break; case MOVE_ACT: view_move(w,mwin,xp); break; case SAVE_ACT: view_save_dispatch(w,mwin,HEADER_UNKNOWN); break; case PRINT_ACT: view_print_dispatch(w,mwin,HEADER_UNKNOWN); break; case SHELL_ACT: view_exec_dispatch(w,mwin,HEADER_UNKNOWN); break; case SELECT_ACT: view_select_messages(w,mwin,xp); break; case NEW_ACT: view_select_new_messages(w,mwin,xp); break; case UNSEEN_ACT: view_select_unseen_messages(w,mwin,xp); break; case UNSELECT_ACT: view_unselect_messages(w,mwin,xp); break; case FLAG_ACT: view_set_flagged(w,mwin,xp); break; case SET_ACT: view_setflag(w,mwin,sys_flagname(lview->script_arg)); break; case UNSET_ACT: view_clearflag(w,mwin,sys_flagname(lview->script_arg)); break; case READ_ACT: view_read_selected(w,mwin,(XmListCallbackStruct *) xp); break; default: sprintf(warn,MLGetLocalized(XtNmsgUnknownAction,MsgUnknownAction), a->localized); mm_log(warn,WARN); break; } lview->scripting = FALSE; continue; } free_actions(parsed_actions); return; } #ifdef __STDC__ void view_set_select_messages(Widget w, MainWindow *mwin, XmListCallbackStruct *xp) #else void view_set_select_messages(w,mwin,xp) Widget w; MainWindow *mwin; XmListCallbackStruct *xp; #endif { unsigned long n = 0; Message_List *message_list; for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { if((is_selected(xp, message_list->number)) == TRUE) message_list->selected = TRUE; else message_list->selected = FALSE; if(message_list->selected == TRUE) n ++; } mwin->current->num_selected = n; if(n) mwin->current->buttonstate &= ~(BTN_NOSELECTION); else mwin->current->buttonstate |= BTN_NOSELECTION; view_check_buttons(); return; } #ifdef __STDC__ void view_check_mailbox(Widget w, MainWindow *mwin, XtPointer xp) #else void view_check_mailbox(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Mailbox *mailbox; for(mailbox = session->mailboxes; mailbox; mailbox = mailbox->next) { if(mailbox->mailstream == mwin->current->mailstream) { check_mailbox(mailbox,FALSE); break; } } return; } #ifdef __STDC__ void view_stopload_mailbox(Widget w, MainWindow *mwin, XtPointer xp) #else void view_stopload_mailbox(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Mailbox *mailbox; for(mailbox = session->mailboxes; mailbox; mailbox = mailbox->next) { if(mailbox->mailstream == mwin->current->mailstream) { if(mailbox->bg_timer) { update_logical_views(mailbox,TRUE); mailbox->update_needed = 0; XtRemoveTimeOut(mailbox->bg_timer); mailbox->bg_timer = (XtIntervalId) 0; mm_log(MLGetLocalized(XtNmsgBackgroundStop,MsgBackgroundStop), MLNOTIFY); break; } else break; } } return; } #ifdef __STDC__ void view_contload_mailbox(Widget w, MainWindow *mwin, XtPointer xp) #else void view_contload_mailbox(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Mailbox *mailbox; for(mailbox = session->mailboxes; mailbox; mailbox = mailbox->next) { if(mailbox->mailstream == mwin->current->mailstream) { if(mailbox->bg_timer != (XtIntervalId) 0) return; mailbox->bg_timer = XtAppAddTimeOut(context, (mailbox->type == MAILBOX_TYPE_NEWS) ? (preferences.news_background * 1000) : (preferences.mail_background * 1000), (XtTimerCallbackProc) background_fetch, mailbox); return; } } return; } #ifdef __STDC__ void view_find(Widget w, MainWindow *mwin, XtPointer xp) #else void view_find(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Lview *lview; Filter *filter; char *text; parse_errors errors; Message_List *new, *curr; Message_List *message_list; unsigned long count = 0L; char errmsg[FILEBUFFLEN]; text = input_string(mwin->shell,MLGetLocalized(XtNmsgFilterDefinition, MsgFilterDefinition), NULL,EDFILTERHELPFILE); if(text == NULL) return; if(*text == NUL_TERM) { fs_give((void **) &text); return; } filter = new_filter(); filter->name = cpystr("Search"); errors = lv_parse_filter(filter->name,text, (LEAF **) &filter->search_tree, &filter->text, errmsg); if(errors != parse_success) { free_filter(filter); fs_give((void **) &text); mm_log(errmsg,WARN); return; } view_unselect_messages(w,mwin,xp); new = do_imap_search(mwin->current->mailbox,mwin->current, filter->search_tree); for(message_list = new; message_list; message_list = message_list->next) count ++; sprintf(errmsg,MLGetLocalized(XtNmsgFoundMessage,MsgFoundMessage),count, (count == 1) ? MLGetLocalized(XtNmsgMessageSingular,MsgMessageSingular) : MLGetLocalized(XtNmsgMessagePlural,MsgMessagePlural)); mm_log(errmsg,MLNOTIFY); if(count) { XtVaSetValues(mwin->list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL); for(curr = mwin->current->message_list; curr; curr = curr->next) { for(message_list = new; message_list; message_list = message_list->next){ if(message_list->message == curr->message) { XmListSelectPos(mwin->list,curr->number,FALSE); curr->selected = TRUE; } } } XtVaSetValues(mwin->list, XmNselectionPolicy, XmEXTENDED_SELECT, NULL); } mwin->current->num_selected = count; if(count) mwin->current->buttonstate &= ~(BTN_NOSELECTION); else mwin->current->buttonstate |= BTN_NOSELECTION; view_check_buttons(); free_message_list(new,TRUE,FALSE); free_filter(filter); fs_give((void **) &text); return; } #ifdef __STDC__ void view_read_message(Widget w, MainWindow *mwin, XmListCallbackStruct *xp) #else void view_read_message(w,mwin,xp) Widget w; MainWindow *mwin; XmListCallbackStruct *xp; #endif { Message_List *message_list; mwin->current->num_selected = 0L; for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { message_list->selected = FALSE; if(message_list->number == xp->item_position) { message_list->selected = TRUE; mwin->current->num_selected = 1L; mwin->current->buttonstate &= ~(BTN_NOSELECTION); view_check_buttons(); view_read_selected(w,mwin,xp); break; } } return; } #ifdef __STDC__ void view_read_selected(Widget w, MainWindow *mwin, XmListCallbackStruct *xp) #else void view_read_selected(w,mwin,xp) Widget w; MainWindow *mwin; XmListCallbackStruct *xp; #endif { int slider_value; if(mwin->current->num_selected) { XtVaGetValues(mwin->slider, XmNvalue, &slider_value, NULL); if(slider_value == 0) slider_value = 1; push_cursor(WATCH_CURSOR); read_messagelist(mwin, mwin->current, mwin->current->message_list, slider_value, FALSE); if(slider_value != 100) XtVaSetValues(mwin->slider, XmNvalue, 100, NULL); pop_cursor(); } return; } #ifdef __STDC__ void view_read_selected_newwin(Widget w, MainWindow *mwin, XmListCallbackStruct *xp) #else void view_read_selected_newwin(w,mwin,xp) Widget w; MainWindow *mwin; XmListCallbackStruct *xp; #endif { int slider_value; if(mwin->current->num_selected) { XtVaGetValues(mwin->slider, XmNvalue, &slider_value, NULL); if(slider_value == 0) slider_value = 1; push_cursor(WATCH_CURSOR); read_messagelist(mwin, mwin->current, mwin->current->message_list, slider_value, TRUE); if(slider_value != 100) XtVaSetValues(mwin->slider, XmNvalue, 100, NULL); pop_cursor(); } return; } #ifdef __STDC__ void view_next(Widget w, MainWindow *mwin, XtPointer xp) #else void view_next(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { if(mwin->current->next) view_context_switch(mwin,mwin->current,mwin->current->next); return; } #ifdef __STDC__ void view_prev(Widget w, MainWindow *mwin, XtPointer xp) #else void view_prev(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { if(mwin->current->prev) view_context_switch(mwin,mwin->current,mwin->current->prev); return; } #ifdef __STDC__ void view_expunge_messages(Widget w, MainWindow *mwin, XtPointer xp) #else void view_expunge_messages(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { push_cursor(WATCH_CURSOR); mail_expunge(mwin->current->mailstream); view_after_expunge(mwin); pop_cursor(); return; } #ifdef __STDC__ char *rep_to_sortstr(Representation_Type representation) #else char *rep_to_sortstr(representation) Representation_Type representation; #endif { return(Representation[representation].localized); } #ifdef __STDC__ Representation_Type sortstr_to_rep(char * sortstr) #else Representation_Type sortstr_to_rep(sortstr) char *sortstr; #endif { int i = 0; if(sortstr != NULL) { for(i = 0; Representation[i].name != NULL; i ++) if((strncasecmp(sortstr,Representation[i].localized, strlen(Representation[i].localized))) == STRMATCH) return(i); } return(i); } #ifdef __STDC__ void view_sort_reverse(Widget w, MainWindow *mwin, XtPointer xp) #else void view_sort_reverse(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *old, *new; if((mwin->current == NULL) || (mwin->current->filter == NULL) || (mwin->current->message_list == NULL)) return; push_cursor(WATCH_CURSOR); mwin->current->representation = REP_DESCENDING; old = mwin->current->message_list; new = sort_message_list(mwin->current->message_list, mwin->current->representation); update_lview_message_list(mwin,mwin->current,old, new, FALSE); pop_cursor(); return; } #ifdef __STDC__ void view_sort_size(Widget w, MainWindow *mwin, XtPointer xp) #else void view_sort_size(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *old, *new; if((mwin->current == NULL) || (mwin->current->filter == NULL) || (mwin->current->message_list == NULL)) return; push_cursor(WATCH_CURSOR); mwin->current->representation = REP_SORT_SIZE; old = mwin->current->message_list; new = sort_message_list(mwin->current->message_list, mwin->current->representation); update_lview_message_list(mwin,mwin->current,old, new, FALSE); pop_cursor(); return; } #ifdef __STDC__ void view_sort_normal(Widget w, MainWindow *mwin, XtPointer xp) #else void view_sort_normal(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *old, *new; if((mwin->current == NULL) || (mwin->current->filter == NULL) || (mwin->current->message_list == NULL)) return; push_cursor(WATCH_CURSOR); mwin->current->representation = REP_ASCENDING; old = mwin->current->message_list; new = sort_message_list(mwin->current->message_list, mwin->current->representation); update_lview_message_list(mwin,mwin->current,old,new, FALSE); pop_cursor(); return; } #ifdef __STDC__ void view_sort_subject(Widget w, MainWindow *mwin, XtPointer xp) #else void view_sort_subject(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *old, *new; if((mwin->current == NULL) || (mwin->current->filter == NULL) || (mwin->current->message_list == NULL)) return; push_cursor(WATCH_CURSOR); mwin->current->representation = REP_SORT_SUBJECT; old = mwin->current->message_list; new = sort_message_list(mwin->current->message_list, mwin->current->representation); update_lview_message_list(mwin,mwin->current,old,new, FALSE); pop_cursor(); return; } #ifdef __STDC__ void view_sort_sender(Widget w, MainWindow *mwin, XtPointer xp) #else void view_sort_sender(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *old, *new; if((mwin->current == NULL) || (mwin->current->filter == NULL) || (mwin->current->message_list == NULL)) return; push_cursor(WATCH_CURSOR); mwin->current->representation = REP_SORT_SENDER; old = mwin->current->message_list; new = sort_message_list(mwin->current->message_list, mwin->current->representation); update_lview_message_list(mwin,mwin->current,old,new,FALSE); pop_cursor(); return; } #ifdef __STDC__ void view_select_messages(Widget w, MainWindow *mwin, XtPointer xp) #else void view_select_messages(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *message_list; unsigned long selected = 0L; view_unselect_messages(w,mwin,xp); push_cursor(WATCH_CURSOR); XtVaSetValues(mwin->list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL); for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { XmListSelectPos(mwin->list,message_list->number,FALSE); message_list->selected = TRUE; selected ++; } XtVaSetValues(mwin->list, XmNselectionPolicy, XmEXTENDED_SELECT, NULL); mwin->current->num_selected = selected; if(selected > 0) mwin->current->buttonstate &= ~(BTN_NOSELECTION); else mwin->current->buttonstate |= BTN_NOSELECTION; view_check_buttons(); pop_cursor(); return; } #ifdef __STDC__ void view_unselect_messages(Widget w, MainWindow *mwin, XtPointer xp) #else void view_unselect_messages(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *message_list; push_cursor(WATCH_CURSOR); for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { XmListDeselectPos(mwin->list,message_list->number); message_list->selected = FALSE; } mwin->current->num_selected = 0L; mwin->current->buttonstate |= BTN_NOSELECTION; view_check_buttons(); pop_cursor(); return; } #ifdef __STDC__ void view_select_new_messages(Widget w, MainWindow *mwin, XtPointer xp) #else void view_select_new_messages(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *message_list; MESSAGECACHE *elt; unsigned long selected = 0L; view_unselect_messages(w,mwin,xp); push_cursor(WATCH_CURSOR); XtVaSetValues(mwin->list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL); for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { if((message_list->message == NULL) || (message_list->message->fetched == FALSE) || (message_list->message->longcache == NULL)) continue; elt = &(message_list->message->longcache->elt); if((elt) && (elt->recent) && (!elt->seen)) { XmListSelectPos(mwin->list,message_list->number,FALSE); message_list->selected = TRUE; selected ++; } } XtVaSetValues(mwin->list, XmNselectionPolicy, XmEXTENDED_SELECT, NULL); mwin->current->num_selected = selected; if(selected) mwin->current->buttonstate &= ~(BTN_NOSELECTION); else mwin->current->buttonstate |= BTN_NOSELECTION; view_check_buttons(); pop_cursor(); return; } #ifdef __STDC__ void view_select_unseen_messages(Widget w, MainWindow *mwin, XtPointer xp) #else void view_select_unseen_messages(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *message_list; MESSAGECACHE *elt; unsigned long selected = 0L; view_unselect_messages(w,mwin,xp); push_cursor(WATCH_CURSOR); XtVaSetValues(mwin->list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL); for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { if((message_list->message == NULL) || (message_list->message->fetched == FALSE) || (message_list->message->longcache == NULL)) continue; elt = &(message_list->message->longcache->elt); if((elt) && (!elt->seen)) { XmListSelectPos(mwin->list,message_list->number,FALSE); message_list->selected = TRUE; selected ++; } } XtVaSetValues(mwin->list, XmNselectionPolicy, XmEXTENDED_SELECT, NULL); mwin->current->num_selected = selected; if(selected) mwin->current->buttonstate &= ~(BTN_NOSELECTION); else mwin->current->buttonstate |= BTN_NOSELECTION; view_check_buttons(); pop_cursor(); return; } #ifdef __STDC__ void view_copy_dispatch(Widget w, MainWindow *mwin, Boolean move) #else void view_copy_dispatch(w,mwin,move) Widget w; MainWindow *mwin; Boolean move; #endif { extern STRINGDRIVER mail_string; STRING bs; char *ptr; Boolean changed = FALSE; char *sequence = NULL; char *mailbox_name = NULL; Message_List *message_list; Message_List *new_message_list = NULL; int result = NIL; if(mwin->current->scripting && mwin->current->script_arg) mailbox_name = fix_netmailboxpath(mwin->current->script_arg,&changed); if(mailbox_name == NULL) mailbox_name = get_mailbox_name(mwin->shell, (mwin->current->mailbox->host) ? mwin->current->mailbox->host : EMPTYSTR, &changed, &move); if(mailbox_name == NULL) { session->active = NULL; return; } if(*mailbox_name == NUL_TERM) { fs_give((void **) &mailbox_name); session->active = NULL; return; } push_cursor(WATCH_CURSOR); if(changed == FALSE) { sequence = generate_sequence(mwin->current); if(sequence && *sequence && *mailbox_name) result = mail_copy(mwin->current->mailstream, sequence, mailbox_name); if(result == T) { if(move) { mm_log(MLGetLocalized(XtNmsgMoveSuccess,MsgMoveSuccess), NIL); view_setflag(w,mwin, DELETED_FLAG); for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { if(message_list->selected == TRUE) update_view_line(mwin->current->mailbox, message_list->message); } } else mm_log(MLGetLocalized(XtNmsgCopySuccess,MsgCopySuccess), NIL); } else { if(move) mm_log(MLGetLocalized(XtNmsgMoveFail,MsgMoveFail), WARN); else mm_log(MLGetLocalized(XtNmsgCopyFail,MsgCopyFail), WARN); } } else { free_message_list(mwin->current->mailbox->found, TRUE, FALSE); mwin->current->mailbox->found = NULL; for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { if(message_list->selected == TRUE) mm_searched(message_list->message->mailstream, message_list->message->msgno); } new_message_list = sort_message_list(mwin->current->mailbox->found, REP_ASCENDING); mwin->current->mailbox->found = NULL; result = SYSCALL_SUCCESS; if(new_message_list) { for(message_list = new_message_list; message_list; message_list = message_list->next) { if(message_list->message) { result = copy_message_to_mailbox(message_list->message->mailstream, message_list->message->msgno, mailbox_name); if(result != SYSCALL_SUCCESS) break; } } if(result == SYSCALL_SUCCESS) { if(move) { view_setflag(w,mwin, DELETED_FLAG); for(message_list = new_message_list; message_list; message_list = message_list->next) update_view_line(mwin->current->mailbox, message_list->message); } mm_log((move) ? MLGetLocalized(XtNmsgMoveSuccess,MsgMoveSuccess) : MLGetLocalized(XtNmsgCopySuccess,MsgCopySuccess), NIL); } else mm_log((move) ? MLGetLocalized(XtNmsgMoveFail,MsgMoveFail) : MLGetLocalized(XtNmsgCopyFail,MsgCopyFail), WARN ); free_message_list(new_message_list, TRUE, FALSE); } } if(sequence) fs_give((void **) &sequence); fs_give((void **) &mailbox_name); session->active = NULL; pop_cursor(); return; } #ifdef __STDC__ void view_copy(Widget w, MainWindow *mwin, XtPointer xp) #else void view_copy(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_copy_dispatch(w, mwin, FALSE); return; } #ifdef __STDC__ void view_move(Widget w, MainWindow *mwin, XtPointer xp) #else void view_move(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_copy_dispatch(w, mwin, TRUE); return; } /* * To avoid excessive scrolling and flicker when we change context, * we grab a new list widget, load it up, and then change the old * one out from under the user. There's still a screen flash, but * that's life... */ #ifdef __STDC__ void view_context_switch(MainWindow *mwin, Lview *old, Lview *new) #else void view_context_switch(mwin,old,new) MainWindow *mwin; Lview *old; Lview *new; #endif { Dimension width, height; XtTranslations translations; char *new_title = NULL; Widget list, oldlist; unsigned long total = 0L; unsigned long highlighted = 0L; Message_List *message_list; char *act = NULL; XtVaGetValues(mwin->shell,XmNwidth,&width,XmNheight,&height,NULL); mwin->current = new; list = new_list_widget(mwin); if((old != NULL) && (old->filter != NULL)) { act = XmTextGetString(mwin->action); if(old->filter->action) fs_give((void **) &old->filter->action); old->filter->action = act; } if(new != NULL) { if(new->title) { new_title = (char *) fs_get(strlen(new->title) + 64); sprintf(new_title,"%s (%s)", new->title, Representation[new->representation].localized); XtVaSetValues(mwin->shell,XmNtitle,new_title,NULL); fs_give((void **) &new_title); } if((new->filter) && (new->filter->action)) XmTextSetString(mwin->action,new->filter->action); else XmTextSetString(mwin->action,preferences.default_action); XtVaSetValues(list,XmNselectionPolicy,XmMULTIPLE_SELECT,NULL); for(message_list = new->message_list; message_list; message_list = message_list->next) { if(message_list->message) { XmListAddItemUnselected(list,message_list->message->viewline,0); message_list->number = (++total); if(message_list->selected) { XmListSelectPos(list,message_list->number, FALSE); highlighted ++; } } } XtVaSetValues(list,XmNselectionPolicy,XmEXTENDED_SELECT,NULL); new->num_selected = highlighted; if(new->representation == REP_ASCENDING || new->representation == REP_SORT_SIZE) XmListSetBottomPos(list, new->count); else XmListSetBottomPos(list,1); if(highlighted != 0L) new->buttonstate &= ~(BTN_NOSELECTION); else new->buttonstate |= BTN_NOSELECTION; view_check_buttons(); } else { /* No more open mailboxes. */ XtVaSetValues(mwin->shell,XmNtitle,PROGRAM,NULL); XmTextSetString(mwin->action,EMPTYSTR); view_check_buttons(); mwin->lview = NULL; } translations = XtParseTranslationTable(GLOBAL_lview_pop_translations); XtOverrideTranslations(list,translations); oldlist = mwin->list; XtUnmanageChild(oldlist); mwin->list = list; XtManageChild(list); XtVaSetValues(mwin->shell,XmNwidth,width,XmNheight,height,NULL); XtDestroyWidget(oldlist); return; } /* * Called when we are going to close a mailbox, and we need to * destroy the current lview. Since any other views of this mailbox * are going away, we can't use them. This finds a view unrelated * to this mailbox or else NULL. It's safe to context switch to * another mailbox. */ #ifdef __STDC__ Lview *find_lview_another_mailbox(MainWindow *mwin,Mailbox *mailbox) #else Lview *find_lview_another_mailbox(mwin,mailbox) MainWindow *mwin; Mailbox *mailbox; #endif { Lview *lview = NULL; for(lview = mwin->lview; lview; lview = lview->prev) { if(lview->mailbox != mailbox) return(lview); } return(NULL); } #ifdef __STDC__ void mwin_close_mailbox(Mailbox *mailbox) #else void mwin_close_mailbox(mailbox) Mailbox *mailbox; #endif { Lview *lview; Boolean found = FALSE; MainWindow *mwin = find_main_window(mailbox); if(! mwin) return; do { found = FALSE; for(lview = mwin->lview; lview; lview = lview->prev) if(lview->mailstream == mailbox->mailstream) { found = TRUE; view_unlink_destroy_lview(mwin,lview,TRUE); break; } } while(found == TRUE); if(mwin->lview == NULL) { if(! mwin->is_main) { XtPopdown(mwin->shell); mwin->destroyed = TRUE; if(mwin->listwin->is_realized) XtPopdown(mwin->listwin->shell); } } return; } #ifdef __STDC__ void view_unlink_destroy_lview(MainWindow *mwin,Lview *lview,Boolean closing) #else void view_unlink_destroy_lview(mwin,lview,closing) MainWindow *mwin; Lview *lview; Boolean closing; #endif { Lview *curr = NULL; Lview *next_view = NULL; /* First reparent any orphans we might make */ if((closing == FALSE) && (lview->filter != NULL) && (lview->filter->filter_type != FILTER_TYPE_ALL)) { for(curr = mwin->lview; curr; curr = curr->prev) { if((curr->mailstream == lview->mailstream) && (curr->parent == lview)) curr->parent = lview->parent; } for(curr = mwin->lview; curr; curr = curr->prev) { if((curr->parent != NULL) && (curr->level != (curr->parent->level + 1))) curr->level --; } } read_lview_detach(lview); /* Extract this sucker from mwin->lview */ if(mwin->lview == lview) mwin->lview = lview->prev; if(lview->prev) { lview->prev->next = lview->next; if(lview->next) lview->prev->buttonstate &= ~(BTN_NONEXT); else lview->prev->buttonstate |= BTN_NONEXT; } if(lview->next) { lview->next->prev = lview->prev; if(lview->prev) lview->next->buttonstate &= ~(BTN_NOPREV); else lview->next->buttonstate |= BTN_NOPREV; } if(lview->filter && lview->filter->filter_type == FILTER_TYPE_ALL) free_message_list(lview->message_list,TRUE,TRUE); else free_message_list(lview->message_list,TRUE,FALSE); free_filter(lview->filter); if(lview == mwin->current) { if(closing) next_view = find_lview_another_mailbox(mwin,lview->mailbox); else { if(lview->prev) next_view = lview->prev; else if(lview->next) next_view = lview->next; } view_context_switch(mwin, NULL, next_view); } stuff_lview_list(mwin,TRUE,closing); free_lview(lview); lview = NULL; return; } /* Returns the "ALL" lview (main mailbox) for a particular mailstream */ #ifdef __STDC__ Lview *get_all_lview(MAILSTREAM *mailstream) #else Lview *get_all_lview(mailstream) MAILSTREAM *mailstream; #endif { MainWindow *mwin; Lview *lview; for(mwin = session->mwin; mwin; mwin = mwin->next) for(lview = mwin->lview; lview ; lview = lview->prev) if((lview->mailstream == mailstream) && (lview->filter) && (lview->filter->filter_type == FILTER_TYPE_ALL)) return(lview); return(NULL); } /* Returns the "UNFILTERED" lview for a particular mailstream */ #ifdef __STDC__ Lview *get_bucket_lview(MAILSTREAM *mailstream) #else Lview *get_bucket_lview(mailstream) MAILSTREAM *mailstream; #endif { MainWindow *mwin; Lview *lview; for(mwin = session->mwin; mwin; mwin = mwin->next) for(lview = mwin->lview; lview ; lview = lview->prev) if((lview->mailstream == mailstream) && (lview->filter) && (lview->filter->filter_type == FILTER_TYPE_BUCKET)) return(lview); return(NULL); } #ifdef __STDC__ void load_default_filters(MainWindow *mwin,Lview *lview,Filter_Map *filter_map) #else void load_default_filters(mwin,lview,filter_map) MainWindow *mwin; Lview *lview; Filter_Map *filter_map; #endif { FILE *fp; Boolean found = FALSE; char buf[FILEBUFFLEN]; char pname[FILEBUFFLEN]; char *name; int level; char *parent_name; char *ptr; Lview *our_lview; Lview *parent_lview; Lview *pptr; Filter *our_filter; Filter *curr_filter; parse_errors errors; char *temp_txt; char errmsg[FILEBUFFLEN]; mm_log(MLGetLocalized(XtNmsgLoadingFilters,MsgLoadingFilters), NIL); if((fp = fopen(filter_map->filename,"r")) == NULL) { return; } /* * parse the filter map file. * filter_name [SP] level [SP] parent_name ( [SP] parent_name ) [LF] */ while(fgets(buf,sizeof(buf),fp)) { buf[strlen(buf) - 1] = NUL_TERM; name = buf; ptr = strchr(buf,SPACECHAR); if(ptr == NULL) continue; *ptr = NUL_TERM; ptr ++; level = atoi(ptr); if(level == 0) continue; parent_name = strchr(ptr,SPACECHAR); if(parent_name == NULL) continue; parent_name ++; for(curr_filter = session->filters; curr_filter; curr_filter = curr_filter->next) { /* find requested filter */ if(strcmp(curr_filter->name,name) == STRMATCH) break; } if(curr_filter == NULL) continue; /* find the (active) parent */ for(parent_lview = mwin->lview; parent_lview; parent_lview = parent_lview->prev) { if(parent_lview->mailstream != lview->mailstream) continue; if(parent_lview->level != (level - 1)) continue; if(parent_lview->filter == NULL) continue; *pname = NUL_TERM; for(pptr = parent_lview, found = FALSE; pptr; pptr = pptr->parent) { if(pptr->filter && pptr->filter->name) { if(found) strcat(pname,SPACESTR); found = TRUE; strcat(pname,pptr->filter->name); } if(pptr->filter && pptr->filter->filter_type == FILTER_TYPE_ALL) break; } if((*pname != NUL_TERM) && ((strcmp(pname,parent_name)) == STRMATCH)) break; } /* no parent found */ if(parent_lview == NULL) continue; /* we have a parent -- now see if the filter parses */ our_filter = new_filter(); our_filter->filter_type = FILTER_TYPE_USER; our_filter->representation = curr_filter->representation; our_filter->name = cpystr(curr_filter->name); temp_txt = cpystr(curr_filter->text); our_filter->action = cpystr(curr_filter->action); errors = lv_parse_filter(our_filter->name,temp_txt, (LEAF **) &our_filter->search_tree, &our_filter->text, errmsg); fs_give((void **) &temp_txt); if(errors != parse_success) { free_filter(our_filter); mm_log(errmsg,WARN); continue; } our_lview = new_lview(); our_lview->filter = our_filter; our_lview->parent = parent_lview; our_lview->level = level; create_lview(mwin,our_lview,TRUE); } fclose(fp); update_logical_views(lview->mailbox,FALSE); view_check_buttons(); return; } #ifdef __STDC__ void attach_session_filters(Lview *lview) #else void attach_session_filters(lview) Lview *lview; #endif { #if 0 Lview *our_lview; Lview *parent_lview; Filter *our_filter; Filter *curr_filter; parse_errors errors; char *temp_txt; char errmsg[FILEBUFFLEN]; if(session->session_filters == NULL) return; mm_log(MLGetLocalized(XtNmsgAttachingFilters,MsgAttachingFilters),NIL); for(curr_filter = session->session_filters; curr_filter; curr_filter = curr_filter->next) { our_filter = new_filter(); our_filter->filter_type = FILTER_TYPE_ONESHOT; our_filter->name = cpystr(curr_filter->name); temp_txt = cpystr(curr_filter->text); our_filter->action = cpystr(curr_filter->action); errors = lv_parse_filter(our_filter->name,temp_txt, (LEAF **) &our_filter->search_tree, &our_filter->text, errmsg); fs_give((void **) &temp_txt); our_lview = new_lview(); our_lview->filter = our_filter; our_lview->parent = lview; our_lview->level = lview->level + 1; create_lview(our_lview,TRUE); } update_logical_views(lview->mailbox,TRUE); view_context_switch(mwin, mwin->current, our_lview); #endif return; } #ifdef __STDC__ void create_lview(MainWindow *mwin,Lview *lview, Boolean batch) #else void create_lview(mwin,lview, batch) MainWindow *mwin; Lview *lview; Boolean batch; #endif { char buffer[FILEBUFFLEN]; char *fixedname; Mailbox *mailbox; Lview *parent; Lview *bucket; Filter *filter; push_cursor(WATCH_CURSOR); if(! mwin->current) { pop_cursor(); return; } mailbox = mwin->current->mailbox; lview->mailstream = mailbox->mailstream; lview->mailbox = mailbox; if(((bucket = get_bucket_lview(mailbox->mailstream)) == NULL) && lview->filter && lview->filter->filter_type == FILTER_TYPE_USER) { /* create the "UNFILTERED" view */ filter = new_filter(); filter->name = cpystr(MLGetLocalized(XtNstrBucket,StrBucket)); filter->action = cpystr(preferences.default_action); filter->filter_type = FILTER_TYPE_BUCKET; bucket = new_lview(); bucket->parent = get_all_lview(mailbox->mailstream); bucket->level = 1; bucket->mailstream = mailbox->mailstream; bucket->mailbox = mailbox; bucket->filter = filter; if(mailbox->type == MAILBOX_TYPE_NEWS) filter->representation = sortstr_to_rep(preferences.news_sort); else filter->representation = sortstr_to_rep(preferences.mail_sort); bucket->representation = filter->representation; filter->mailboxname = cpystr(mailbox->imapname); fixedname = unfix_mailboxpath(mailbox->mailboxname); sprintf(buffer,"[%d]%s%s%s[%s]", mwin->serialno, (mailbox->host) ? mailbox->host : EMPTYSTR, (mailbox->host) ? ":" : EMPTYSTR, fixedname, filter->name); fs_give((void **) &fixedname); bucket->title = cpystr(buffer); if(mailbox->type == MAILBOX_TYPE_NEWS) bucket->buttonstate |= BTN_ISNEWS; else bucket->buttonstate |= BTN_ISMAIL; for(parent = mwin->lview; parent; parent = parent->prev) { if(parent == bucket->parent) break; } if(parent) { bucket->next = parent; bucket->prev = parent->prev; parent->prev = bucket; parent->buttonstate &= ~(BTN_NOPREV); if(bucket->prev) { bucket->buttonstate &= ~(BTN_NOPREV); bucket->prev->next = bucket; bucket->prev->buttonstate &= ~(BTN_NONEXT); } else bucket->buttonstate |= BTN_NOPREV; bucket->buttonstate &= ~(BTN_NONEXT); } else mm_log(MLGetLocalized(XtNmsgNoParentView,MsgNoParentView), ERROR); } lview->filter->mailboxname = cpystr(mailbox->imapname); fixedname = unfix_mailboxpath(mailbox->mailboxname); sprintf(buffer,"[%d]%s%s%s[%s]", mwin->serialno, (mailbox->host) ? mailbox->host : EMPTYSTR, (mailbox->host && *mailbox->host) ? ":" : EMPTYSTR, fixedname, lview->filter->name); fs_give((void **) &fixedname); lview->title = cpystr(buffer); lview->representation = lview->filter->representation; /* * Link into our structure beneath the parent. We should always * have a parent. session->->lview is ordered in reverse. * (Everything is "prev" to the root node). */ if(mailbox->type == MAILBOX_TYPE_NEWS) lview->buttonstate |= BTN_ISNEWS; else lview->buttonstate |= BTN_ISMAIL; for(parent = mwin->lview; parent; parent = parent->prev) { if(parent == lview->parent) break; } if(parent) { lview->next = parent; lview->prev = parent->prev; parent->prev = lview; parent->buttonstate &= ~(BTN_NOPREV); if(lview->prev) { lview->buttonstate &= ~(BTN_NOPREV); lview->prev->next = lview; lview->prev->buttonstate &= ~(BTN_NONEXT); } else lview->buttonstate |= BTN_NOPREV; lview->buttonstate &= ~(BTN_NONEXT); } else mm_log(MLGetLocalized(XtNmsgNoParentView,MsgNoParentView), ERROR); /* * If we're running in "batch" mode, there could be several filters * to attach. The caller has promised to update the logical views * when it's done attaching everything it needs. This avoids lengthy * (steadily increasing) delays as the number of filters is growing; * and it also avoids excessive flicker. Set batch to false if there's * only one filter to attach. Everything will be updated and sorted for * you when this function returns. */ if(batch == FALSE) { update_logical_views(mailbox,TRUE); view_context_switch(mwin, mwin->current, lview); } pop_cursor(); return; } /* * Creates a main mailbox ("ALL" lview) and loads * its message info. */ #ifdef __STDC__ void create_all_lview(MainWindow *mwin,Mailbox *mailbox) #else void create_all_lview(mwin,mailbox) MainWindow *mwin; Mailbox *mailbox; #endif { Lview *lview; Filter *filter; Filter_Map *filter_map; Message_List *old, *new; char buffer[FILEBUFFLEN]; char *fixedname; if(! mwin) return; push_cursor(WATCH_CURSOR); /* * "ALL" is just another logical view except it has a few * special properties. It ALWAYS holds a message structure * for each message in the mailbox. So whenever mailbox changes * occur, we update this view to guarantee that it stays consistent * with the server's representation. We then derive other logical * views from it. We also don't put any special meaning on the name * "ALL". We set the filter_type to FILTER_TYPE_ALL instead, and * use a combination of the filter_type and either the mailstream or * mailbox to absolutely identify it. */ lview = new_lview(); lview->mailstream = mailbox->mailstream; lview->mailbox = mailbox; lview->count = mailbox->nmsgs; filter = new_filter(); filter->mailboxname = cpystr(mailbox->imapname); filter->name = cpystr(MLGetLocalized(XtNstrAll, StrAll)); filter->filter_type = FILTER_TYPE_ALL; if(mailbox->type == MAILBOX_TYPE_NEWS) filter->representation = sortstr_to_rep(preferences.news_sort); else filter->representation = sortstr_to_rep(preferences.mail_sort); lview->filter = filter; lview->representation = filter->representation; fixedname = unfix_mailboxpath(mailbox->mailboxname); sprintf(buffer,"[%d]%s%s%s[%s]", mwin->serialno, (mailbox->host) ? mailbox->host : EMPTYSTR, (mailbox->host && *mailbox->host) ? ":" : EMPTYSTR, fixedname, filter->name); fs_give((void **) &fixedname); lview->title = cpystr(buffer); lview->next = NULL; lview->buttonstate |= BTN_NONEXT; if(mwin->lview) { lview->prev = mwin->lview; lview->buttonstate &= ~(BTN_NOPREV); mwin->lview->next = lview; mwin->lview->buttonstate &= ~(BTN_NONEXT); } else { lview->buttonstate |= BTN_NOPREV; lview->prev = NULL; } if(mailbox->type == MAILBOX_TYPE_NEWS) lview->buttonstate |= BTN_ISNEWS; else lview->buttonstate |= BTN_ISMAIL; lview->buttonstate |= BTN_ISALL; mwin->lview = lview; if(mailbox->ispop) { check_mailbox(mailbox,TRUE); lview->count = mailbox->nmsgs; } fast_fetch_message_info(mailbox,lview); lview->has_new = has_new_messages(lview,TRUE); old = lview->message_list; new = sort_message_list(lview->message_list,lview->representation); update_lview_message_list(mwin,lview,old,new,FALSE); view_context_switch(mwin, mwin->current, lview); /* * If there are any saved active filters for this mailbox, load them * at this time. */ if((filter_map = get_filter_map(lview)) != NULL) load_default_filters(mwin,lview,filter_map); attach_session_filters(lview); stuff_lview_list(mwin,TRUE, FALSE); pop_cursor(); return; } /* * Called from the c-client when a (single) message is expunged. * We go through this in distinct steps. First, remove the message * from the "ALL" view (main mailbox), but !!DON'T!! yet free the message. * We need to check it against all our views for this mailbox. Decrement * any higher message numbers in the message structures we encounter in * this view by one. Once that's accomplished, we go through all our * logical views for this mailbox and unlink any message_list structures * which contain the expunged message. We can free these message_list * structures at this point, but we still don't free the message itself. * The final act is to destroy the message structure itself once all of * its references have been eliminated. * Since expunge is always initiated by us, when we perform the act, * we follow up by calling the view_after_expunge() procedure to update * the visuals. This takes care of all the highlighting stuff, and * avoids excessive flicker if we are expunging several messages. */ #ifdef __STDC__ void view_expunge(MAILSTREAM *mailstream,unsigned long msgno) #else void view_expunge(mailstream,msgno) MAILSTREAM *mailstream; unsigned long msgno; #endif { MainWindow *mwin; Boolean found_it = FALSE; Lview *lview; Message_List *message_list; Message_List *dead_message_list = NULL; unsigned long x = 1L; lview = get_all_lview(mailstream); if(! lview) return; found_it = FALSE; for(message_list = lview->message_list; message_list; message_list = message_list->next) { if(message_list->message == NULL) continue; if(message_list->message->msgno == msgno) { found_it = TRUE; dead_message_list = message_list; if(lview->count) lview->count --; if((message_list->selected == TRUE) && (lview->num_selected > 0L)) { lview->num_selected --; if(lview->num_selected == 0L) lview->buttonstate |= BTN_NOSELECTION; } if(message_list->next) message_list->next->prev = message_list->prev; if(message_list->prev) message_list->prev->next = message_list->next; else lview->message_list = message_list->next; } if(message_list->message->msgno > msgno) message_list->message->msgno --; } /* * Yes, we could have done this while we were running through but it * complicates the logic. I'll probably work that in at some point, * because this could cause delays on a huge mailbox. */ for(message_list = lview->message_list; message_list; message_list = message_list->next) { message_list->number = x; x ++; } lview->has_new = has_new_messages(lview,FALSE); if(found_it == FALSE) /* shouldn't happen */ return; /* Update any other lviews attached to this stream. */ for(mwin = session->mwin; mwin; mwin = mwin->next) { for(lview = mwin->lview; lview; lview = lview->prev) { if(lview->mailstream != mailstream) continue; if(lview->filter && lview->filter->filter_type == FILTER_TYPE_ALL) continue; /* already got this guy */ do { found_it = FALSE; for(message_list = lview->message_list; message_list; message_list = message_list->next) { if(message_list->message == NULL) continue; if(message_list->message == dead_message_list->message) { found_it = TRUE; if(lview->count) lview->count --; if((message_list->selected == TRUE) && (lview->num_selected > 0L)) { lview->num_selected --; if(lview->num_selected == 0L) lview->buttonstate |= BTN_NOSELECTION; } if(message_list->next) message_list->next->prev = message_list->prev; if(message_list->prev) message_list->prev->next = message_list->next; else lview->message_list = message_list->next; free_message_list(message_list,FALSE,FALSE); break; } } } while (found_it == TRUE); lview->has_new = has_new_messages(lview,FALSE); x = 1L; for(message_list = lview->message_list; message_list; message_list = message_list->next) { message_list->number = x; x ++; } } } free_message_list(dead_message_list,FALSE,TRUE); return; } #ifdef __STDC__ void view_after_expunge(MainWindow *mwin) #else void view_after_expunge(mwin) MainWindow *mwin; #endif { read_after_expunge(); view_context_switch(mwin,mwin->current,mwin->current); stuff_lview_list(mwin,TRUE,FALSE); return; } #ifdef __STDC__ void view_close_mailbox(Widget w, MainWindow *mwin, XtPointer xp) #else void view_close_mailbox(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Mailbox *mailbox, *next; for(mailbox = session->mailboxes; mailbox ; mailbox = next) { next = mailbox->next; if((mwin->current) && (mailbox->mailstream != mwin->current->mailstream)) continue; close_mailbox(mailbox); break; } return; } #ifdef __STDC__ void view_no_update(Widget w, MainWindow *mwin, XtPointer xp) #else void view_no_update(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { if(mwin && mwin->current && mwin->current->mailbox) mwin->current->mailbox->no_update = TRUE; return; } #ifdef __STDC__ void view_lview_window(Widget w, MainWindow *mwin, XtPointer xp) #else void view_lview_window(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Arg args[ARGLISTSIZE]; char buffer[FILEBUFFLEN]; int n = 0; XtTranslations translations; Widget form, menubar, dummy; if(mwin->listwin->is_realized == TRUE) { de_iconify(mwin->listwin->shell); return; } sprintf(buffer,"[%d] %s",mwin->serialno,MLGetLocalized(XtNstrLogicalViews, StrLogicalViews)); XtSetArg(args[n], XmNtitle, buffer); n ++; XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n ++; XtSetArg(args[n], XmNx, -1000); n ++; XtSetArg(args[n], XmNy, -1000); n ++; mwin->listwin->shell = XtCreatePopupShell("lview", topLevelShellWidgetClass, mwin->shell, args, n); n = 0; AddDestroyCallback (mwin->listwin->shell); setup_editres(mwin->listwin->shell); if(list_icon != (Pixmap) None) XtVaSetValues(mwin->listwin->shell, XmNiconPixmap,list_icon, NULL); form = XmCreateForm(mwin->listwin->shell, "form", args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++; menubar = XmCreateMenuBar(form,"menubar", args, n); n = 0; XtManageChild(menubar); create_buttons(NULL, menubar,view_lview_menu, XtNumber(view_lview_menu), BTN_ON, (XtPointer) mwin, ROOTMENULEVEL); /* * An invisible text field. This is used only to set the window * width, since the list widget living under the form can change * size otherwise, depending only on its contents. */ XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++; dummy = XmCreateTextField(form,"dummy", args, n); n = 0; XtManageChild(dummy); XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++; XtSetArg(args[n], XmNtopWidget, menubar); n ++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++; XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n ++; XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); n ++; XtSetArg(args[n], XmNselectionPolicy, XmSINGLE_SELECT); n ++; mwin->listwin->list = XmCreateScrolledList(form,"list",args,n); n = 0; XtAddCallback(mwin->listwin->list, XmNsingleSelectionCallback, (XtCallbackProc) view_lview_select, mwin); XtAddCallback(mwin->listwin->list, XmNdefaultActionCallback, (XtCallbackProc) view_lview_accept, mwin); translations = XtParseTranslationTable(GLOBAL_lview_pop_translations); XtOverrideTranslations(mwin->listwin->list,translations); XtAddCallback(mwin->listwin->shell, XmNpopdownCallback, (XtCallbackProc) view_lview_destroy, mwin); stuff_lview_list(mwin,FALSE,FALSE); XtManageChild(mwin->listwin->list); XtManageChild(form); XtManageChild(mwin->listwin->shell); position_popup_widget(mwin->listwin->shell, FALSE); XtPopup(mwin->listwin->shell, XtGrabNone); mwin->listwin->is_realized = TRUE; return; } #ifdef __STDC__ void view_lview_save(Widget w, MainWindow *mwin, XtPointer xp) #else void view_lview_save(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { FILE *fp; Lview *lview; Lview *current; Filter_Map *filter_map; char log[MAXPATHLEN + 128]; Lview *pptr; push_cursor(WATCH_CURSOR); for(current = mwin->lview; current; current = current->prev) { if((current->filter == NULL) || (current->filter->filter_type != FILTER_TYPE_ALL)) continue; filter_map = get_filter_map(current); if(filter_map == NULL) filter_map = generate_filter_map(current); if((fp = fopen(filter_map->filename,"w")) == NULL) { sprintf(log,MLGetLocalized(XtNmsgCannotWriteFile,MsgCannotWriteFile), filter_map->filename); mm_log(log,WARN); pop_cursor(); continue; } (void) chmod(filter_map->filename,S_IRWXU); for(lview = current->prev; lview; lview = lview->prev) { if(lview->filter == NULL) continue; if(lview->filter->filter_type == FILTER_TYPE_ALL) { fclose(fp); break; } if(lview->filter->filter_type != FILTER_TYPE_USER) continue; if((lview->parent == NULL) || (lview->parent->filter == NULL) || (lview->parent->filter->name == NULL)) continue; fprintf(fp,"%s %d", lview->filter->name, lview->level); pptr = lview->parent; for(pptr = lview->parent; pptr; pptr = pptr->parent) { fprintf(fp," %s",(pptr->filter && pptr->filter->name) ? pptr->filter->name : SPACESTR); if(pptr->filter && pptr->filter->filter_type == FILTER_TYPE_ALL) break; } fprintf(fp,"\n"); } fclose(fp); } pop_cursor(); return; } #ifdef __STDC__ void view_lview_select(Widget w, MainWindow *mwin, XmListCallbackStruct *xp) #else void view_lview_select(w,mwin,xp) Widget w; MainWindow *mwin; XmListCallbackStruct *xp; #endif { Lview *lview; for(lview = mwin->lview; lview; lview = lview->prev) { if(lview->number == xp->item_position) { if(lview->selected == FALSE) { lview->selected = TRUE; view_context_switch(mwin,mwin->current,lview); de_iconify(mwin->shell); } else XmListSelectPos(mwin->listwin->list,xp->item_position, FALSE); } else lview->selected = FALSE; } return; } #ifdef __STDC__ void view_lview_accept(Widget w, MainWindow *mwin, XmListCallbackStruct *xp) #else void view_lview_accept(w,mwin,xp) Widget w; MainWindow *mwin; XmListCallbackStruct *xp; #endif { return; } #ifdef __STDC__ void view_lview_hide(Widget w, MainWindow *mwin, XtPointer xp) #else void view_lview_hide(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { if(mwin->listwin->hide_empty == TRUE) mwin->listwin->hide_empty = FALSE; else mwin->listwin->hide_empty = TRUE; stuff_lview_list(mwin,TRUE,FALSE); return; } #ifdef __STDC__ void view_lview_detach(Widget w, MainWindow *mwin, XtPointer xp) #else void view_lview_detach(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Lview *lview; Filter *filter, *session_filter; Boolean found = FALSE; for(lview = mwin->lview; lview; lview = lview->prev) { if(lview->selected == TRUE) { /* * Annoying, but we have to make the lview we want * to detach the ``current'' lview. We might get some update * flicker as it gets switched in, and then immediately * switched out again. That's life. "view_close_mailbox()" * and "view_unlink_destroy_lview()" operate on the assumption * that the current lview is the target. */ view_context_switch(mwin,mwin->current,lview); break; } } if(! lview) return; if(lview->filter && lview->filter->filter_type == FILTER_TYPE_ALL) view_close_mailbox(w,mwin,xp); else view_unlink_destroy_lview(mwin,lview,FALSE); return; } #ifdef __STDC__ void view_lview_dismiss(Widget w, MainWindow *mwin, XtPointer xp) #else void view_lview_dismiss(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Lview *lview; /* for(lview = mwin->lview; lview; lview = lview->prev) * if(lview->selected == TRUE) * lview->selected = FALSE; */ XtRemoveCallback(mwin->listwin->shell, XmNpopdownCallback, (XtCallbackProc) view_lview_destroy, mwin); XtPopdown(mwin->listwin->shell); XtDestroyWidget(mwin->listwin->shell); mwin->listwin->is_realized = FALSE; return; } #ifdef __STDC__ void view_lview_destroy(Widget w, MainWindow *mwin, XtPointer xp) #else void view_lview_destroy(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Lview *lview; for(lview = mwin->lview; lview; lview = lview->prev) if(lview->selected == TRUE) lview->selected = FALSE; XtDestroyWidget(mwin->listwin->shell); mwin->listwin->is_realized = FALSE; return; } #ifdef __STDC__ void view_lview_help(Widget w, MainWindow *mwin, XtPointer xp) #else void view_lview_help(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { help(mwin->listwin->shell, VIEWLISTHELPFILE); return; } /* * Stuff the view selector window. Update is set to false to stuff * it the first time around. Thereafter, it is always called with * update set to true, in order to refresh the contents. The closing * flag means to not check the new message status, since the message cache * structures might be bogus at that point. It will just go on prior * knowledge which should still be accurate. */ #ifdef __STDC__ void stuff_lview_list(MainWindow *mwin, Boolean update, Boolean closing) #else void stuff_lview_list(mwin, update, closing) MainWindow *mwin; Boolean update; Boolean closing; #endif { Lview *lview; int n = 1; int level = 0; char buffer[FILEBUFFLEN]; int spaces; char *fixed_name = NULL; int font_type = 0; XmString xstr; if(session == NULL || mwin == NULL) return; if(update) { if(mwin->listwin->is_realized == FALSE) return; XmListDeselectAllItems(mwin->listwin->list); XmListDeleteAllItems(mwin->listwin->list); } for(lview = mwin->lview; lview; lview = lview->prev) { if(closing != TRUE) lview->has_new = has_new_messages(lview,FALSE); font_type = 0; /* Always show "ALL", even if empty */ if((lview->filter != NULL) && (lview->filter->filter_type != FILTER_TYPE_ALL)) { if((mwin->listwin->hide_empty == TRUE) && (lview->count == 0L)) { lview->number = 0; lview->selected = FALSE; continue; } } lview->number = n; lview->selected = FALSE; buffer[0] = NUL_TERM; sprintf(buffer,"%6lu ",lview->count); if((lview->filter) && (lview->filter->filter_type == FILTER_TYPE_ONESHOT)) font_type += 2; if(lview->has_new) font_type += 1; for(level = 0; level < lview->level; level ++) strcat(buffer,">"); if(lview->level) strcat(buffer," "); strcat(buffer,lview->filter->name); for(spaces = strlen(buffer); spaces < 30; spaces ++) strcat(buffer,SPACESTR); if((lview->mailbox != NULL) && (lview->mailbox->host != NULL) && (*lview->mailbox->host != NUL_TERM)) { strcat(buffer,lview->mailbox->host); strcat(buffer,":"); } if(lview->mailbox && lview->mailbox->mailboxname) fixed_name = unfix_mailboxpath(lview->mailbox->mailboxname); if(fixed_name) { strcat(buffer,fixed_name); fs_give((void **) &fixed_name); } else strcat(buffer,EMPTYSTR); switch(font_type) { case 1: xstr = XmStringCreate(buffer, "BOLD"); break; case 2: xstr = XmStringCreate(buffer, "ITALIC"); break; case 3: xstr = XmStringCreate(buffer, "BOLD_ITALIC"); break; case 0: default: xstr = XmStringCreate(buffer, "NORMAL"); break; } XmListAddItemUnselected(mwin->listwin->list,xstr,0); if(lview == mwin->current) { XmListSelectPos(mwin->listwin->list,n,FALSE); lview->selected = TRUE; } XmStringFree(xstr); n ++; } return; } #ifdef __STDC__ char *view_fetch(Message *message,Header_Mode header_mode) #else char *view_fetch(message,header_mode) Message *message; Header_Mode header_mode; #endif { char *mail_header = NULL; char *header = NULL; char *mail_text = NULL; char *everything; if((message == NULL) || (message->mailstream == NULL) || (message->msgno == 0L)) return(NULL); mail_header = cpystr(mail_fetchheader(message->mailstream,message->msgno)); stripcr(mail_header); if(mail_header[strlen(mail_header) - 1] == LFCHAR) mail_header[strlen(mail_header) - 1] = NUL_TERM; if(header_mode == HEADER_FULL) header = cpystr(mail_header); if(header_mode == HEADER_PART) header = get_short_header(mail_header); if(header == NULL) header = cpystr(EMPTYSTR); mail_text = cpystr(mail_fetchtext(message->mailstream,message->msgno)); stripcr(mail_text); everything = (char *) fs_get(strlen(header) + strlen(mail_text) + 8); strcpy(everything,header); if(*header != NUL_TERM) strcat(everything,LFSTR); strcat(everything,mail_text); fs_give((void **) &mail_header); fs_give((void **) &header); fs_give((void **) &mail_text); return(everything); } #ifdef __STDC__ void view_printfull(Widget w, MainWindow *mwin, XtPointer xp) #else void view_printfull(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_print_dispatch(w,mwin,HEADER_FULL); return; } #ifdef __STDC__ void view_printpart(Widget w, MainWindow *mwin, XtPointer xp) #else void view_printpart(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_print_dispatch(w,mwin,HEADER_PART); return; } #ifdef __STDC__ void view_printnone(Widget w, MainWindow *mwin, XtPointer xp) #else void view_printnone(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_print_dispatch(w,mwin,HEADER_NONE); return; } #ifdef __STDC__ void view_print_dispatch(Widget w,MainWindow *mwin,Header_Mode header_mode) #else void view_print_dispatch(w,mwin,header_mode) Widget w; MainWindow *mwin; Header_Mode header_mode; #endif { Message_List *message_list; char *contents; int errors = 0; if(*preferences.print_command == NUL_TERM) { mm_log(MLGetLocalized(XtNmsgNoPrintCommand,MsgNoPrintCommand), WARN); return; } push_cursor(WATCH_CURSOR); for(message_list = mwin->current->message_list; message_list; message_list = message_list->next ) { if(message_list->selected) { contents = view_fetch(message_list->message, (mwin->current->scripting) ? mwin->current->script_header : header_mode); if(! contents) continue; if(write_to_pipe(preferences.print_command, NULL, contents, strlen(contents))) errors ++; fs_give((void **) &contents); } } if(errors) mm_log(MLGetLocalized(XtNmsgPrintFail,MsgPrintFail), WARN); else mm_log(MLGetLocalized(XtNmsgPrintSuccess,MsgPrintSuccess), NIL); pop_cursor(); return; } #ifdef __STDC__ void view_execfull(Widget w, MainWindow *mwin, XtPointer xp) #else void view_execfull(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_exec_dispatch(w,mwin,HEADER_FULL); return; } #ifdef __STDC__ void view_execpart(Widget w, MainWindow *mwin, XtPointer xp) #else void view_execpart(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_exec_dispatch(w,mwin,HEADER_PART); return; } #ifdef __STDC__ void view_execnone(Widget w, MainWindow *mwin, XtPointer xp) #else void view_execnone(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_exec_dispatch(w,mwin,HEADER_NONE); return; } #ifdef __STDC__ void view_exec_dispatch(Widget w, MainWindow *mwin, Header_Mode header_mode) #else void view_exec_dispatch(w,mwin,header_mode) Widget w; MainWindow *mwin; Header_Mode header_mode; #endif { Message_List *message_list; char *contents; int errors = 0; char *command = NULL; if(mwin->current->scripting && mwin->current->script_arg) command = cpystr(mwin->current->script_arg); if(command == NULL) command = input_string(mwin->shell,MLGetLocalized(XtNmsgInputCommand, MsgInputCommand), session->last_command, SHELLCOMMANDHELPFILE); if(command == NULL) return; if(*command == NUL_TERM) { fs_give((void **) &command); return; } push_cursor(WATCH_CURSOR); for(message_list = mwin->current->message_list; message_list; message_list = message_list->next ) { if(message_list->selected) { contents = view_fetch(message_list->message, (mwin->current->scripting) ? mwin->current->script_header : header_mode); if(! contents) continue; if(write_to_pipe(command, NULL, contents, strlen(contents))) errors ++; fs_give((void **) &contents); } } if(errors) mm_log(MLGetLocalized(XtNmsgPipeFail,MsgPipeFail), WARN); if(session->last_command != NULL) fs_give((void **) &session->last_command); session->last_command = command; pop_cursor(); return; } #ifdef __STDC__ void view_savefull(Widget w, MainWindow *mwin, XtPointer xp) #else void view_savefull(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_save_dispatch(w,mwin,HEADER_FULL); return; } #ifdef __STDC__ void view_savepart(Widget w, MainWindow *mwin, XtPointer xp) #else void view_savepart(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_save_dispatch(w,mwin,HEADER_PART); return; } #ifdef __STDC__ void view_savenone(Widget w, MainWindow *mwin, XtPointer xp) #else void view_savenone(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_save_dispatch(w,mwin,HEADER_NONE); return; } #ifdef __STDC__ void view_save_dispatch(Widget w, MainWindow *mwin, Header_Mode header_mode) #else void view_save_dispatch(w,mwin,header_mode) Widget w; MainWindow *mwin; Header_Mode header_mode; #endif { FILE *fp; char *filename = NULL; Message_List *message_list; char *contents; int errors = 0; Boolean append_it; if((mwin->current) && mwin->current->scripting && mwin->current->script_arg) { filename = cpystr(mwin->current->script_arg); append_it = TRUE; } if(! filename) filename = file_select(mwin->shell,NULL, NULL, NULL, TRUE, &append_it); if(filename == NULL) return; push_cursor(WATCH_CURSOR); if((fp = fopen(filename,(append_it == TRUE) ? "a" : "w")) != NULL) { (void) chmod(filename,S_IRWXU); for(message_list = mwin->current->message_list; message_list; message_list = message_list->next ) { if(message_list->selected) { contents = view_fetch(message_list->message, (mwin->current->scripting) ? mwin->current->script_header : header_mode); if(! contents) continue; if((fwrite(contents,strlen(contents),1,fp)) != 1) errors ++; fs_give((void **) &contents); } if(errors) break; } if((fclose(fp)) != SYSCALL_SUCCESS) errors ++; } if(errors) mm_log(MLGetLocalized(XtNmsgSaveFail,MsgSaveFail), WARN); else mm_log(MLGetLocalized(XtNmsgSaveSuccess,MsgSaveSuccess), NIL); pop_cursor(); return; } #ifdef __STDC__ void view_set_deleted(Widget w, MainWindow *mwin, XtPointer xp) #else void view_set_deleted(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_setflag(w,mwin,DELETED_FLAG); return; } #ifdef __STDC__ void view_set_seen(Widget w, MainWindow *mwin, XtPointer xp) #else void view_set_seen(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_setflag(w,mwin,SEEN_FLAG); return; } #ifdef __STDC__ void view_set_flagged(Widget w, MainWindow *mwin, XtPointer xp) #else void view_set_flagged(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_setflag(w,mwin,FLAGGED_FLAG); return; } #ifdef __STDC__ void view_set_answered(Widget w, MainWindow *mwin, XtPointer xp) #else void view_set_answered(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_setflag(w,mwin,ANSWERED_FLAG); return; } #ifdef __STDC__ void view_clear_deleted(Widget w, MainWindow *mwin, XtPointer xp) #else void view_clear_deleted(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_clearflag(w,mwin,DELETED_FLAG); return; } #ifdef __STDC__ void view_clear_seen(Widget w, MainWindow *mwin, XtPointer xp) #else void view_clear_seen(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_clearflag(w,mwin,SEEN_FLAG); return; } #ifdef __STDC__ void view_clear_flagged(Widget w, MainWindow *mwin, XtPointer xp) #else void view_clear_flagged(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_clearflag(w,mwin,FLAGGED_FLAG); return; } #ifdef __STDC__ void view_clear_answered(Widget w, MainWindow *mwin, XtPointer xp) #else void view_clear_answered(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { view_clearflag(w,mwin,ANSWERED_FLAG); return; } #ifdef __STDC__ void update_flags(Lview *lview) #else void update_flags(lview) Lview *lview; #endif { Message_List *message_list; if((lview == NULL) || (lview->num_selected == 0L)) return; for(message_list = lview->message_list; message_list; message_list = message_list->next) { if((message_list->selected == TRUE) && (message_list->message != NULL)) mm_flags(message_list->message->mailstream, message_list->message->msgno); } return; } #ifdef __STDC__ void view_setflag(Widget w, MainWindow *mwin, char *flag) #else void view_setflag(w,mwin,flag) Widget w; MainWindow *mwin; char *flag; #endif { char *sequence = NULL; sequence = generate_sequence(mwin->current); if(sequence == NULL) return; push_cursor(WATCH_CURSOR); mail_setflag(mwin->current->mailstream,sequence,flag); update_flags(mwin->current); fs_give((void **) &sequence); pop_cursor(); return; } #ifdef __STDC__ void view_clearflag(Widget w, MainWindow *mwin, char *flag) #else void view_clearflag(w,mwin,flag) Widget w; MainWindow *mwin; char *flag; #endif { char *sequence = NULL; sequence = generate_sequence(mwin->current); if(sequence == NULL) return; push_cursor(WATCH_CURSOR); mail_clearflag(mwin->current->mailstream,sequence,flag); update_flags(mwin->current); fs_give((void **) &sequence); pop_cursor(); return; } #ifdef __STDC__ void view_filter(Widget w, MainWindow *mwin, XtPointer xp) #else void view_filter(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { create_edfilter_window(mwin); return; } #ifdef __STDC__ void view_reply_sender(Widget w, MainWindow *mwin, XtPointer xp) #else void view_reply_sender(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *message_list; for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { if(message_list->selected) compose_message(COMPOSE_REPLY, FALSE,NULL, message_list->message, NULL); } return; } #ifdef __STDC__ void view_reply_all(Widget w, MainWindow *mwin, XtPointer xp) #else void view_reply_all(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *message_list; for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { if(message_list->selected) compose_message(COMPOSE_REPLYALL, FALSE, NULL, message_list->message, NULL); } return; } #ifdef __STDC__ void view_remail(Widget w, MainWindow *mwin, XtPointer xp) #else void view_remail(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { Message_List *message_list; for(message_list = mwin->current->message_list; message_list; message_list = message_list->next) { if(message_list->selected) compose_message(COMPOSE_REMAIL, FALSE, NULL, message_list->message, NULL); } return; } #ifdef __STDC__ void view_forward(Widget w, MainWindow *mwin, XtPointer xp) #else void view_forward(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { (void) compose_message(COMPOSE_FORWARD, FALSE, mwin->current, NULL, NULL); return; } #ifdef __STDC__ void view_forward_attach(Widget w, MainWindow *mwin, XtPointer xp) #else void view_forward_attach(w,mwin,xp) Widget w; MainWindow *mwin; XtPointer xp; #endif { (void) compose_message(COMPOSE_FORWARDATTACH, FALSE, mwin->current, NULL, NULL); return; } #ifdef __STDC__ int message_list_compare(Message_List *list1,Message_List *list2) #else int message_list_compare(list1,list2) Message_List *list1; Message_List *list2; #endif { Message_List *ptr1 = list1; Message_List *ptr2 = list2; for( ; ; ) { if((ptr1 != NULL) && (ptr2 != NULL)) { if(ptr1->message != ptr2->message) return(LISTNOMATCH); else { ptr1 = ptr1->next; ptr2 = ptr2->next; continue; } } else { if(ptr1 != ptr2) return(LISTNOMATCH); else return(LISTMATCH); } } /* NOTREACHED */ } #ifdef __STDC__ void update_current_view(Mailbox *mailbox) #else void update_current_view(mailbox) Mailbox *mailbox; #endif { MainWindow *mwin = find_main_window(mailbox); Lview *lview; Message_List *message_list; char ** strtab; int n; if((mwin == NULL) || (mwin->current == NULL) || (mwin->current->count == 0L)) return; lview = mwin->current; /* * If we're pruning the view, zero it and start over. Then * set prune_happened so we don't ever do it again. */ XmListDeselectAllItems(mwin->list); if(lview->pruned && (lview->prune_happened == FALSE)) XmListDeleteAllItems(mwin->list); strtab = (char **) fs_get(lview->count * (sizeof(char *))); for(message_list = lview->message_list, n = 0 ; message_list; message_list = message_list->next) { strtab[n] = (char *) message_list->message->viewline; n ++; } lview->count = n; if(lview->pruned && (lview->prune_happened == FALSE)) { XmListAddItems(mwin->list, (XmStringTable) strtab, lview->count, 1); if(lview->representation == REP_ASCENDING || lview->representation == REP_SORT_SIZE) XmListSetBottomPos(mwin->list, lview->count); else XmListSetBottomPos(mwin->list,1); } else XmListReplaceItemsPos(mwin->list, (XmStringTable) strtab, lview->count,1); if(lview->pruned) lview->prune_happened = TRUE; free(strtab); XtVaSetValues(mwin->list, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL); for(message_list = lview->message_list; message_list; message_list = message_list->next) { if(message_list->selected == TRUE) XmListSelectPos(mwin->list, message_list->number, FALSE); } XtVaSetValues(mwin->list, XmNselectionPolicy, XmEXTENDED_SELECT, NULL); stuff_lview_list(mwin,TRUE,FALSE); return; } #ifdef __STDC__ void update_bucket(Mailbox *mailbox) #else void update_bucket(mailbox) Mailbox *mailbox; #endif { Lview *all; Lview *bucket; Message_List *message_list; Message_List *old; Message_List *new; MainWindow *mwin = find_main_window(mailbox); all = get_all_lview(mailbox->mailstream); bucket = get_bucket_lview(mailbox->mailstream); if(mwin == NULL || all == NULL || bucket == NULL) return; free_message_list(mailbox->found,TRUE,FALSE); mailbox->found = NULL; for(message_list = all->message_list; message_list; message_list = message_list->next) { if((message_list->message) && (message_list->message->in_view == FALSE)) mm_searched(mailbox->mailstream,message_list->message->msgno); } new = mailbox->found; mailbox->found = NULL; old = bucket->message_list; if((message_list_compare(old,new)) == LISTMATCH) free_message_list(new,TRUE,FALSE); else { update_lview_message_list(mwin,bucket,old,new,FALSE); free_message_list(old,TRUE,FALSE); } return; } #ifdef __STDC__ void set_found_flags(Message_List *message_list) #else void set_found_flags(message_list) Message_List *message_list; #endif { Message_List *curr; for(curr = message_list; curr; curr = curr->next) if(curr->message) curr->message->in_view = TRUE; return; } /* * The initialize flag says to update all views. * We set it to true when creating a filter, and after an expunge * to catch the one-shot filters. */ #ifdef __STDC__ void update_logical_views(Mailbox *mailbox,Boolean initialize) #else void update_logical_views(mailbox,initialize) Mailbox *mailbox; Boolean initialize; #endif { Lview *lview; Message_List *old; Message_List *new; MainWindow *mwin = find_main_window(mailbox); if(! mwin) return; for(lview = mwin->lview; lview ; lview = lview->prev) { if(lview->filter == NULL || lview->mailbox != mailbox) continue; if(lview->filter->filter_type == FILTER_TYPE_ALL) { lview->has_new = has_new_messages(lview,TRUE); /* and wipe "in_view" */ continue; } if(lview->filter->filter_type == FILTER_TYPE_BUCKET) continue; if((lview->filter->filter_type == FILTER_TYPE_ONESHOT) && (initialize == FALSE)) continue; new = do_imap_search(lview->mailbox,lview->parent, lview->filter->search_tree); new = sort_message_list(new, lview->representation); old = lview->message_list; if((message_list_compare(old,new)) == LISTMATCH) { free_message_list(new,TRUE,FALSE); set_found_flags(old); continue; } update_lview_message_list(mwin,lview,old,new, TRUE); free_message_list(old,TRUE,FALSE); } update_bucket(mailbox); stuff_lview_list(mwin,TRUE,FALSE); mailbox->update_needed = 0; return; } #ifdef __STDC__ int sort_ascending(const void *list1,const void *list2) #else int sort_ascending(list1,list2) const void *list1; const void *list2; #endif { Message_List ** l1 = (Message_List **) list1; Message_List ** l2 = (Message_List **) list2; return((*l1)->message->msgno - (*l2)->message->msgno); } #ifdef __STDC__ int sort_size(const void *list1,const void *list2) #else int sort_size(list1,list2) const void *list1; const void *list2; #endif { Message_List ** l1 = (Message_List **) list1; Message_List ** l2 = (Message_List **) list2; MESSAGECACHE *elt1; MESSAGECACHE *elt2; unsigned long size1 = 0L; unsigned long size2 = 0L; elt1 = ((*l1)->message && (*l1)->message->longcache) ? &((*l1)->message->longcache->elt) : NULL; elt2 = ((*l2)->message && (*l2)->message->longcache) ? &((*l2)->message->longcache->elt) : NULL; size1 = (elt1) ? elt1->rfc822_size : 0L; size2 = (elt2) ? elt2->rfc822_size : 0L; return(size1 - size2); } #ifdef __STDC__ int sort_reverse(const void *list1, const void *list2) #else int sort_reverse(list1,list2) const void *list1; const void *list2; #endif { Message_List ** l1 = (Message_List **) list1; Message_List ** l2 = (Message_List **) list2; return((*l2)->message->msgno - (*l1)->message->msgno); } #ifdef __STDC__ int sort_subject(const void *list1,const void *list2) #else int sort_subject(list1,list2) const void *list1; const void *list2; #endif { Message_List ** l1 = (Message_List **) list1; Message_List ** l2 = (Message_List **) list2; int result; unsigned char *ptr1; unsigned char *ptr2; if((*l1)->message->subject == NULL) ptr1 = (unsigned char *) EMPTYSTR; else ptr1 = (unsigned char *) (*l1)->message->subject; if((*l2)->message->subject == NULL) ptr2 = (unsigned char *) EMPTYSTR; else ptr2 = (unsigned char *) (*l2)->message->subject; do { if((result = strncasecmp((char *) ptr1,"re",2)) == STRMATCH) { if((*(ptr1 + 2) == ':') || (*(ptr1 + 2) == '[')) { while(*ptr1 && ! isspace(*ptr1)) ptr1 ++; while(*ptr1 && isspace(*ptr1)) ptr1 ++; } else result = ~STRMATCH; } } while(result == STRMATCH); do { if((result = strncasecmp((char *) ptr2,"re",2)) == STRMATCH) { if((*(ptr2 + 2) == ':') || (*(ptr2 + 2) == '[')) { while(*ptr2 && ! isspace(*ptr2)) ptr2 ++; while(*ptr2 && isspace(*ptr2)) ptr2 ++; } else result = ~STRMATCH; } } while(result == STRMATCH); while((*ptr1) && (isspace(*ptr1))) ptr1 ++; while((*ptr2) && (isspace(*ptr2))) ptr2 ++; result = strcasecmp((char *) ptr1,(char *) ptr2); if(result == STRMATCH) return((*l1)->message->msgno - (*l2)->message->msgno); else return(result); } #ifdef __STDC__ int sort_sender(const void *list1, const void *list2) #else int sort_sender(list1,list2) const void *list1; const void *list2; #endif { Message_List ** l1 = (Message_List **) list1; Message_List ** l2 = (Message_List **) list2; int result; char * ptr1, *ptr2; if((*l1)->message->sender) ptr1 = (*l1)->message->sender; else ptr1 = EMPTYSTR; if((*l2)->message->sender) ptr2 = (*l2)->message->sender; else ptr2 = EMPTYSTR; result = strcasecmp(ptr1, ptr2); if(result == STRMATCH) return((*l1)->message->msgno - (*l2)->message->msgno); else return(result); } #ifdef __STDC__ void thread_preprocess(Message_List *message_list, Message *message) #else void thread_preprocess(message_list,message) Message_List *message_list; Message *message; #endif { Message_List *tmp; Boolean found = FALSE; if((message != NULL) && (message->references != NULL) && (*message->references != NUL_TERM)) { for(tmp = message_list; tmp; tmp = tmp->next) { if((tmp->message != NULL) && (tmp->message->message_id != NULL) && (*tmp->message->message_id != NUL_TERM) && ((strcmp(tmp->message->message_id, message->references)) == STRMATCH)) { message->thread_parent = tmp->message; message->thread_child = TRUE; found = TRUE; break; } } } if(found == FALSE) { message->thread_parent = NULL; message->thread_child = FALSE; } return; } #ifdef __STDC__ Message_List * sort_message_list(Message_List *message_list, Representation_Type representation) #else Message_List * sort_message_list(message_list, representation) Message_List *message_list; Representation_Type representation; #endif { Message_List **sort; Message_List *ml_ptr; Message_List *result = NULL; int n = 0; int total = 0; if(message_list == NULL) return(message_list); for(ml_ptr = message_list; ml_ptr; ml_ptr = ml_ptr->next) total ++; if(total < 2) return(message_list); sort = (Message_List **) fs_get(total * sizeof(Message_List *)); for(ml_ptr = message_list; ml_ptr; ml_ptr = ml_ptr->next) { if(ml_ptr->message == NULL) continue; sort[n] = ml_ptr; n ++; } switch (representation) { case REP_DESCENDING: qsort((char *) sort,total,sizeof(Message_List **),sort_reverse); break; case REP_SORT_SUBJECT: qsort((char *) sort,total,sizeof(Message_List **),sort_subject); break; case REP_SORT_SIZE: qsort((char *) sort,total,sizeof(Message_List **),sort_size); break; case REP_SORT_SENDER: qsort((char *) sort,total,sizeof(Message_List **),sort_sender); break; case REP_ASCENDING: default: qsort((char *) sort,total,sizeof(Message_List **),sort_ascending); break; } for(n = 0; n < total; n ++) { ml_ptr = sort[n]; if(n == 0) { result = ml_ptr; ml_ptr->next = sort[n + 1]; ml_ptr->prev = NULL; ml_ptr->number = n + 1; } else { ml_ptr->prev = sort[n - 1]; ml_ptr->number = n + 1; if(n == (total - 1)) ml_ptr->next = NULL; else ml_ptr->next = sort[n + 1]; } } fs_give((void **) &sort); return(result); } /* * This function has been overloaded a bit to save running through the list * a second time to clear the "in_view" flag. */ #ifdef __STDC__ Boolean has_new_messages(Lview *lview,Boolean wipe) #else Boolean has_new_messages(lview,wipe) Lview *lview; Boolean wipe; #endif { Message_List *message_list; MESSAGECACHE *elt; Boolean has_new = FALSE; for(message_list = lview->message_list; message_list; message_list = message_list->next) { if(! message_list->message) continue; if(wipe) message_list->message->in_view = FALSE; if((message_list->message->fetched == TRUE) && (message_list->message->longcache)) { elt = &(message_list->message->longcache->elt); if((! elt->seen) && elt->recent) { has_new = TRUE; if(wipe == FALSE) return(has_new); } } } return(has_new); } #ifdef __STDC__ void update_lview_message_list(MainWindow *mwin, Lview *lview, Message_List *old, Message_List *new, Boolean update_in_view_flag) #else void update_lview_message_list(mwin,lview,old,new,update_in_view_flag) MainWindow *mwin; Lview *lview; Message_List *old; Message_List *new; Boolean update_in_view_flag; #endif { int n = 0; Message_List *list1, *list2; for(list1 = old; list1; list1 = list1->next) { for(list2 = new; list2; list2 = list2->next) { if(list1->message != list2->message) continue; if(list1->selected == TRUE) list2->selected = TRUE; } } for(list2 = new; list2; list2 = list2->next) { n ++; if((list2->message) && (update_in_view_flag == TRUE)) list2->message->in_view = TRUE; } lview->count = n; lview->message_list = new; lview->has_new = has_new_messages(lview,FALSE); if(lview == mwin->current) view_context_switch(mwin,mwin->current,lview); return; } #ifdef __STDC__ void lview_pop(Widget w, XtPointer xp) #else void lview_pop(w,xp) Widget w; XtPointer xp; #endif { MainWindow *mwin; for(mwin = session->mwin; mwin; mwin = mwin->next) { if((mwin->list == w) || ((mwin->listwin->list == w) && (mwin->listwin->is_realized == TRUE))) { if(mwin->listwin->is_realized == FALSE) view_lview_window(w,mwin,NULL); else view_lview_dismiss(w,mwin,NULL); return; } } return; }