Commit d3e9c08a authored by Thomas Roessler's avatar Thomas Roessler

The addressbook used to crash when someone issued the alias and

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>.
parent 0dd6d287
......@@ -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;
}
}
......@@ -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);
......
......@@ -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)
......
......@@ -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" },
......
......@@ -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;
......
......@@ -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
......
......@@ -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
......
......@@ -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[];
......
......@@ -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)
{
......
......@@ -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;
......
......@@ -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])
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment