/* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1