/*
* Copyright notice from original mutt:
* Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
*
* This file is part of mutt-ng, see http://www.muttng.org/.
* It's licensed under the GNU General Public License,
* please see the file GPL in the top level source directory.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "mutt.h"
#include "mutt_curses.h"
#include "mutt_menu.h"
#include "sort.h"
#include "mx.h"
#include "sidebar.h"
#ifdef USE_IMAP
#include "imap_private.h"
#endif
#include "lib/intl.h"
void _mutt_set_flag (CONTEXT * ctx, HEADER * h, int flag, int bf, int upd_ctx)
{
int changed = h->changed;
int deleted = ctx->deleted;
int tagged = ctx->tagged;
int flagged = ctx->flagged;
if (ctx->readonly && flag != M_TAG)
return; /* don't modify anything if we are read-only */
switch (flag) {
case M_DELETE:
if (!mx_acl_check (ctx, ACL_DELETE))
return;
if (bf) {
if (!h->deleted && !ctx->readonly) {
h->deleted = 1;
if (upd_ctx)
ctx->deleted++;
#ifdef USE_IMAP
/* deleted messages aren't treated as changed elsewhere so that the
* purge-on-sync option works correctly. This isn't applicable here */
if (ctx && ctx->magic == M_IMAP) {
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
#endif
}
}
else if (h->deleted) {
h->deleted = 0;
if (upd_ctx) {
ctx->deleted--;
if (h->appended)
ctx->appended--;
}
h->appended = 0; /* when undeleting, also reset the appended flag */
#ifdef USE_IMAP
/* see my comment above */
if (ctx->magic == M_IMAP) {
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
#endif
/*
* If the user undeletes a message which is marked as
* "trash" in the maildir folder on disk, the folder has
* been changed, and is marked accordingly. However, we do
* _not_ mark the message itself changed, because trashing
* is checked in specific code in the maildir folder
* driver.
*/
if (ctx->magic == M_MAILDIR && upd_ctx && h->trash)
ctx->changed = 1;
}
break;
case M_APPENDED:
if (bf) {
if (!h->appended) {
h->appended = 1;
if (upd_ctx)
ctx->appended++;
}
}
break;
case M_PURGED:
if (bf) {
if (!h->purged)
h->purged = 1;
}
else if (h->purged)
h->purged = 0;
break;
case M_NEW:
if (!mx_acl_check (ctx, ACL_SEEN))
return;
if (bf) {
if (h->read || h->old) {
h->old = 0;
if (upd_ctx)
ctx->new++;
if (h->read) {
h->read = 0;
if (upd_ctx)
ctx->unread++;
}
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
}
else if (!h->read) {
if (!h->old)
if (upd_ctx)
ctx->new--;
h->read = 1;
if (upd_ctx)
ctx->unread--;
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
break;
case M_OLD:
if (!mx_acl_check (ctx, ACL_SEEN))
return;
if (bf) {
if (!h->old) {
h->old = 1;
if (!h->read)
if (upd_ctx)
ctx->new--;
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
}
else if (h->old) {
h->old = 0;
if (!h->read)
if (upd_ctx)
ctx->new++;
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
break;
case M_READ:
if (!mx_acl_check (ctx, ACL_SEEN))
return;
if (bf) {
if (!h->read) {
h->read = 1;
if (upd_ctx)
ctx->unread--;
if (!h->old)
if (upd_ctx)
ctx->new--;
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
}
else if (h->read) {
h->read = 0;
if (upd_ctx)
ctx->unread++;
if (!h->old)
if (upd_ctx)
ctx->new++;
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
break;
case M_REPLIED:
if (!mx_acl_check (ctx, ACL_WRITE))
return;
if (bf) {
if (!h->replied) {
h->replied = 1;
if (!h->read) {
h->read = 1;
if (upd_ctx)
ctx->unread--;
if (!h->old)
if (upd_ctx)
ctx->new--;
}
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
}
else if (h->replied) {
h->replied = 0;
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
break;
case M_FLAG:
if (!mx_acl_check (ctx, ACL_WRITE))
return;
if (bf) {
if (!h->flagged) {
h->flagged = bf;
if (upd_ctx)
ctx->flagged++;
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
}
else if (h->flagged) {
h->flagged = 0;
if (upd_ctx)
ctx->flagged--;
h->changed = 1;
if (upd_ctx)
ctx->changed = 1;
}
break;
case M_TAG:
if (bf) {
if (!h->tagged) {
h->tagged = 1;
if (upd_ctx)
ctx->tagged++;
}
}
else if (h->tagged) {
h->tagged = 0;
if (upd_ctx)
ctx->tagged--;
}
break;
}
mutt_set_header_color (ctx, h);
/* if the message status has changed, we need to invalidate the cached
* search results so that any future search will match the current status
* of this message and not what it was at the time it was last searched.
*/
if (h->searched && (changed != h->changed || deleted != ctx->deleted ||
tagged != ctx->tagged || flagged != ctx->flagged))
h->searched = 0;
sidebar_draw (0);
}
void mutt_tag_set_flag (int flag, int bf)
{
int j;
for (j = 0; j < Context->vcount; j++)
if (Context->hdrs[Context->v2r[j]]->tagged)
mutt_set_flag (Context, Context->hdrs[Context->v2r[j]], flag, bf);
}
int mutt_thread_set_flag (HEADER * hdr, int flag, int bf, int subthread)
{
THREAD *start, *cur = hdr->thread;
if ((Sort & SORT_MASK) != SORT_THREADS) {
mutt_error _("Threading is not enabled.");
return (-1);
}
if (!subthread)
while (cur->parent)
cur = cur->parent;
start = cur;
if (cur->message)
mutt_set_flag (Context, cur->message, flag, bf);
if ((cur = cur->child) == NULL)
return (0);
FOREVER {
if (cur->message)
mutt_set_flag (Context, cur->message, flag, bf);
if (cur->child)
cur = cur->child;
else if (cur->next)
cur = cur->next;
else {
while (!cur->next) {
cur = cur->parent;
if (cur == start)
return (0);
}
cur = cur->next;
}
}
/* not reached */
}
int mutt_change_flag (HEADER * h, int bf)
{
int i, flag;
event_t event;
mvprintw (LINES - 1, 0, "%s? (D/N/O/r/*/!): ",
bf ? _("Set flag") : _("Clear flag"));
clrtoeol ();
event = mutt_getch ();
i = event.ch;
if (i == -1) {
CLEARLINE (LINES - 1);
return (-1);
}
CLEARLINE (LINES - 1);
switch (i) {
case 'd':
case 'D':
flag = M_DELETE;
break;
case 'N':
case 'n':
flag = M_NEW;
break;
case 'o':
case 'O':
if (h)
mutt_set_flag (Context, h, M_READ, !bf);
else
mutt_tag_set_flag (M_READ, !bf);
flag = M_OLD;
break;
case 'r':
case 'R':
flag = M_REPLIED;
break;
case '*':
flag = M_TAG;
break;
case '!':
flag = M_FLAG;
break;
default:
BEEP ();
return (-1);
}
if (h)
mutt_set_flag (Context, h, flag, bf);
else
mutt_tag_set_flag (flag, bf);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1