/*
* Copyright (C) 1996-2000,2002 Michael R. Elkins <me@mutt.org>
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
+ */
#if HAVE_CONFIG_H
# include "config.h"
mutt_error _(No_visible); \
break; \
}
-
+
#define CHECK_READONLY if (Context->readonly) \
{ \
/* store pointers to the newly added messages */
HEADER **save_new = NULL;
int j;
-
+
/* take note of the current message */
if (oldcount)
{
else
oldcount = 0; /* invalid message number! */
}
-
+
/* We are in a limited view. Check if the new message(s) satisfy
* the limit criteria. If they do, set their virtual msgno so that
* they will be visible in the limited view */
ctx->vcount = 0;
if (mutt_pattern_exec (ctx->limit_pattern,
- M_MATCH_FULL_ADDRESS,
+ M_MATCH_FULL_ADDRESS,
ctx, ctx->hdrs[j]))
{
assert (ctx->vcount < ctx->msgcount);
}
#undef THIS_BODY
}
-
+
/* save the list of new messages */
if (oldcount && check != M_REOPENED
&& ((Sort & SORT_MASK) == SORT_THREADS))
for (j = oldcount; j < ctx->msgcount; j++)
save_new[j-oldcount] = ctx->hdrs[j];
}
-
+
/* if the mailbox was reopened, need to rethread from scratch */
mutt_sort_headers (ctx, (check == M_REOPENED));
if (check == M_REOPENED)
{
THREAD *h, *j;
-
+
ctx->collapsed = 0;
-
+
for (h = ctx->tree; h; h = h->next)
{
for (j = h; !j->message; j = j->child)
for (j = 0; j < ctx->msgcount - oldcount; j++)
{
int k;
-
+
for (k = 0; k < ctx->msgcount; k++)
{
HEADER *h = ctx->hdrs[k];
mutt_set_virtual (ctx);
}
}
-
+
menu->current = -1;
if (oldcount)
{
}
}
}
-
+
if (menu->current < 0)
menu->current = ci_first_message ();
-
+
}
static void resort_index (MUTTMENU *menu)
break;
}
}
-
+
if ((Sort & SORT_MASK) == SORT_THREADS && menu->current < 0)
menu->current = mutt_parent_message (Context, current);
-
+
if (menu->current < 0)
menu->current = ci_first_message ();
-
+
menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
}
{ N_("Reply"), OP_REPLY },
{ N_("Group"), OP_GROUP_REPLY },
{ N_("Help"), OP_HELP },
- { NULL }
+ { NULL, 0 }
};
/* This function handles the message index window as well as commands returned
int do_buffy_notify = 1;
int close = 0; /* did we OP_QUIT or OP_EXIT out of this menu? */
int attach_msg = option(OPTATTACHMSG);
-
+
menu = mutt_new_menu (MENU_MAIN);
menu->offset = 1;
menu->pagelen = LINES - 3;
menu->color = index_color;
menu->current = ci_first_message ();
menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MAIN, IndexHelp);
-
- if (!attach_msg)
+
+ if (!attach_msg)
mutt_buffy_check(1); /* force the buffy check after we enter the folder */
FOREVER
* any 'op' below could do mutt_enter_command(), either here or
* from any new menu launched, and change $sort/$sort_aux
*/
- if (option (OPTNEEDRESORT) && Context && Context->msgcount)
+ if (option (OPTNEEDRESORT) && Context && Context->msgcount && menu->current >= 0)
resort_index (menu);
menu->max = Context ? Context->vcount : 0;
* modified underneath us.)
*/
-#ifdef USE_IMAP
- imap_allow_reopen (Context);
-#endif
-
index_hint = (Context->vcount && menu->current >= 0 && menu->current < Context->vcount) ? CURHDR->index : 0;
if ((check = mx_check_mailbox (Context, &index_hint, 0)) < 0)
else if (check == M_NEW_MAIL || check == M_REOPENED || check == M_FLAGS)
{
update_index (menu, Context, check, oldcount, index_hint);
-
+
/* notify the user of new mail */
if (check == M_REOPENED)
mutt_error _("Mailbox was externally modified. Flags may be wrong.");
/* avoid the message being overwritten by buffy */
do_buffy_notify = 0;
-
+
menu->redraw = REDRAW_FULL;
menu->max = Context->vcount;
-
+
set_option (OPTSEARCHINVALID);
}
}
menu_redraw_current (menu);
}
- if (menu->redraw & REDRAW_STATUS)
+ if (menu->redraw & REDRAW_STATUS)
{
menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
CLEARLINE (option (OPTSTATUSONTOP) ? 0 : LINES-2);
if (op == -1)
continue; /* either user abort or timeout */
-
+
mutt_curs_set (1);
-
+
/* special handling for the tag-prefix function */
if (op == OP_TAG_PREFIX)
{
menu->oldcurrent = menu->current;
else
menu->oldcurrent = -1;
-
+
mutt_curs_set (1); /* fallback from the pager */
}
-#ifdef USE_IMAP
- imap_disallow_reopen (Context);
-#endif
-
switch (op)
{
|| !buf[0])
break;
- if (! isdigit ((unsigned char) buf[0]))
+ if (mutt_atoi (buf, &i) < 0)
{
mutt_error _("Argument must be a message number.");
break;
}
- i = atoi (buf);
if (i > 0 && i <= Context->msgcount)
{
for (j = i-1; j < Context->msgcount; j++)
}
if (Context->pattern)
mutt_message _("To view all messages, limit to \"all\".");
- break;
+ break;
case OP_QUIT:
if (query_quadoption (OPT_QUIT, _("Quit Mutt?")) == M_YES)
{
int check;
-
+
oldcount = Context ? Context->msgcount : 0;
if (!Context || (check = mx_close_mailbox (Context, &index_hint)) == 0)
resort_index (menu);
set_option (OPTSEARCHINVALID);
}
+ if (menu->menu == MENU_PAGER)
+ {
+ op = OP_DISPLAY_MESSAGE;
+ continue;
+ }
menu->redraw |= REDRAW_STATUS;
}
break;
if (Context && Context->magic == M_IMAP)
imap_check_mailbox (Context, &index_hint, 1);
break;
+
+ case OP_MAIN_IMAP_LOGOUT_ALL:
+ if (Context && Context->magic == M_IMAP)
+ {
+ if (mx_close_mailbox (Context, &index_hint) != 0)
+ {
+ set_option (OPTSEARCHINVALID);
+ menu->redraw = REDRAW_FULL;
+ break;
+ }
+ FREE (&Context);
+ }
+ imap_logout_all();
+ mutt_message _("Logged out of IMAP servers.");
+ set_option (OPTSEARCHINVALID);
+ menu->redraw = REDRAW_FULL;
+ break;
#endif
-
+
case OP_MAIN_SYNC_FOLDER:
if (Context && !Context->msgcount)
{
int oldvcount = Context->vcount;
int oldcount = Context->msgcount;
- int dcount = 0;
- int check;
-
- /* calculate the number of messages _above_ the cursor,
- * so we can keep the cursor on the current message
- */
- for (j = 0; j <= menu->current; j++)
- {
- if (Context->hdrs[Context->v2r[j]]->deleted)
- dcount++;
- }
+ int check, newidx;
+ HEADER *newhdr = NULL;
+
+ /* threads may be reordered, so figure out what header the cursor
+ * should be on. #3092 */
+ newidx = menu->current;
+ if (CURHDR->deleted)
+ newidx = ci_next_undeleted (menu->current);
+ if (newidx < 0)
+ newidx = ci_previous_undeleted (menu->current);
+ if (newidx >= 0)
+ newhdr = Context->hdrs[Context->v2r[newidx]];
if ((check = mx_sync_mailbox (Context, &index_hint)) == 0)
{
- if (Context->vcount != oldvcount)
- menu->current -= dcount;
+ if (newhdr && Context->vcount != oldvcount)
+ for (j = 0; j < Context->vcount; j++)
+ {
+ if (Context->hdrs[Context->v2r[j]] == newhdr)
+ {
+ menu->current = j;
+ break;
+ }
+ }
set_option (OPTSEARCHINVALID);
}
else if (check == M_NEW_MAIL || check == M_REOPENED)
update_index (menu, Context, check, oldcount, index_hint);
- /*
+ /*
* do a sanity check even if mx_sync_mailbox failed.
*/
case OP_MAIN_CHANGE_FOLDER:
case OP_MAIN_NEXT_UNREAD_MAILBOX:
-
+
if (attach_msg)
op = OP_MAIN_CHANGE_FOLDER_READONLY;
}
mutt_str_replace (&CurrentFolder, buf);
+ /* keepalive failure in mutt_enter_fname may kill connection. #3028 */
+ if (Context && !Context->path)
+ FREE (&Context);
+
if (Context)
{
int check;
{
if (check == M_NEW_MAIL || check == M_REOPENED)
update_index (menu, Context, check, oldcount, index_hint);
-
+
set_option (OPTSEARCHINVALID);
menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
break;
}
mutt_sleep (0);
-
+
/* Set CurrentMenu to MENU_MAIN before executing any folder
* hooks so that all the index menu functions are available to
* the exec command.
CurrentMenu = MENU_MAIN;
mutt_folder_hook (buf);
- if ((Context = mx_open_mailbox (buf,
+ if ((Context = mx_open_mailbox (buf,
(option (OPTREADONLY) || op == OP_MAIN_CHANGE_FOLDER_READONLY) ?
M_READONLY : 0, NULL)) != NULL)
{
if (option (OPTUNCOLLAPSEJUMP))
menu->current = mutt_thread_next_unread (Context, CURHDR);
}
-
- if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
+
+ if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
if ((op = mutt_display_message (CURHDR)) == -1)
{
}
if ((menu->menu == MENU_MAIN)
- && (query_quadoption (OPT_QUIT,
+ && (query_quadoption (OPT_QUIT,
_("Exit Mutt without saving?")) == M_YES))
{
if (Context)
if ((Sort & SORT_MASK) != SORT_THREADS)
mutt_error _("Threading is not enabled.");
- else
+ else if (CURHDR->env->in_reply_to || CURHDR->env->references)
{
{
HEADER *oldcur = CURHDR;
else
menu->redraw |= REDRAW_INDEX;
}
+ else
+ mutt_error _("Thread cannot be broken, message is not part of a thread");
- break;
+ break;
case OP_MAIN_LINK_THREADS:
mutt_error _("No Message-ID: header available to link thread");
else if (!tag && (!Context->last_tag || !Context->last_tag->tagged))
mutt_error _("First, please tag a message to be linked here");
- else
+ else
{
HEADER *oldcur = CURHDR;
{
mutt_sort_headers (Context, 1);
menu->current = oldcur->virtual;
-
+
Context->changed = 1;
mutt_message _("Threads linked");
}
case OP_DECRYPT_COPY:
case OP_DECRYPT_SAVE:
if (!WithCrypto)
- break;
+ break;
/* fall thru */
case OP_COPY_MESSAGE:
case OP_SAVE:
{
int first_unread = -1;
int first_new = -1;
-
+
CHECK_MSGCOUNT;
CHECK_VISIBLE;
menu->current = -1;
for (j = 0; j != Context->vcount; j++)
{
-#define CURHDRi Context->hdrs[Context->v2r[i]]
+#define CURHDRi Context->hdrs[Context->v2r[i]]
if (op == OP_MAIN_NEXT_NEW || op == OP_MAIN_NEXT_UNREAD || op == OP_MAIN_NEXT_NEW_THEN_UNREAD)
{
i++;
if ((!CURHDRi->old) && first_new == -1)
first_new = i;
}
-
+
if ((op == OP_MAIN_NEXT_UNREAD || op == OP_MAIN_PREV_UNREAD) &&
first_unread != -1)
break;
}
#undef CURHDRi
if ((op == OP_MAIN_NEXT_NEW || op == OP_MAIN_PREV_NEW ||
- op == OP_MAIN_NEXT_NEW_THEN_UNREAD || op == OP_MAIN_PREV_NEW_THEN_UNREAD)
+ op == OP_MAIN_NEXT_NEW_THEN_UNREAD || op == OP_MAIN_PREV_NEW_THEN_UNREAD)
&& first_new != -1)
menu->current = first_new;
else if ((op == OP_MAIN_NEXT_UNREAD || op == OP_MAIN_PREV_UNREAD ||
case OP_MAIN_NEXT_SUBTHREAD:
menu->current = mutt_next_subthread (CURHDR);
break;
-
+
case OP_MAIN_PREV_THREAD:
menu->current = mutt_previous_thread (CURHDR);
break;
mutt_error _("Threading is not enabled.");
break;
}
-
+
if (CURHDR->collapsed)
{
menu->current = mutt_uncollapse_thread (Context, CURHDR);
HEADER *h, *base;
THREAD *thread, *top;
int final;
-
+
if (CURHDR->collapsed)
final = mutt_uncollapse_thread (Context, CURHDR);
else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (CURHDR))
final = mutt_collapse_thread (Context, CURHDR);
else
final = CURHDR->virtual;
-
+
base = Context->hdrs[Context->v2r[final]];
-
+
top = Context->tree;
Context->collapsed = !Context->collapsed;
while ((thread = top) != NULL)
}
top = top->next;
}
-
+
mutt_set_virtual (Context);
for (j = 0; j < Context->vcount; j++)
{
break;
}
}
-
+
menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
}
break;
-
+
/* --------------------------------------------------------------------
* These functions are invoked directly from the internal-pager
*/
if (rc != -1)
{
if (option (OPTDELETEUNTAG))
- mutt_thread_set_flag (CURHDR, M_TAG, 0,
+ mutt_thread_set_flag (CURHDR, M_TAG, 0,
op == OP_DELETE_THREAD ? 0 : 1);
if (option (OPTRESOLVE))
if ((menu->current = ci_next_undeleted (menu->current)) == -1)
CHECK_ATTACH;
CHECK_ACL(M_ACL_INSERT, _("edit message"));
- if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
+ if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
mutt_edit_message (Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_ATTACH;
- if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
+ if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
ci_send_message (SENDFORWARD, NULL, NULL, Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_ATTACH;
- if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
+ if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
ci_send_message (SENDREPLY|SENDGROUPREPLY, NULL, NULL, Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
CHECK_ATTACH;
CHECK_MSGCOUNT;
CHECK_VISIBLE;
- if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
+ if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
ci_send_message (SENDREPLY|SENDLISTREPLY, NULL, NULL, Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
menu->redraw = REDRAW_FULL;
break;
-
+
case OP_EXTRACT_KEYS:
if (!WithCrypto)
break;
case OP_CHECK_TRADITIONAL:
if (!(WithCrypto & APPLICATION_PGP))
break;
- CHECK_MSGCOUNT;
+ CHECK_MSGCOUNT;
CHECK_VISIBLE;
- if (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))
+ if (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
-
+
if (menu->menu == MENU_PAGER)
{
op = OP_DISPLAY_MESSAGE;
{
if (option (OPTRESOLVE))
{
- if ((menu->current = (op == OP_MAIN_READ_THREAD ?
+ if ((menu->current = (op == OP_MAIN_READ_THREAD ?
mutt_next_thread (CURHDR) : mutt_next_subthread (CURHDR))) == -1)
menu->current = menu->oldcurrent;
+ else if (menu->menu == MENU_PAGER)
+ {
+ op = OP_DISPLAY_MESSAGE;
+ continue;
+ }
}
menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
}
break;
case OP_RESEND:
-
+
CHECK_ATTACH;
CHECK_MSGCOUNT;
CHECK_VISIBLE;
-
+
if (tag)
{
for (j = 0; j < Context->vcount; j++)
}
else
mutt_resend_message (NULL, Context, CURHDR);
-
+
menu->redraw = REDRAW_FULL;
break;
-
+
case OP_REPLY:
CHECK_ATTACH;
CHECK_MSGCOUNT;
CHECK_VISIBLE;
- if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
+ if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
ci_send_message (SENDREPLY, NULL, NULL, Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
CHECK_VISIBLE;
rc = mutt_thread_set_flag (CURHDR, M_TAG, !CURHDR->tagged,
op == OP_TAG_THREAD ? 0 : 1);
-
+
if (rc != -1)
{
if (option (OPTRESOLVE))
CHECK_VISIBLE;
CHECK_READONLY;
CHECK_ACL(M_ACL_DELETE, _("undelete message"));
-
+
if (tag)
{
mutt_tag_set_flag (M_DELETE, 0);
if (!curhdr)
return;
-
+
for (color = ColorIndexList; color; color = color->next)
if (mutt_pattern_exec (color->color_pattern, M_MATCH_FULL_ADDRESS, ctx, curhdr))
{