]> granicus.if.org Git - neomutt/commitdiff
The addressbook used to crash when someone issued the alias and
authorThomas Roessler <roessler@does-not-exist.org>
Tue, 11 Sep 2001 11:20:34 +0000 (11:20 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Tue, 11 Sep 2001 11:20:34 +0000 (11:20 +0000)
unalias commands while on that menu.  This patch has a basic fix for
this behaviour, and adds delete and undelete functions to this menu.
While I'm on it, I've also made sure that "apply-tag" untags
everything on all menus.

The original crash was noted by Oliver Kauss <kauss@gmx.de>.

12 files changed:
addrbook.c
attach.h
browser.c
functions.h
init.c
init.h
keymap.c
keymap.h
menu.c
mutt.h
mutt_menu.h
recvattach.c

index 99c973cdadfadba3d1c7b78899acc2aa42e90d15..7c738841e42255f5cc7abf4129093bfab319d664 100644 (file)
@@ -44,6 +44,10 @@ alias_format_str (char *dest, size_t destlen, char op, const char *src,
 
   switch (op)
   {
+    case 'f':
+      snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+      snprintf (dest, destlen, tmp, alias->del ? "D" : " ");
+      break;
     case 'a':
       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
       snprintf (dest, destlen, tmp, alias->name);
@@ -72,9 +76,14 @@ void alias_entry (char *s, size_t slen, MUTTMENU *m, int num)
   mutt_FormatString (s, slen, NONULL (AliasFmt), alias_format_str, (unsigned long) ((ALIAS **) m->data)[num], M_FORMAT_ARROWCURSOR);
 }
 
-int alias_tag (MUTTMENU *menu, int n)
+int alias_tag (MUTTMENU *menu, int n, int m)
 {
-  return ((((ALIAS **) menu->data)[n]->tagged = !((ALIAS **) menu->data)[n]->tagged) ? 1 : -1);
+  ALIAS *cur = ((ALIAS **) menu->data)[n];
+  int ot = cur->tagged;
+  
+  cur->tagged = (m >= 0 ? m : !cur->tagged);
+  
+  return cur->tagged - ot;
 }
 
 static int alias_SortAlias (const void *a, const void *b)
@@ -108,11 +117,12 @@ static int alias_SortAddress (const void *a, const void *b)
 
 void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases)
 {
-  ALIAS *aliasp;
+  ALIAS *aliasp, *aliasl;
   MUTTMENU *menu;
   ALIAS **AliasTable = NULL;
   int t = -1;
   int i, done = 0;
+  int op;
   char helpstr[SHORT_STRING];
 
   if (!aliases)
@@ -124,6 +134,9 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases)
   /* tell whoever called me to redraw the screen when I return */
   set_option (OPTNEEDREDRAW);
 
+  /* tell mutt_alias and mutt_unalias that this menu is active */
+  set_option (OPTALIASMENU);
+  
   menu = mutt_new_menu ();
   menu->make_entry = alias_entry;
   menu->tag = alias_tag;
@@ -134,6 +147,7 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases)
   /* count the number of aliases */
   for (aliasp = aliases; aliasp; aliasp = aliasp->next)
   {
+    aliasp->del    = 0;
     aliasp->tagged = 0;
     menu->max++;
   }
@@ -153,8 +167,28 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases)
 
   while (!done)
   {
-    switch (mutt_menuLoop (menu))
+    switch ((op = mutt_menuLoop (menu)))
     {
+      case OP_DELETE:
+      case OP_UNDELETE:
+        if (menu->tagprefix)
+        {
+         for (i = 0; i < menu->max; i++)
+           if (AliasTable[i]->tagged)
+             AliasTable[i]->del = (op == OP_DELETE) ? 1 : 0;
+         menu->redraw |= REDRAW_INDEX;
+       }
+        else
+        {
+         AliasTable[menu->current]->del = (op == OP_DELETE) ? 1 : 0;
+         menu->redraw |= REDRAW_CURRENT;
+         if (option (OPTRESOLVE) && menu->current < menu->max - 1)
+         {
+           menu->current++;
+           menu->redraw |= REDRAW_MOTION;
+         }
+       }
+        break;
       case OP_GENERIC_SELECT_ENTRY:
         t = menu->current;
       case OP_EXIT:
@@ -174,7 +208,33 @@ void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases)
 
   if(t != -1)
     rfc822_write_address (buf, buflen, AliasTable[t]->addr);
-  
+
   mutt_menuDestroy (&menu);
   safe_free ((void **) &AliasTable);
+  
+  unset_option (OPTALIASMENU);
+
+  /* remove aliases marked for deletion. */
+  aliasl = NULL;
+  for (aliasp = Aliases; aliasp; aliasp = aliasp->next)
+  {
+    if (aliasp->del)
+    {
+      if (aliasl) 
+       aliasl->next = aliasp->next;
+      else
+       Aliases = aliasp->next;
+      
+      aliasp->next = NULL;
+      mutt_free_alias (&aliasp);
+
+      if (aliasl)
+       aliasp = aliasl;
+      else
+       aliasp = Aliases;
+    }
+    else
+      aliasl = aliasp;
+  }
+
 }
index 3e1cffdf7cccbbfe2ee502fc56d3b8f4011a0cbe..5b84ac0c24f64d15742bee820ebda83c9264cb6a 100644 (file)
--- a/attach.h
+++ b/attach.h
@@ -18,7 +18,7 @@
 
 /* common protos for compose / attach menus */
 
-int mutt_tag_attach (MUTTMENU *menu, int n);
+int mutt_tag_attach (MUTTMENU *menu, int n, int m);
 int mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
                              BODY *cur, ATTACHPTR ***idxp, short *idxlen, short *idxmax,
                              int recv);
index 7d259dd709bf866554139831a93eb7a964c4045d..a195299d89cd9df660c2786a299186b04e835184 100644 (file)
--- a/browser.c
+++ b/browser.c
@@ -507,16 +507,20 @@ static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title,
   menu->redraw = REDRAW_FULL;
 }
 
-int file_tag (MUTTMENU *menu, int n)
+int file_tag (MUTTMENU *menu, int n, int m)
 {
   struct folder_file *ff = &(((struct folder_file *)menu->data)[n]);
+  int ot;
   if (S_ISDIR (ff->mode) || (S_ISLNK (ff->mode) && link_is_dir (LastDir, ff->name)))
   {
     mutt_error _("Can't attach a directory!");
     return 0;
   }
   
-  return ((ff->tagged = !ff->tagged) ? 1 : -1);
+  ot = ff->tagged;
+  ff->tagged = (m >= 0 ? m : !ff->tagged);
+  
+  return ff->tagged - ot;
 }
 
 void _mutt_select_file (char *f, size_t flen, int flags, char ***files, int *numfiles)
index f1f813b6a2cffac4a993f403bb192c76d7cd79bd..aa54ed6979845202d65639ec219af7e260369578 100644 (file)
@@ -328,6 +328,13 @@ struct binding_t OpPost[] = {
   { NULL,              0,              NULL }
 };
 
+struct binding_t OpAlias[] = {
+  { "delete-entry",    OP_DELETE,      "d" },
+  { "undelete-entry",  OP_UNDELETE,    "u" },
+  { NULL,              0,              NULL }
+};
+  
+
 /* The file browser */
 struct binding_t OpBrowser[] = {
   { "change-dir",      OP_CHANGE_DIRECTORY,    "c" },
diff --git a/init.c b/init.c
index 8f57ff5e93abe16d395d3347f9dfeee2701184ff..46c4c51390257b17782ef46da3729146381a1bcf 100644 (file)
--- a/init.c
+++ b/init.c
@@ -428,11 +428,17 @@ static int parse_unalias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *er
   {
     mutt_extract_token (buf, s, 0);
 
-    tmp = Aliases;
     for (tmp = Aliases; tmp; tmp = tmp->next)
     {
       if (mutt_strcasecmp (buf->data, tmp->name) == 0)
       {
+       if (option (OPTALIASMENU))
+       {
+         tmp->del = 1;
+         set_option (OPTFORCEREDRAWINDEX);
+         break;
+       }
+
        if (last)
          last->next = tmp->next;
        else
@@ -483,6 +489,8 @@ static int parse_alias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
   {
     /* override the previous value */
     rfc822_free_address (&tmp->addr);
+    if (option (OPTALIASMENU))
+      set_option (OPTFORCEREDRAWINDEX);
   }
   s->dptr = p;
 
diff --git a/init.h b/init.h
index 20427ad6d6c97f13ec23d7b4eada105f3cf725b3..678b44e5db479f7232110a18e7d79ba8f5bc45e3 100644 (file)
--- a/init.h
+++ b/init.h
@@ -127,7 +127,7 @@ struct option_t MuttVars[] = {
   ** \fBNote:\fP Mutt will not automatically source this file; you must
   ** explicitly use the ``$source'' command for it to be executed.
   */
-  { "alias_format",    DT_STR,  R_NONE, UL &AliasFmt, UL "%4n %t %-10a   %r" },
+  { "alias_format",    DT_STR,  R_NONE, UL &AliasFmt, UL "%4n %2f %t %-10a   %r" },
   /*
   ** .pp
   ** Specifies the format of the data displayed for the `alias' menu.  The
@@ -135,6 +135,7 @@ struct option_t MuttVars[] = {
   ** .pp
   ** .dl
   ** .dt %a .dd alias name
+  ** .dt %f .dd flags - currently, a "d" for an alias marked for deletion
   ** .dt %n .dd index number
   ** .dt %r .dd address which alias expands to
   ** .dt %t .dd character which indicates if the alias is tagged for inclusion
index 7b48e97ef8586e1437b31a8be00f9e2393d9e31e..e7d90aa8d81ff0c67e153f63af82b8223321c837 100644 (file)
--- a/keymap.c
+++ b/keymap.c
@@ -526,7 +526,7 @@ void km_init (void)
   create_bindings (OpPager, MENU_PAGER);
   create_bindings (OpPost, MENU_POST);
   create_bindings (OpQuery, MENU_QUERY);
-
+  create_bindings (OpAlias, MENU_ALIAS);
 
 
 #ifdef HAVE_PGP
index 040e354dd8d808ea61f9af75d3f7e614207310c8..34937e7551bf37c96c9b6a96424db873b9838429 100644 (file)
--- a/keymap.h
+++ b/keymap.h
@@ -100,6 +100,7 @@ extern struct binding_t OpCompose[];
 extern struct binding_t OpBrowser[];
 extern struct binding_t OpEditor[];
 extern struct binding_t OpQuery[];
+extern struct binding_t OpAlias[];
 
 #ifdef HAVE_PGP
 extern struct binding_t OpPgp[];
diff --git a/menu.c b/menu.c
index 19d36a5e713ced18865cc24c92e72edb85812bd0..b0d9762c705f68d10e57328609e794f3f3269ccf 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -966,9 +966,15 @@ int mutt_menuLoop (MUTTMENU *menu)
       case OP_TAG:
        if (menu->tag && !menu->dialog)
        {
-         if (menu->max)
+         if (menu->tagprefix && !option (OPTAUTOTAG))
          {
-           int i = menu->tag (menu, menu->current);
+           for (i = 0; i < menu->max; i++)
+             menu->tagged += menu->tag (menu, i, 0);
+           menu->redraw = REDRAW_INDEX;
+         }
+         else if (menu->max)
+         {
+           int i = menu->tag (menu, menu->current, -1);
            menu->tagged += i;
            if (i && option (OPTRESOLVE) && menu->current < menu->max - 1)
            {
diff --git a/mutt.h b/mutt.h
index dcf25df9b5549215bcc324e9744328620b842d47..acb179cdef2bdb35be5f725ef309f01c477da6aa 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -442,6 +442,7 @@ enum
                         *          functions while we are executing an
                         *          external program.
                         */
+  OPTALIASMENU,                /* (pseudo) alias menu active */
 #ifdef HAVE_PGP
   OPTPGPCHECKTRUST,    /* (pseudo) used by pgp_select_key () */
   OPTDONTHANDLEPGPKEYS,        /* (pseudo) used to extract PGP keys */
@@ -489,6 +490,7 @@ typedef struct alias
   ADDRESS *addr;
   struct alias *next;
   short tagged;
+  short del;
   short num;
 } ALIAS;
 
index 13e01b63131a04a660c0e5b88e59a46a828057d1..ee44248a5b08bbdd1c712838a5d070f7a8955656 100644 (file)
@@ -62,7 +62,7 @@ typedef struct menu_t
   /* how to search the menu */
   int (*search) (struct menu_t *, regex_t *re, int n);
 
-  int (*tag) (struct menu_t *, int i);
+  int (*tag) (struct menu_t *, int i, int m);
 
   /* color pair to be used for the requested element 
    * (default function returns ColorDefs[MT_COLOR_NORMAL])
index c41fa2ce89b510e761cfea4dc9e6644125cb5a05..6039f48f5f889e0b5390f1e82e13d356d93cfd45 100644 (file)
@@ -354,9 +354,13 @@ void attach_entry (char *b, size_t blen, MUTTMENU *menu, int num)
   mutt_FormatString (b, blen, NONULL (AttachFormat), mutt_attach_fmt, (unsigned long) (((ATTACHPTR **)menu->data)[num]), M_FORMAT_ARROWCURSOR);
 }
 
-int mutt_tag_attach (MUTTMENU *menu, int n)
+int mutt_tag_attach (MUTTMENU *menu, int n, int m)
 {
-  return ((((ATTACHPTR **) menu->data)[n]->content->tagged = !((ATTACHPTR **) menu->data)[n]->content->tagged) ? 1 : -1);
+  BODY *cur = ((ATTACHPTR **) menu->data)[n]->content;
+  int ot = cur->tagged;
+  
+  cur->tagged = (m >= 0 ? m : !cur->tagged);
+  return cur->tagged - ot;
 }
 
 int mutt_is_message_type (int type, const char *subtype)