From bfc0e8390b0f963d602a14d5890228a1b4458a57 Mon Sep 17 00:00:00 2001 From: Thomas Roessler Date: Sat, 27 Jan 2001 13:33:53 +0000 Subject: Add collapsing to the receive-attach menu, and improve digest handling that way. --- OPS | 1 + attach.c | 2 +- attach.h | 6 ++- compose.c | 3 +- functions.h | 6 +-- init.h | 6 +++ mutt.h | 3 +- pager.c | 6 +++ pager.h | 1 + protos.h | 1 + recvattach.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++------------- 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; -- cgit v1.2.3