]> granicus.if.org Git - mutt/commitdiff
Add collapsing to the receive-attach menu, and improve digest
authorThomas Roessler <roessler@does-not-exist.org>
Sat, 27 Jan 2001 13:33:53 +0000 (13:33 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Sat, 27 Jan 2001 13:33:53 +0000 (13:33 +0000)
handling that way.

OPS
attach.c
attach.h
compose.c
functions.h
init.h
mutt.h
pager.c
pager.h
protos.h
recvattach.c

diff --git a/OPS b/OPS
index 9ed55ce54e64f4914d082c4e47f32490a321f4ad..ee15e7f9e7a69c93f5421c291407e54439961464 100644 (file)
--- 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"
index b4bfe5eb389843c7a3f874188a971b679b584dc8..1939f45aa2a9bc0ec064ee45104219e5a27a4fe2 100644 (file)
--- 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;
index c356130601cde018c3603daa3497c58ecff65fce..3e1cffdf7cccbbfe2ee502fc56d3b8f4011a0cbe 100644 (file)
--- a/attach.h
+++ b/attach.h
 /* 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 *);
index c43fa3219b1fe03ce3789f5bd24bdde621b59de1..141389ec07d5e26664140ee4ef0508412d2dc579 100644 (file)
--- 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;
 
index 0f2f1e59ac9f79d3d79e61a44190b65d2257aa80..77c036b4ff96d66f1b854d1bc4cc679e74ca7eef 100644 (file)
@@ -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 81e5e5ee999ad2491363726638ec7a018bd8c9c1..598fd4f2b261aa09305c2f99c28fc30c3d2b6390 100644 (file)
--- 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 59fc7d7f194a1020a455d3564d350acd38fa8544..6b6be1130bf6b59499d94e20f7cf151bf1479820 100644 (file)
--- 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 ed4f2c03983665ff592b2f45402f92a61baccb16..97042609c6e87cd1d7b753bb1e7ac08d34c2e8ba 100644 (file)
--- 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 70695a9967c31764ba0f9ff94a84f51426cff481..4c198316e9a422d6f6834f69d03d4a56c7b8570c 100644 (file)
--- 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)
 
index acd600dec2407627f2ffd11a00f072821e3e673f..dc6bab9a1fada57bccf1588780a90403ca14651a 100644 (file)
--- 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 *);
index 27c04e4ca76fdaf8c41cb6e8ae8b14c2fd6781fc..75180f46e6c94e8399af78527393c54571d605cd 100644 (file)
@@ -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;