static char rcsid[] = "@(#)$Id: thread.c,v 1.10 2006/04/16 21:01:35 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.10 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
* or Kari Hurtta <elm@elmme-mailer.org>
*****************************************************************************/
#include "def_elm.h"
#include "s_me.h"
DEBUG_VAR(Debug,__FILE__,"mail");
static void first_item P_((void));
static void first_item()
{
lib_error(CATGETS(elm_msg_cat, MeSet,
MeNoMoreThreadsAbove,
"No more threads above."));
}
static void last_item P_((void));
static void last_item()
{
lib_error(CATGETS(elm_msg_cat, MeSet,
MeNoMoreThreadsBelow,
"No more threads below."));
}
static struct move_messages M = {
first_item,
last_item
};
#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif
struct sort_list {
char status_letter;
int idx;
};
struct menu_anon_param {
struct MailboxView * mailbox;
struct sort_list * sort_list;
int sort_list_len;
};
struct sort_data1 {
struct MailboxView *mailbox;
int index;
};
static int compare_threads_1 P_((const struct thread_info *X1,
const struct thread_info *X2));
static int compare_threads_1(X1,X2)
CONST struct thread_info *X1;
CONST struct thread_info *X2;
{
long diff = 0;
int ret;
switch (give_dt_sort_as_int(&thread_sortby)) {
case SENT_DATE: /* as THREAD sorting */
diff = X1->time_sent_first - X2->time_sent_first;
if (diff < 0)
return -1;
if (diff > 0)
return 1;
break;
case REVERSE SENT_DATE:
if (unstable_reverse_thread) {
/* Move thread new location when new mail arrives,
therfore use newest sent time
*/
diff = X1->time_sent_last - X2->time_sent_last;
} else
diff = X1->time_sent_first - X2->time_sent_first;
if (diff < 0)
return 1;
if (diff > 0)
return -1;
break;
case SUBJECT:
if (! X1->thread_subject && ! X2->thread_subject)
return 0;
if (! X1->thread_subject)
return -1;
if (! X2->thread_subject)
return 1;
ret = string_cmp(X1->thread_subject,X2->thread_subject,
0 /* == Values not comparable */ );
return ret;
case REVERSE SUBJECT:
if (! X1->thread_subject && ! X2->thread_subject)
return 0;
if (! X1->thread_subject)
return -1;
if (! X2->thread_subject)
return 1;
ret = string_cmp(X1->thread_subject,X2->thread_subject,
0 /* == Values not comparable */ );
return ret;
}
return 0;
}
static int compare_threads P_((struct sort_data1 *p1,
struct sort_data1 *p2));
static int compare_threads(p1,p2)
struct sort_data1 *p1;
struct sort_data1 *p2;
{
int ret;
/* give_thread_info checks that index is correct range */
CONST struct thread_info *X1 = give_thread_info(p1->mailbox,
p1->index);
CONST struct thread_info *X2 = give_thread_info(p2->mailbox,
p2->index);
if (!X1 && !X2) {
return p2->index - p1->index;
}
if (!X1)
return -1;
if (!X2)
return 1;
ret = compare_threads_1(X1,X2);
if (ret != 0)
return ret;
return p2->index - p1->index;
}
static void sort_threads P_((struct MailboxView *mailbox,
struct menu_anon_param *A,
struct menu_context *page));
static void sort_threads(mailbox,A,page)
struct MailboxView *mailbox;
struct menu_anon_param *A;
struct menu_context *page;
{
/* Be sure that we have threads available */
int num_threads = get_thread_count(mailbox,0);
int old_len = A->sort_list_len;
int cur = menu_header_get(page,header_current);
int top = menu_header_get(page,header_top_line);
int real_cur = 0;
int i;
struct sort_data1 * array;
/* Little dirty ... */
typedef int (*compar) P_((const void *, const void *));
compar X = (compar) compare_threads;
int li,co;
menu_get_sizes(page, &li, &co);
if (num_threads < 1) {
A->sort_list_len = 0;
menu_header_change(page, header_top_line,0);
menu_header_change(page,header_current,0);
return;
}
if (cur >= 0 && cur < A->sort_list_len)
real_cur = A->sort_list[cur].idx;
A->sort_list = safe_realloc(A->sort_list,
num_threads * sizeof (A->sort_list[0]));
for (i = old_len; i < num_threads; i++) {
A->sort_list[i].idx = i;
A->sort_list[i].status_letter = '\0';
}
A->sort_list_len = num_threads;
array = safe_malloc(num_threads * sizeof(array[0]));
for (i = 0; i < num_threads; i++) {
array[i].index = A->sort_list[i].idx;
array[i].mailbox = mailbox;
}
qsort(array,num_threads,sizeof (array[0]), X);
for (i = 0; i < num_threads; i++) {
if (array[i].index != A->sort_list[i].idx) {
A->sort_list[i].idx = array[i].index;
A->sort_list[i].status_letter = '\0';
}
}
free(array);
/* FIXME -- not very effective */
for (i = 0; i < A->sort_list_len; i++) {
if (real_cur == A->sort_list[i].idx) {
menu_header_change(page,header_current,i);
if (i < top || i >= top+li)
menu_header_change(page,header_current,i);
break;
}
}
menu_trigger_redraw(page);
}
static int calculate_status P_((struct menu_anon_param *A,
int index));
/* return 1 if changed */
static int calculate_status(A,index)
struct menu_anon_param *A;
int index;
{
int * vector = NULL;
int len;
char new_val;
if (index < 0 || index > A->sort_list_len)
panic("THREAD PANIC",__FILE__,__LINE__,"calculate_status",
"Bad index",0);
vector = give_thread_message_list(A->mailbox,A->sort_list[index].idx,
&len);
if (vector) {
int i;
int all_deleted = 1;
int all_expired = 1;
new_val = ' ';
for (i = 0; i < len; i++) {
if (!ison_status_message(A->mailbox,vector[i],status_basic,
DELETED))
all_deleted = 0;
if (!ison_status_message(A->mailbox,vector[i],status_basic,
EXPIRED))
all_expired = 0;
if (' ' == new_val &&
ison_status_message(A->mailbox,vector[i],status_basic,UNREAD))
new_val = 'O';
if ((' ' == new_val || 'O' == new_val) &&
ison_status_message(A->mailbox,vector[i],status_basic,NEW))
new_val = 'N';
}
if (all_expired)
new_val = 'E';
if (all_deleted)
new_val = 'D';
free(vector);
} else
new_val = 'Z';
if (A->sort_list[index].status_letter != new_val) {
A->sort_list[index].status_letter = new_val;
return 1;
}
return 0;
}
enum { thread_mp_mailbox,
thread_mp_param,
thread_mp_COUNT };
S_(header_line_redraw thread_show_header)
static void thread_show_header P_((struct menu_context *ptr,
struct menu_param *list,
int line_number,
int index,
int is_current));
static void thread_show_header(ptr,list,line_number,index,is_current)
struct menu_context *ptr;
struct menu_param *list;
int line_number;
int index;
int is_current;
{
struct menu_anon_param *A = mp_lookup_anon(list,thread_mp_param);
int LINES, COLUMNS;
menu_get_sizes(ptr, &LINES, &COLUMNS);
menu_ClearLine(ptr,line_number);
menu_MoveCursor(ptr,line_number,0);
if (is_current) {
if (has_highlighting && ! arrow_cursor) {
menu_StartXX(ptr,pg_INVERSE);
menu_PutLine0(ptr,line_number,0," ");
} else {
menu_PutLine0(ptr,line_number,0,"-> ");
}
} else
menu_PutLine0(ptr,line_number,0," ");
if (index >= 0 && index < A->sort_list_len) {
CONST struct thread_info *X;
if (!A->sort_list[index].status_letter)
calculate_status(A,index);
/* give_thread_info checks that index is correct range */
X = give_thread_info(A->mailbox,A->sort_list[index].idx);
if (X) {
/* Message menu is show time as sending timezone,
but on thread view we use localtime
*/
char buffer[7];
struct tm * tmres = localtime(& X->time_sent_first);
struct string * S = NULL;
int l;
S = format_string(FRM("%c %3d %3.3s %-2d "),
A->sort_list[index].status_letter ?
A->sort_list[index].status_letter : '?',
index+1,
arpa_monname[tmres->tm_mon], tmres->tm_mday);
l = string_len(S);
if (COLUMNS > l+3) {
struct string *S1;
if (X->time_sent_first != X->time_sent_last) {
tmres = localtime(& X->time_sent_last);
S1 = format_string(FRM("- %3.3s %-2d %04d "),
arpa_monname[tmres->tm_mon],
tmres->tm_mday,tmres->tm_year+1900);
} else {
S1 = format_string(FRM("%04d "),
tmres->tm_year+1900);
}
append_string(&S,S1);
free_string(&S1);
l = string_len(S);
}
if (COLUMNS > l+3) {
struct string *S1;
if (X->num_messages != 1) {
S1 = format_string(FRM("[%3d] "),
X->num_messages);
} else {
S1 = format_string(FRM(" "));
}
append_string(&S,S1);
free_string(&S1);
l = string_len(S);
}
menu_PutLineX(ptr,line_number,3,FRM("%S"),S);
free_string(&S);
if (X->thread_subject && COLUMNS > l+3) {
struct string * buffer2 = NULL;
int X1 = 0;
int subj_width = COLUMNS-l-3;
int was_len;
/* clip_from_string updates X1 */
buffer2 = curses_printable_clip(X->thread_subject,&X1,
subj_width,
&was_len,subj_width);
if (buffer2) {
menu_PutLineX(ptr,line_number,l+3,FRM("%S"),
buffer2);
free_string(&buffer2);
}
if (is_current && !arrow_cursor) {
while (was_len < subj_width) {
menu_Writechar(ptr,' ');
was_len++;
}
}
}
}
}
if (is_current) {
if (has_highlighting && ! arrow_cursor) {
menu_EndXX(ptr,pg_INVERSE);
}
}
menu_Writechar(ptr,'\r');
menu_Writechar(ptr,'\n');
}
S_(header_line_redraw thread_show_current)
static void thread_show_current P_((struct menu_context *ptr,
struct menu_param *list,
int line_number,
int index,
int is_current));
static void thread_show_current(ptr,list,line_number,index,is_current)
struct menu_context *ptr;
struct menu_param *list;
int line_number;
int index;
int is_current;
{
if (has_highlighting && ! arrow_cursor) {
thread_show_header(ptr,list,line_number,index,is_current);
} else {
if (!is_current)
menu_PutLine0(ptr,line_number,0," "); /* remove old pointer... */
else
menu_PutLine0(ptr,line_number,0,"->");
}
}
S_(header_line_redraw thread_show_status)
static void thread_show_status P_((struct menu_context *ptr,
struct menu_param *list,
int line_number,
int index,
int is_current));
static void thread_show_status(ptr,list,line_number,index,is_current)
struct menu_context *ptr;
struct menu_param *list;
int line_number;
int index;
int is_current;
{
struct menu_anon_param *A = mp_lookup_anon(list,thread_mp_param);
if (has_highlighting && ! arrow_cursor) {
thread_show_header(ptr,list,line_number,index,is_current);
} else {
if (!is_current)
menu_PutLine0(ptr,line_number,0," "); /* remove old pointer... */
else
menu_PutLine0(ptr,line_number,0,"->");
if (index >= 0 && index < A->sort_list_len) {
CONST struct thread_info *X;
/* give_thread_info checks that index is correct range */
X = give_thread_info(A->mailbox,A->sort_list[index].idx);
if (X) {
menu_PutLineX(ptr,line_number,3,
FRM("%c"),
A->sort_list[index].status_letter ?
A->sort_list[index].status_letter : '?');
}
}
}
}
S_(subpage_simple_redraw sb_update_thread_menu)
static int sb_update_thread_menu P_((struct menu_context *ptr,
struct menu_param *list));
static int sb_update_thread_menu(ptr,list)
struct menu_context *ptr;
struct menu_param *list;
{
menu_ClearScreen(ptr);
menu_print_format_center(ptr,0,
CATGETS(elm_msg_cat, MeSet, MeThreadMenuLine1,
"To select thread, press <return>. j = move down, k = move up, q = quit menu"));
menu_print_format_center(ptr,1,
CATGETS(elm_msg_cat, MeSet, MeThreadMenuLine2,
"Or m)ail message, d)elete or u)ndelete messages of thread"));
return 1;
}
S_(subpage_simple_redraw sb_update_threadtitle)
static int sb_update_threadtitle P_((struct menu_context *ptr,
struct menu_param *list));
static int sb_update_threadtitle(ptr,list)
struct menu_context *ptr;
struct menu_param *list;
{
struct menu_common *mptr = mp_lookup_mcommon(list,thread_mp_mailbox);
struct string * f1 = mcommon_title(mptr);
struct menu_anon_param *A = mp_lookup_anon(list,thread_mp_param);
int num_threads = get_thread_count(A->mailbox,0);
struct string * buffer = NULL;
struct string * buffer2 = NULL;
int LINES, COLUMNS;
int l1,l2,l;
menu_ClearScreen(ptr);
menu_get_sizes(ptr, &LINES, &COLUMNS);
if (1 == num_threads)
buffer = format_string(CATGETS(elm_msg_cat, MeSet,
MeShownWithThread,
"%S with 1 thread"),
f1);
else
buffer = format_string(CATGETS(elm_msg_cat, MeSet,
MeShownWithThreads,
"%S with %d threads"),
f1,num_threads);
l1 = string_len(buffer);
buffer2 = format_string(FRM("[ELM %s]"),
version_buff);
l2 = string_len(buffer2);
l = l1 + l2 + 1; /* Assumed */
if (l > COLUMNS) {
if (l2 < COLUMNS)
menu_PutLineX(ptr,2,(COLUMNS - l2)/2,FRM("%S"),buffer2);
if (l1 > COLUMNS)
menu_PutLineX(ptr,1,1,FRM("%S"),buffer);
else
menu_PutLineX(ptr,1,(COLUMNS - l1)/2,FRM("%S"),buffer);
} else {
menu_PutLineX(ptr,1,(COLUMNS - l)/2,FRM("%S %S"),buffer,buffer2);
}
free_string(&buffer2);
free_string(&buffer);
free_string(&f1);
return 1; /* subpage area updated completely */
}
static void set_thread_screen P_((struct menu_context *page,
struct screen_parts *LOC,
struct menu_param *LIST));
static void set_thread_screen(page,LOC,LIST)
struct menu_context *page;
struct screen_parts *LOC;
struct menu_param *LIST;
{
int LINES, COLUMNS;
int headers_per_page;
menu_get_sizes(page,&LINES, &COLUMNS);
/* 1) Title part of screen */
if (! LOC->title_page)
LOC->title_page = new_menu_subpage(page,0,4,sb_update_threadtitle,
LIST);
else
menu_subpage_relocate(LOC->title_page,page,0,4);
/* 3) menu part */
if (LOC->menu_page && LINES < 14)
erase_menu_context (&(LOC->menu_page));
else if (LOC->menu_page)
menu_subpage_relocate(LOC->menu_page,page,LINES-7,3);
else if (mini_menu && LINES > 14)
LOC->menu_page = new_menu_subpage(page,LINES-7,3,
sb_update_thread_menu,LIST);
/* 4) prompt part */
if (LOC->prompt_page)
menu_subpage_relocate(LOC->prompt_page,page,LINES-4,4);
else
LOC->prompt_page = new_menu_subpage(page,LINES-4,4,
subpage_simple_noredraw,LIST);
/* 2) thread part */
headers_per_page = LOC->menu_page ? LINES-12 : LINES-9;
if (headers_per_page < 1) {
headers_per_page = 1;
}
if (! LOC->header_page)
LOC->header_page = new_menu_header(page,4,
headers_per_page,
thread_show_header,
thread_show_current,
null_header_param_changed,
thread_show_status,
LIST);
else
menu_header_relocate(LOC->header_page,page,
4,headers_per_page);
}
static void check_thread_screen P_((struct screen_parts *LOC,
struct menu_param *list));
static void check_thread_screen(LOC,list)
struct screen_parts *LOC;
struct menu_param *list;
{
/* 1) title page */
if (menu_resized(LOC->title_page)) {
DPRINT(Debug,1, (&Debug, "title page resized\n"));
}
if (menu_need_redraw(LOC->title_page)) {
DPRINT(Debug,1, (&Debug, "title page redraw???\n"));
sb_update_threadtitle(LOC->title_page,list);
}
/* 2) headers part */
if (menu_resized(LOC->header_page)) {
DPRINT(Debug,1, (&Debug, "header page resized\n"));
}
if (menu_need_redraw(LOC->header_page)) {
DPRINT(Debug,1, (&Debug, "header page redraw\n"));
menu_ClearScreen(LOC->header_page);
}
if (LOC->menu_page) {
/* 3) menu page */
if (menu_resized(LOC->menu_page)) {
DPRINT(Debug,1, (&Debug, "menu page resized\n"));
}
if (menu_need_redraw(LOC->menu_page)) {
DPRINT(Debug,1, (&Debug, "menu page redraw\n"));
sb_update_thread_menu(LOC->menu_page,list);
}
}
/* 4) prompt part */
if (menu_resized(LOC->prompt_page)) {
DPRINT(Debug,1, (&Debug, "prompt page resized\n"));
}
if (menu_need_redraw(LOC->prompt_page)) {
DPRINT(Debug,7, (&Debug, "prompt page redraw\n"));
menu_ClearScreen(LOC->prompt_page);
show_last_error(); /* for those operations that have to
* clear the footer except for a message.
*/
}
}
void ViewThreads(mailbox,aview, parent_page)
struct MailboxView *mailbox;
struct AliasView *aview;
struct menu_context *parent_page;
{
struct menu_context * page;
struct screen_parts LOC = { NULL, NULL, NULL, NULL };
struct menu_common MENU;
int mailbox_sort_needed = 0;
struct menu_anon_param A;
struct menu_param PARAM[thread_mp_COUNT+1] = {
{ mp_menu_common, 0 },
{ mp_anon_param,0 },
{ mp_END,0 }
};
int ch;
int update = 1;
int c;
/* we need update thread list, becuase it may be changed meanwhile */
update_mailbox_threads(mailbox);
set_mcommon_from_mbxview(&MENU,mailbox);
mp_list_set_mcommon(PARAM,thread_mp_mailbox,&MENU);
A.mailbox = mailbox;
A.sort_list = NULL;
A.sort_list_len = 0;
mp_list_set_anon(PARAM,thread_mp_param,&A);
page = new_menu_context();
set_thread_screen(page,&LOC,PARAM);
sort_threads(mailbox,&A,LOC.header_page);
c = get_current(mailbox);
if (c > 0) {
int i;
struct folder_view INDEX;
int li,co;
INDEX.thread_number = -1;
give_index_number(mailbox,c-1,&INDEX);
menu_get_sizes(LOC.header_page, &li, &co);
/* FIXME -- not very effective */
for (i = 0; i < A.sort_list_len; i++) {
if (INDEX.thread_number == A.sort_list[i].idx) {
menu_header_change(LOC.header_page,header_current,i);
if (i > li)
menu_header_change(LOC.header_page, header_top_line,i);
}
}
}
for (;;) {
if (menu_resized(page)) {
set_thread_screen(page,&LOC,PARAM);
update = 1;
}
new_mail_check(mailbox, page, &LOC);
if (update_view(mailbox)) {
update = 1;
mailbox_sort_needed = 1;
/* We do not sort mailbox, because we do not show
message list */
update_mailbox_threads(mailbox);
sort_threads(mailbox,&A,LOC.header_page);
}
if (update || menu_need_redraw(page)) {
menu_ClearScreen(page);
/* Call refresh routines of children */
menu_redraw_children(page);
update = 0;
show_last_error();
}
check_thread_screen(&LOC, PARAM);
{
int lin,col;
menu_ClearLine(LOC.prompt_page,0);
menu_PutLineX (LOC.prompt_page,0, 0,
CATGETS(elm_msg_cat, MeSet, MeThreadMenuPrompt,
"Thread command: "));
menu_GetXYLocation(LOC.prompt_page,&lin,&col);
menu_CleartoEOS(LOC.prompt_page);
show_last_error();
menu_MoveCursor(LOC.prompt_page,lin,col);
ch = menu_ReadCh(LOC.prompt_page,
REDRAW_MARK|READCH_CURSOR|READCH_resize|
READCH_sig_char);
menu_CleartoEOS(LOC.prompt_page);
set_error(""); /* clear error buffer */
}
ch = do_movement1(LOC.header_page,ch,A.sort_list_len,&M);
switch (ch) {
int cur;
int top;
int li,co;
case RESIZE_MARK:
DPRINT(Debug,4, (&Debug, " ... resizing\n"));
continue;
case ctrl('L'):
case REDRAW_MARK:
update = 1;
break;
case DOWN_MARK :
case 'j' :
cur = menu_header_get(LOC.header_page,header_current);
cur++;
while (0 <= cur && cur < A.sort_list_len) {
if (A.sort_list[cur].status_letter != 'D' &&
A.sort_list[cur].status_letter != 'Z') {
goto found1;
}
cur++;
}
lib_error(CATGETS(elm_msg_cat, MeSet,
MeNoMoreUndThreadsBelow,
"No more undeleted threads below."));
break;
found1:
top = menu_header_get(LOC.header_page,header_top_line);
menu_header_change(LOC.header_page, header_current,cur);
menu_get_sizes(LOC.header_page, &li, &co);
if (top+li <= cur)
menu_header_change(LOC.header_page, header_top_line,cur);
break;
case UP_MARK :
case 'k' :
cur = menu_header_get(LOC.header_page,header_current);
cur--;
while (0 <= cur && cur < A.sort_list_len) {
if (A.sort_list[cur].status_letter != 'D' &&
A.sort_list[cur].status_letter != 'Z') {
goto found2;
}
cur--;
}
lib_error(CATGETS(elm_msg_cat, MeSet,
MeNoMoreUndThreadsAbove,
"No more undeleted threads above."));
break;
found2:
top = menu_header_get(LOC.header_page,header_top_line);
menu_header_change(LOC.header_page, header_current,cur);
menu_get_sizes(LOC.header_page, &li, &co);
if (top > cur) {
top = cur-li+1;
if (top < 0)
top = 0;
menu_header_change(LOC.header_page, header_top_line,top);
}
break;
case 'd':
cur = menu_header_get(LOC.header_page,header_current);
if (0 <= cur && cur < A.sort_list_len) {
int len;
int * vector = give_thread_message_list(mailbox,A.sort_list[cur].idx,
&len);
if (vector) {
int i;
for (i = 0; i < len; i++) {
setf_status_message(mailbox,vector[i],status_basic,
DELETED);
}
free(vector);
}
if (calculate_status(&A,cur)) {
menu_header_status_update(LOC.header_page,cur);
}
}
if (resolve_mode) {
cur = menu_header_get(LOC.header_page,header_current);
cur++;
while (0 <= cur && cur < A.sort_list_len) {
if (A.sort_list[cur].status_letter != 'D' &&
A.sort_list[cur].status_letter != 'Z') {
goto found1;
}
cur++;
}
}
break;
case 'u':
cur = menu_header_get(LOC.header_page,header_current);
if (0 <= cur && cur < A.sort_list_len) {
int len;
int * vector = give_thread_message_list(mailbox,A.sort_list[cur].idx,
&len);
if (vector) {
int i;
for (i = 0; i < len; i++) {
clearf_status_message(mailbox,vector[i],status_basic,
DELETED);
}
free(vector);
}
if (calculate_status(&A,cur)) {
menu_header_status_update(LOC.header_page,cur);
}
}
if (resolve_mode) {
cur = menu_header_get(LOC.header_page,header_current);
cur++;
while (0 <= cur && cur < A.sort_list_len) {
if (A.sort_list[cur].status_letter != 'Z') {
goto found1;
}
cur++;
}
}
break;
case '\n':
cur = menu_header_get(LOC.header_page,header_current);
if (0 <= cur && cur < A.sort_list_len) {
int need_resort = 0;
ViewThread1(mailbox,aview,A.sort_list[cur].idx,page,
&need_resort);
if (calculate_status(&A,cur)) {
menu_header_status_update(LOC.header_page,cur);
}
/* New mails may be arrived meanwhile */
update = 1;
if (need_resort)
mailbox_sort_needed = 1;
/* We do not sort mailbox, because we do not show
message list */
update_mailbox_threads(mailbox);
sort_threads(mailbox,&A,LOC.header_page);
}
break;
case 'm':
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, MeSet,
MeMail,
"Mail"));
FlushBuffer();
send_msg_l(-1, NULL, NULL, NULL,
MAIL_EDIT_MSG,allow_forms,
mailbox, aview,page, LOC.prompt_page);
break;
case 'i':
case 'q':
case 'x':
case TERMCH_interrupt_char:
case EOF:
goto OUT;
case 0:
break;
default:
if (ch > '0' && ch <= '9') {
int value;
struct string * str = format_string(CATGETS(elm_msg_cat, MeSet,
MeThreadItem,
"thread"));
menu_Write_to_screen(LOC.prompt_page,
CATGETS(elm_msg_cat, MeSet,
MeNewCurrentThread,
"New current thread"));
cur = menu_header_get(LOC.header_page,header_current);
value = read_number(ch, str, cur+1, page, LOC.prompt_page);
free_string(&str);
if (value > A.sort_list_len) {
lib_error(CATGETS(elm_msg_cat, MeSet,
MeNotThatManyThread,
"Not that many threads."));
} else if (value > 0) {
cur = value-1;
top = menu_header_get(LOC.header_page,header_top_line);
menu_header_change(LOC.header_page, header_current,cur);
menu_get_sizes(LOC.header_page, &li, &co);
if (top+li <= cur)
menu_header_change(LOC.header_page, header_top_line,cur);
else if (top > cur) {
top = cur-li+1;
if (top < 0)
top = 0;
menu_header_change(LOC.header_page, header_top_line,top);
}
}
} else {
if (isascii(ch) && isprint(ch))
lib_error(CATGETS(elm_msg_cat, MeSet,
MeThreadUnknownCommand,
"Unknown command: %c"),
ch);
else
lib_error(CATGETS(elm_msg_cat, MeSet,
MeUnknownCommand2,
"Unknown command."));
}
}
}
OUT:
free_mailbox_screen(&LOC);
erase_menu_context(&page);
if (mailbox_sort_needed)
resort_mailbox(mailbox,1);
menu_trigger_redraw(parent_page);
/* Force default return to parent page ... */
menu_set_default(parent_page);
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1