Changeset 3495:14ec8eba0341

Show
Ignore:
Timestamp:
2003-10-04 13:34:59 (5 years ago)
Author:
Thomas Roessler <roessler@…>
Branch:
HEAD
Message:

This patch fixes various aspects of the attachment-saving
user interface. Changes include:

* When tagging and saving multiple attachments, you can now use the

same target directory for multiple attachments.

* When you can't save an attachment, you get an opportunity to enter

a new file name.

* The menu cursor will highlight the attachment that you are

currently discussing with mutt.

* Various bug fixes.

This does, in particular, address #1619 (Debian#208430).

Files:
13 modified

Legend:

Unmodified
Added
Removed
  • attach.h

    r3179 r3495  
    2525 
    2626 
    27 void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr); 
     27void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu); 
    2828void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter); 
    2929void mutt_print_attachment_list (FILE *fp, int tag, BODY *top); 
  • commands.c

    r3447 r3495  
    762762 
    763763  /* check to make sure that this file is really the one the user wants */ 
    764   if (!mutt_save_confirm (buf, &st)) 
     764  if (mutt_save_confirm (buf, &st) != 0) 
    765765    return -1; 
    766766 
  • compose.c

    r3480 r3495  
    484484  if (idxlen) 
    485485    idx[idxlen - 1]->content->next = idx[idxlen]->content; 
     486  idx[idxlen]->content->aptr = idx[idxlen]; 
    486487  menu->current = idxlen++; 
    487488  mutt_update_tree (idx, idxlen); 
     
    761762        if ((idx[idxlen]->content = crypt_pgp_make_key_attachment(NULL)) != NULL) 
    762763        { 
    763           idx[idxlen]->level = (idxlen > 0) ? idx[idxlen-1]->level : 0; 
    764  
    765           if(idxlen) 
    766             idx[idxlen - 1]->content->next = idx[idxlen]->content; 
    767            
    768           menu->current = idxlen++; 
    769           mutt_update_tree (idx, idxlen); 
    770           menu->max = idxlen; 
     764          update_idx (menu, idx, idxlen++); 
    771765          menu->redraw |= REDRAW_INDEX; 
    772766        } 
     
    11881182            continue; 
    11891183          } 
    1190            
    1191           idx[idxlen]->level = (idxlen > 0) ? idx[idxlen-1]->level : 0; 
    1192           if (idxlen) 
    1193             idx[idxlen - 1]->content->next = idx[idxlen]->content; 
    1194            
    1195           menu->current = idxlen++; 
    1196           mutt_update_tree (idx, idxlen); 
    1197           menu->max = idxlen; 
     1184          update_idx (menu, idx, idxlen++); 
    11981185 
    11991186          idx[menu->current]->content->type = itype; 
     
    12281215      case OP_SAVE: 
    12291216        CHECK_COUNT; 
    1230         mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ?  msg->content : idx[menu->current]->content, NULL); 
     1217        mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ?  msg->content : idx[menu->current]->content, NULL, menu); 
    12311218        MAYBE_REDRAW (menu->redraw); 
    12321219        break; 
     
    13931380    msg->content = idx[0]->content; 
    13941381    for (i = 0; i < idxlen; i++) 
     1382    { 
     1383      idx[i]->content->aptr = NULL; 
    13951384      FREE (&idx[i]); 
     1385    } 
    13961386  } 
    13971387  else 
  • keymap.h

    r3435 r3495  
    1919#ifndef KEYMAP_H 
    2020#define KEYMAP_H 
     21 
     22#include "mapping.h" 
    2123 
    2224/* maximal length of a key binding sequence used for buffer in km_bindkey */ 
  • lib.c

    r3480 r3495  
    647647  return d; 
    648648} 
     649 
     650const char *mutt_basename (const char *f) 
     651{ 
     652  const char *p = strrchr (f, '/'); 
     653  if (p) ++p; 
     654  return p; 
     655} 
  • lib.h

    r3480 r3495  
    119119 
    120120const char *mutt_stristr (const char *, const char *); 
     121const char *mutt_basename (const char *); 
    121122 
    122123int mutt_copy_stream (FILE *, FILE *); 
  • menu.c

    r3493 r3495  
    801801} 
    802802 
     803int menu_redraw (MUTTMENU *menu) 
     804{ 
     805  /* See if all or part of the screen needs to be updated.  */ 
     806  if (menu->redraw & REDRAW_FULL) 
     807  { 
     808    menu_redraw_full (menu); 
     809    /* allow the caller to do any local configuration */ 
     810    return (OP_REDRAW); 
     811  } 
     812   
     813  if (!menu->dialog) 
     814    menu_check_recenter (menu); 
     815   
     816  if (menu->redraw & REDRAW_STATUS) 
     817    menu_redraw_status (menu); 
     818  if (menu->redraw & REDRAW_INDEX) 
     819    menu_redraw_index (menu); 
     820  else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNCH)) 
     821    menu_redraw_motion (menu); 
     822  else if (menu->redraw == REDRAW_CURRENT) 
     823    menu_redraw_current (menu); 
     824   
     825  if (menu->dialog) 
     826    menu_redraw_prompt (menu); 
     827   
     828  return OP_NULL; 
     829} 
     830 
    803831int mutt_menuLoop (MUTTMENU *menu) 
    804832{ 
     
    820848#endif 
    821849 
    822     /* See if all or part of the screen needs to be updated.  */ 
    823     if (menu->redraw & REDRAW_FULL) 
    824     { 
    825       menu_redraw_full (menu); 
    826       /* allow the caller to do any local configuration */ 
    827       return (OP_REDRAW); 
    828     } 
    829  
    830     if (!menu->dialog) 
    831       menu_check_recenter (menu); 
    832  
    833     if (menu->redraw & REDRAW_STATUS) 
    834       menu_redraw_status (menu); 
    835     if (menu->redraw & REDRAW_INDEX) 
    836       menu_redraw_index (menu); 
    837     else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNCH)) 
    838       menu_redraw_motion (menu); 
    839     else if (menu->redraw == REDRAW_CURRENT) 
    840       menu_redraw_current (menu); 
    841  
    842     if (menu->dialog) 
    843       menu_redraw_prompt (menu); 
     850    if (menu_redraw (menu) == OP_REDRAW) 
     851      return OP_REDRAW; 
    844852     
    845853    menu->oldcurrent = menu->current; 
  • mutt.h

    r3435 r3495  
    599599  struct header *hdr;           /* header information for message/rfc822 */ 
    600600 
     601  struct attachptr *aptr;       /* Menu information, used in recvattach.c */ 
     602   
    601603  time_t stamp;                 /* time stamp of last 
    602604                                 * encoding update. 
  • mutt_menu.h

    r3179 r3495  
    8484void menu_redraw_motion (MUTTMENU *); 
    8585void menu_redraw_current (MUTTMENU *); 
     86int  menu_redraw (MUTTMENU *); 
    8687void menu_first_entry (MUTTMENU *); 
    8788void menu_last_entry (MUTTMENU *); 
  • muttlib.c

    r3441 r3495  
    815815} 
    816816 
    817 /* return 0 on success, -1 on error */ 
     817/* return 0 on success, -1 on abort, 1 on error */ 
    818818int mutt_check_overwrite (const char *attname, const char *path, 
    819                                 char *fname, size_t flen, int *append)  
    820 { 
     819                                char *fname, size_t flen, int *append, char **directory)  
     820{ 
     821  int rc = 0; 
    821822  char tmp[_POSIX_PATH_MAX]; 
    822823  struct stat st; 
     
    829830  if (S_ISDIR (st.st_mode)) 
    830831  { 
    831     if (mutt_yesorno (_("File is a directory, save under it?"), M_YES) != M_YES)  
    832       return (-1); 
     832    if (directory) 
     833    { 
     834      switch (mutt_multi_choice 
     835              (_("File is a directory, save under it? [(y)es, (n)o, (a)ll]"), _("yna"))) 
     836      { 
     837        case 3:         /* all */ 
     838          mutt_str_replace (directory, fname); 
     839          break; 
     840        case 1:         /* yes */ 
     841          FREE (directory); 
     842          break; 
     843        case -1:        /* abort */ 
     844          FREE (directory);  
     845          return -1; 
     846        case  2:        /* no */ 
     847          FREE (directory); 
     848          return 1; 
     849      } 
     850    } 
     851    else if ((rc = mutt_yesorno (_("File is a directory, save under it?"), M_YES)) != M_YES) 
     852      return (rc == M_NO) ? 1 : -1; 
     853 
    833854    if (!attname || !attname[0]) 
    834855    { 
     
    837858                                      M_FILE | M_CLEAR) != 0 || !tmp[0]) 
    838859        return (-1); 
    839       snprintf (fname, flen, "%s/%s", path, tmp); 
     860      mutt_concat_path (fname, path, tmp, flen); 
    840861    } 
    841862    else 
    842       snprintf (fname, flen, "%s/%s", path, attname); 
     863      mutt_concat_path (fname, path, mutt_basename (attname), flen); 
    843864  } 
    844865   
     
    849870    { 
    850871      case -1: /* abort */ 
     872        return -1; 
    851873      case 3:  /* cancel */ 
    852         return -1; 
     874        return 1; 
    853875 
    854876      case 2: /* append */ 
     
    11341156} 
    11351157 
    1136 /* returns 1 if OK to proceed, 0 to abort */ 
     1158/* returns 0 if OK to proceed, -1 to abort, 1 to retry */ 
    11371159int mutt_save_confirm (const char *s, struct stat *st) 
    11381160{ 
    11391161  char tmp[_POSIX_PATH_MAX]; 
    1140   int ret = 1; 
     1162  int ret = 0; 
     1163  int rc; 
    11411164  int magic = 0; 
    11421165 
     
    11471170  { 
    11481171    mutt_error _("Can't save message to POP mailbox."); 
    1149     return 0; 
     1172    return 1; 
    11501173  } 
    11511174#endif 
     
    11561179    { 
    11571180      mutt_error (_("%s is not a mailbox!"), s); 
    1158       return 0; 
     1181      return 1; 
    11591182    } 
    11601183 
     
    11621185    { 
    11631186      snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s); 
    1164       if (mutt_yesorno (tmp, M_YES) != M_YES) 
    1165         ret = 0; 
     1187      if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO) 
     1188        ret = 1; 
     1189      else if (rc == -1) 
     1190        ret = -1; 
    11661191    } 
    11671192  } 
     
    11801205        { 
    11811206          snprintf (tmp, sizeof (tmp), _("Create %s?"), s); 
    1182           if (mutt_yesorno (tmp, M_YES) != M_YES) 
    1183             ret = 0; 
     1207          if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO) 
     1208            ret = 1; 
     1209          else if (rc == -1) 
     1210            ret = -1; 
    11841211        } 
    11851212      } 
     
    11871214      { 
    11881215        mutt_perror (s); 
    1189         return 0; 
     1216        return 1; 
    11901217      } 
    11911218    } 
  • pager.c

    r3480 r3495  
    24392439        if (IsAttach (extra)) 
    24402440        { 
    2441           mutt_save_attachment_list (extra->fp, 0, extra->bdy, extra->hdr); 
     2441          mutt_save_attachment_list (extra->fp, 0, extra->bdy, extra->hdr, NULL); 
    24422442          break; 
    24432443        } 
  • protos.h

    r3329 r3495  
    249249int mutt_check_mime_type (const char *); 
    250250int mutt_check_month (const char *); 
    251 int mutt_check_overwrite (const char *, const char *, char *, size_t, int *); 
     251int mutt_check_overwrite (const char *, const char *, char *, size_t, int *, char **); 
    252252int mutt_check_traditional_pgp (HEADER *, int *); 
    253253int mutt_command_complete (char *, size_t, int, int); 
  • recvattach.c

    r3480 r3495  
    130130      new = idx[(*idxlen)++]; 
    131131      new->content = m; 
     132      m->aptr = new; 
    132133      new->parent_type = parent_type; 
    133134      new->level = level; 
     
    364365} 
    365366 
    366 static int mutt_query_save_attachment (FILE *fp, BODY *body, HEADER *hdr) 
    367 { 
     367static int mutt_query_save_attachment (FILE *fp, BODY *body, HEADER *hdr, char **directory) 
     368{ 
     369  char *prompt; 
    368370  char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX]; 
    369371  int is_message; 
    370372  int append = 0; 
    371  
    372   if (body->filename) 
    373     strfcpy (buf, body->filename, sizeof (buf)); 
     373  int rc; 
     374   
     375  if (body->filename)  
     376  { 
     377    if (directory && *directory) 
     378      mutt_concat_path (buf, *directory, mutt_basename (body->filename), sizeof (buf)); 
     379    else 
     380      strfcpy (buf, body->filename, sizeof (buf)); 
     381  } 
    374382  else if(body->hdr && 
    375383          body->encoding != ENCBASE64 && 
     
    380388    buf[0] = 0; 
    381389 
    382   if (mutt_get_field (_("Save to file: "), buf, sizeof (buf), M_FILE | M_CLEAR) != 0 
    383       || !buf[0]) 
    384     return -1; 
    385  
    386   mutt_expand_path (buf, sizeof (buf)); 
    387  
    388   is_message = (fp &&  
    389       body->hdr &&  
    390       body->encoding != ENCBASE64 &&  
    391       body->encoding != ENCQUOTEDPRINTABLE &&  
    392       mutt_is_message_type (body->type, body->subtype)); 
    393    
    394   if (is_message) 
    395   { 
    396     struct stat st; 
     390  prompt = _("Save to file: "); 
     391  while (prompt) 
     392  { 
     393    if (mutt_get_field (prompt, buf, sizeof (buf), M_FILE | M_CLEAR) != 0 
     394        || !buf[0]) 
     395      return -1; 
    397396     
    398     /* check to make sure that this file is really the one the user wants */ 
    399     if (!mutt_save_confirm (buf, &st)) 
    400       return -1; 
    401     strfcpy(tfile, buf, sizeof(tfile)); 
    402   } 
    403   else 
    404     if (mutt_check_overwrite (body->filename, buf, tfile, sizeof (tfile), &append)) 
    405       return -1; 
    406  
    407   mutt_message _("Saving..."); 
    408   if (mutt_save_attachment (fp, body, tfile, append, (hdr || !is_message) ? hdr : body->hdr) == 0) 
    409   { 
    410     mutt_message _("Attachment saved."); 
    411     return 0; 
    412   } 
    413   else 
    414     return -1; 
    415 } 
    416  
    417 void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr) 
     397    prompt = NULL; 
     398    mutt_expand_path (buf, sizeof (buf)); 
     399     
     400    is_message = (fp &&  
     401                  body->hdr &&  
     402                  body->encoding != ENCBASE64 &&  
     403                  body->encoding != ENCQUOTEDPRINTABLE &&  
     404                  mutt_is_message_type (body->type, body->subtype)); 
     405     
     406    if (is_message) 
     407    { 
     408      struct stat st; 
     409       
     410      /* check to make sure that this file is really the one the user wants */ 
     411      if ((rc = mutt_save_confirm (buf, &st)) == 1) 
     412      { 
     413        prompt = _("Save to file: "); 
     414        continue; 
     415      }  
     416      else if (rc == -1) 
     417        return -1; 
     418      strfcpy(tfile, buf, sizeof(tfile)); 
     419    } 
     420    else 
     421    { 
     422      if ((rc = mutt_check_overwrite (body->filename, buf, tfile, sizeof (tfile), &append, directory)) == -1) 
     423        return -1; 
     424      else if (rc == 1) 
     425      { 
     426        prompt = _("Save to file: "); 
     427        continue; 
     428      } 
     429    } 
     430     
     431    mutt_message _("Saving..."); 
     432    if (mutt_save_attachment (fp, body, tfile, append, (hdr || !is_message) ? hdr : body->hdr) == 0) 
     433    { 
     434      mutt_message _("Attachment saved."); 
     435      return 0; 
     436    } 
     437    else 
     438    { 
     439      prompt = _("Save to file: "); 
     440      continue; 
     441    } 
     442  } 
     443  return 0; 
     444} 
     445     
     446void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu) 
    418447{ 
    419448  char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX]; 
     449  char *directory = NULL; 
    420450  int rc = 1; 
     451  int last = menu ? menu->current : -1; 
    421452  FILE *fpout; 
    422453 
     
    439470          mutt_expand_path (buf, sizeof (buf)); 
    440471          if (mutt_check_overwrite (top->filename, buf, tfile, 
    441                                     sizeof (tfile), &append)) 
     472                                    sizeof (tfile), &append, NULL)) 
    442473            return; 
    443474          rc = mutt_save_attachment (fp, top, tfile, append, hdr); 
     
    458489        } 
    459490      } 
    460       else 
    461         mutt_query_save_attachment (fp, top, hdr); 
     491      else  
     492      { 
     493        if (tag && menu && top->aptr) 
     494        { 
     495          menu->oldcurrent = menu->current; 
     496          menu->current = top->aptr->num; 
     497          menu_check_recenter (menu); 
     498          menu->redraw |= REDRAW_MOTION; 
     499 
     500          menu_redraw (menu); 
     501        } 
     502        if (mutt_query_save_attachment (fp, top, hdr, &directory) == -1) 
     503          break; 
     504      } 
    462505    } 
    463506    else if (top->parts) 
    464       mutt_save_attachment_list (fp, 1, top->parts, hdr); 
     507      mutt_save_attachment_list (fp, 1, top->parts, hdr, menu); 
    465508    if (!tag) 
    466       return; 
    467   } 
    468  
     509      break; 
     510  } 
     511 
     512  FREE (&directory); 
     513 
     514  if (tag && menu) 
     515  { 
     516    menu->oldcurrent = menu->current; 
     517    menu->current = last; 
     518    menu_check_recenter (menu); 
     519    menu->redraw |= REDRAW_MOTION; 
     520  } 
     521   
    469522  if (!option (OPTATTACHSPLIT) && (rc == 0)) 
    470523    mutt_message _("Attachment saved."); 
     
    9781031      case OP_SAVE: 
    9791032        mutt_save_attachment_list (fp, menu->tagprefix,  
    980                   menu->tagprefix ?  cur : idx[menu->current]->content, hdr); 
    981  
    982         if (option (OPTRESOLVE) && menu->current < menu->max - 1) 
     1033                  menu->tagprefix ?  cur : idx[menu->current]->content, hdr, menu); 
     1034 
     1035        if (!menu->tagprefix && option (OPTRESOLVE) && menu->current < menu->max - 1) 
    9831036          menu->current++; 
    9841037       
     
    11211174          if (idx[idxmax]->content && idx[idxmax]->content->deleted) 
    11221175            hdr->attach_del = 1; 
     1176          if (idx[idxmax]->content) 
     1177            idx[idxmax]->content->aptr = NULL; 
    11231178          FREE (&idx[idxmax]->tree); 
    11241179          FREE (&idx[idxmax]);