summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2001-01-27 13:33:53 +0000
committerThomas Roessler <roessler@does-not-exist.org>2001-01-27 13:33:53 +0000
commitbfc0e8390b0f963d602a14d5890228a1b4458a57 (patch)
tree7d6721fbecae5da04cb33e358c88af4f9a1f33ec
parented6ec2db5d070b0be0826e6176d83c11f5947563 (diff)
Add collapsing to the receive-attach menu, and improve digest
handling that way.
-rw-r--r--OPS1
-rw-r--r--attach.c2
-rw-r--r--attach.h6
-rw-r--r--compose.c3
-rw-r--r--functions.h6
-rw-r--r--init.h6
-rw-r--r--mutt.h3
-rw-r--r--pager.c6
-rw-r--r--pager.h1
-rw-r--r--protos.h1
-rw-r--r--recvattach.c128
11 files changed, 127 insertions, 36 deletions
diff --git a/OPS b/OPS
index 9ed55ce5..ee15e7f9 100644
--- a/OPS
+++ b/OPS
@@ -1,6 +1,7 @@
OP_NULL "null operation"
OP_ATTACH_VIEW_MAILCAP "force viewing of attachment using mailcap"
OP_ATTACH_VIEW_TEXT "view attachment as text"
+OP_ATTACH_COLLAPSE "Toggle display of subparts"
OP_BOTTOM_PAGE "move to the bottom of the page"
OP_BOUNCE_MESSAGE "remail a message to another user"
OP_BROWSER_NEW_FILE "select a new file in this directory"
diff --git a/attach.c b/attach.c
index b4bfe5eb..1939f45a 100644
--- a/attach.c
+++ b/attach.c
@@ -575,7 +575,7 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag, HEADER *hdr,
info.hdr = hdr;
rc = mutt_do_pager (descrip, pagerfile,
- is_message ? M_PAGER_MESSAGE : 0, &info);
+ M_PAGER_ATTACHMENT | (is_message ? M_PAGER_MESSAGE : 0), &info);
}
else
rc = 0;
diff --git a/attach.h b/attach.h
index c3561306..3e1cffdf 100644
--- a/attach.h
+++ b/attach.h
@@ -19,12 +19,14 @@
/* common protos for compose / attach menus */
int mutt_tag_attach (MUTTMENU *menu, int n);
+int mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
+ BODY *cur, ATTACHPTR ***idxp, short *idxlen, short *idxmax,
+ int recv);
+
void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr);
void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter);
void mutt_print_attachment_list (FILE *fp, int tag, BODY *top);
-void mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
- BODY *cur, ATTACHPTR **idx, short *idxlen, short *idxmax);
void mutt_attach_bounce (FILE *, HEADER *, ATTACHPTR **, short, BODY *);
void mutt_attach_resend (FILE *, HEADER *, ATTACHPTR **, short, BODY *);
diff --git a/compose.c b/compose.c
index c43fa321..141389ec 100644
--- a/compose.c
+++ b/compose.c
@@ -533,6 +533,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
int oldSort, oldSortAux;
struct stat st;
+ mutt_attach_init (msg->content);
idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1);
menu = mutt_new_menu ();
@@ -1112,7 +1113,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
case OP_VIEW_ATTACH:
case OP_DISPLAY_HEADERS:
CHECK_COUNT;
- mutt_attach_display_loop (menu, op, NULL, NULL, NULL, idx, &idxlen, NULL);
+ mutt_attach_display_loop (menu, op, NULL, NULL, NULL, &idx, &idxlen, NULL, 0);
menu->redraw = REDRAW_FULL;
break;
diff --git a/functions.h b/functions.h
index 0f2f1e59..77c036b4 100644
--- a/functions.h
+++ b/functions.h
@@ -242,7 +242,7 @@ struct binding_t OpPager[] = {
struct binding_t OpAttach[] = {
{ "bounce-message", OP_BOUNCE_MESSAGE, "b" },
- { "display-toggle-weed", OP_DISPLAY_HEADERS, "h" },
+ { "display-toggle-weed", OP_DISPLAY_HEADERS, "h" },
{ "edit-type", OP_EDIT_TYPE, "\005" },
{ "print-entry", OP_PRINT, "p" },
{ "save-entry", OP_SAVE, "s" },
@@ -257,8 +257,8 @@ struct binding_t OpAttach[] = {
{ "view-attach", OP_VIEW_ATTACH, M_ENTER_S },
{ "delete-entry", OP_DELETE, "d" },
{ "undelete-entry", OP_UNDELETE, "u" },
-
-
+ { "collapse-parts", OP_ATTACH_COLLAPSE, "v" },
+
#ifdef HAVE_PGP
{ "extract-keys", OP_EXTRACT_KEYS, "\013" },
diff --git a/init.h b/init.h
index 81e5e5ee..598fd4f2 100644
--- a/init.h
+++ b/init.h
@@ -377,6 +377,12 @@ struct option_t MuttVars[] = {
** for deletion. This applies when you either explicitly delete a message,
** or when you save it to another folder.
*/
+ { "digest_collapse", DT_BOOL, R_NONE, OPTDIGESTCOLLAPSE, 1},
+ /*
+ ** .pp
+ ** If this option is \fIset\fP, mutt's revattach menu will not show the subparts of
+ ** individual messages in a digest. To see these subparts, press 'v' on that menu.
+ */
{ "display_filter", DT_PATH, R_PAGER, UL &DisplayFilter, UL "" },
/*
** .pp
diff --git a/mutt.h b/mutt.h
index 59fc7d7f..6b6be113 100644
--- a/mutt.h
+++ b/mutt.h
@@ -305,6 +305,7 @@ enum
OPTCONFIRMAPPEND,
OPTCONFIRMCREATE,
OPTDELETEUNTAG,
+ OPTDIGESTCOLLAPSE,
OPTEDITHDRS,
OPTENCODEFROM,
OPTENVFROM,
@@ -424,7 +425,6 @@ enum
* functions while we are executing an
* external program.
*/
-
#ifdef HAVE_PGP
OPTPGPCHECKTRUST, /* (pseudo) used by pgp_select_key () */
OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */
@@ -573,6 +573,7 @@ typedef struct body
unsigned int goodsig : 1; /* good PGP signature */
#endif
+ unsigned int collapsed : 1; /* used by recvattach */
} BODY;
diff --git a/pager.c b/pager.c
index ed4f2c03..97042609 100644
--- a/pager.c
+++ b/pager.c
@@ -2417,6 +2417,12 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
break;
case OP_VIEW_ATTACHMENTS:
+ if (flags & M_PAGER_ATTACHMENT)
+ {
+ ch = -1;
+ rc = OP_ATTACH_COLLAPSE;
+ break;
+ }
CHECK_MODE(IsHeader (extra));
mutt_view_attachments (extra->hdr);
if (extra->hdr->attach_del)
diff --git a/pager.h b/pager.h
index 70695a99..4c198316 100644
--- a/pager.h
+++ b/pager.h
@@ -29,6 +29,7 @@
#define M_PAGER_MARKER (1<<6) /* use markers if option is set */
#define M_PAGER_RETWINCH (1<<7) /* need reformatting on SIGWINCH */
#define M_PAGER_MESSAGE (M_SHOWCOLOR | M_PAGER_MARKER)
+#define M_PAGER_ATTACHMENT (1<<8)
#define M_DISPLAYFLAGS (M_SHOW | M_PAGER_NSKIP | M_PAGER_MARKER)
diff --git a/protos.h b/protos.h
index acd600de..dc6bab9a 100644
--- a/protos.h
+++ b/protos.h
@@ -139,6 +139,7 @@ const char *mutt_fqdn(short);
void mutt_adv_mktemp (char *, size_t);
void mutt_alias_menu (char *, size_t, ALIAS *);
void mutt_allow_interrupt (int);
+void mutt_attach_init (BODY *);
void mutt_block_signals (void);
void mutt_block_signals_system (void);
void mutt_body_handler (BODY *, STATE *);
diff --git a/recvattach.c b/recvattach.c
index 27c04e4c..75180f46 100644
--- a/recvattach.c
+++ b/recvattach.c
@@ -111,11 +111,16 @@ ATTACHPTR **mutt_gen_attach_list (BODY *m,
int compose)
{
ATTACHPTR *new;
-
+ int i;
+
for (; m; m = m->next)
{
if (*idxlen == *idxmax)
- safe_realloc ((void **) &idx, sizeof (ATTACHPTR *) * (*idxmax += 5));
+ {
+ safe_realloc ((void **) &idx, sizeof (ATTACHPTR *) * ((*idxmax) += 5));
+ for (i = *idxlen; i < *idxmax; i++)
+ idx[i] = NULL;
+ }
if (m->type == TYPEMULTIPART && m->parts
&& (compose || (parent_type == -1 && mutt_strcasecmp ("alternative", m->subtype)))
@@ -128,15 +133,16 @@ ATTACHPTR **mutt_gen_attach_list (BODY *m,
}
else
{
- new = idx[(*idxlen)++] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR));
+ if (!idx[*idxlen])
+ idx[*idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR));
+
+ new = idx[(*idxlen)++];
new->content = m;
new->parent_type = parent_type;
new->level = level;
- /* called when creating new menu, so clear the tagged indicator */
- m->tagged = 0;
/* We don't support multipart messages in the compose menu yet */
- if (!compose &&
+ if (!compose && !m->collapsed &&
((m->type == TYPEMULTIPART
#ifdef HAVE_PGP
&& !mutt_is_multipart_encrypted (m)
@@ -682,29 +688,35 @@ void mutt_print_attachment_list (FILE *fp, int tag, BODY *top)
print_attachment_list (fp, tag, top, &state);
}
-ATTACHPTR **mutt_update_attach_index (BODY *cur, ATTACHPTR **idx,
+void
+mutt_update_attach_index (BODY *cur, ATTACHPTR ***idxp,
short *idxlen, short *idxmax,
MUTTMENU *menu)
{
+ ATTACHPTR **idx = *idxp;
+ while (--(*idxlen) >= 0)
+ idx[(*idxlen)]->content = NULL;
*idxlen = 0;
- idx = mutt_gen_attach_list (cur, -1, idx, idxlen, idxmax, 0, 0);
+
+ idx = *idxp = mutt_gen_attach_list (cur, -1, idx, idxlen, idxmax, 0, 0);
menu->max = *idxlen;
- menu->data = idx;
+ menu->data = *idxp;
if (menu->current >= menu->max)
menu->current = menu->max - 1;
menu_check_recenter (menu);
menu->redraw |= REDRAW_INDEX;
- return idx;
}
-void
+int
mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
- BODY *cur, ATTACHPTR **idx, short *idxlen, short *idxmax)
+ BODY *cur, ATTACHPTR ***idxp, short *idxlen, short *idxmax,
+ int recv)
{
+ ATTACHPTR **idx = *idxp;
#if 0
int old_optweed = option (OPTWEED);
set_option (OPTWEED);
@@ -747,10 +759,16 @@ mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
/* when we edit the content-type, we should redisplay the attachment
immediately */
mutt_edit_content_type (hdr, idx[menu->current]->content, fp);
- if (idxmax)
- mutt_update_attach_index (cur, idx, idxlen, idxmax, menu);
+ if (idxmax)
+ {
+ mutt_update_attach_index (cur, idxp, idxlen, idxmax, menu);
+ idx = *idxp;
+ }
op = OP_VIEW_ATTACH;
break;
+ case OP_ATTACH_COLLAPSE:
+ if (recv)
+ return op;
default:
op = OP_NULL;
}
@@ -761,8 +779,36 @@ mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
if (option (OPTWEED) != old_optweed)
toggle_option (OPTWEED);
#endif
+ return op;
+}
+
+static void attach_collapse (BODY *b, short collapse, short init, short just_one)
+{
+ short i;
+ for (; b; b = b->next)
+ {
+ i = init || b->collapsed;
+ if (i && option (OPTDIGESTCOLLAPSE) && b->type == TYPEMULTIPART
+ && !mutt_strcasecmp (b->subtype, "digest"))
+ attach_collapse (b->parts, 1, 1, 0);
+ else if (b->type == TYPEMULTIPART || mutt_is_message_type (b->type, b->subtype))
+ attach_collapse (b->parts, collapse, i, 0);
+ b->collapsed = collapse;
+ if (just_one)
+ return;
+ }
}
+void mutt_attach_init (BODY *b)
+{
+ for (; b; b = b->next)
+ {
+ b->tagged = 0;
+ b->collapsed = 0;
+ if (b->parts)
+ mutt_attach_init (b->parts);
+ }
+}
static const char *Function_not_permitted = N_("Function not permitted in attach-message mode.");
@@ -775,6 +821,7 @@ static const char *Function_not_permitted = N_("Function not permitted in attach
+
void mutt_view_attachments (HEADER *hdr)
{
@@ -837,19 +884,14 @@ void mutt_view_attachments (HEADER *hdr)
menu->tag = mutt_tag_attach;
menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_ATTACH, AttachHelp);
-
- idx = mutt_update_attach_index (cur, idx, &idxlen, &idxmax, menu);
+ mutt_attach_init (cur);
+ attach_collapse (cur, 0, 1, 0);
+ mutt_update_attach_index (cur, &idx, &idxlen, &idxmax, menu);
FOREVER
{
switch (op = mutt_menuLoop (menu))
{
- case OP_DISPLAY_HEADERS:
- case OP_VIEW_ATTACH:
- mutt_attach_display_loop (menu, op, fp, hdr, cur, idx, &idxlen, &idxmax);
- menu->redraw = REDRAW_FULL;
- break;
-
case OP_ATTACH_VIEW_MAILCAP:
mutt_view_attachment (fp, idx[menu->current]->content, M_MAILCAP,
hdr, idx, idxlen);
@@ -862,7 +904,35 @@ void mutt_view_attachments (HEADER *hdr)
menu->redraw = REDRAW_FULL;
break;
-
+ case OP_DISPLAY_HEADERS:
+ case OP_VIEW_ATTACH:
+ op = mutt_attach_display_loop (menu, op, fp, hdr, cur, &idx, &idxlen, &idxmax, 1);
+ menu->redraw = REDRAW_FULL;
+ if (op != OP_ATTACH_COLLAPSE)
+ break;
+ /* else fall through - hack! */
+ case OP_ATTACH_COLLAPSE:
+ if (!idx[menu->current]->content->collapsed)
+ {
+ if (!idx[menu->current]->content->parts)
+ {
+ mutt_error _("There are no subparts to hide!");
+ break;
+ }
+ attach_collapse (idx[menu->current]->content, 1, 0, 1);
+ }
+ else
+ {
+ if (!idx[menu->current]->content->parts)
+ {
+ mutt_error _("There are no subparts to show!");
+ break;
+ }
+ attach_collapse (idx[menu->current]->content, 0, 1, 1);
+ }
+ mutt_update_attach_index (cur, &idx, &idxlen, &idxmax, menu);
+ break;
+
#ifdef HAVE_PGP
case OP_EXTRACT_KEYS:
@@ -1021,18 +1091,20 @@ void mutt_view_attachments (HEADER *hdr)
case OP_EDIT_TYPE:
mutt_edit_content_type (hdr, idx[menu->current]->content, fp);
- mutt_update_attach_index (cur, idx, &idxlen, &idxmax, menu);
+ mutt_update_attach_index (cur, &idx, &idxlen, &idxmax, menu);
break;
case OP_EXIT:
mx_close_message (&msg);
hdr->attach_del = 0;
- while (idxlen-- > 0)
+ while (idxmax-- > 0)
{
- if (idx[idxlen]->content->deleted)
+ if (!idx[idxmax])
+ continue;
+ if (idx[idxmax]->content && idx[idxmax]->content->deleted)
hdr->attach_del = 1;
- safe_free ((void **) &idx[idxlen]->tree);
- safe_free ((void **) &idx[idxlen]);
+ safe_free ((void **) &idx[idxmax]->tree);
+ safe_free ((void **) &idx[idxmax]);
}
if (hdr->attach_del)
hdr->changed = 1;