addrbook.c 5.67 KB
Newer Older
Thomas Roessler's avatar
Thomas Roessler committed
1
/*
2
 * Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu>
Thomas Roessler's avatar
Thomas Roessler committed
3 4 5 6 7 8 9 10 11 12 13 14 15
 * 
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with this program; if not, write to the Free Software
16
 *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
Thomas Roessler's avatar
Thomas Roessler committed
17 18 19 20
 */ 

#include "mutt.h"
#include "mutt_menu.h"
Thomas Roessler's avatar
Thomas Roessler committed
21
#include "mapping.h"
Thomas Roessler's avatar
Thomas Roessler committed
22 23 24 25 26 27 28 29 30
#include "sort.h"

#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define RSORT(x) (SortAlias & SORT_REVERSE) ? -x : x

static struct mapping_t AliasHelp[] = {
31
  { N_("Exit"),   OP_EXIT },
32 33
  { N_("Del"),    OP_DELETE },
  { N_("Undel"),  OP_UNDELETE },
34 35
  { N_("Select"), OP_GENERIC_SELECT_ENTRY },
  { N_("Help"),   OP_HELP },
Thomas Roessler's avatar
Thomas Roessler committed
36 37 38 39 40 41 42 43 44 45 46 47 48
  { NULL }
};

static const char *
alias_format_str (char *dest, size_t destlen, char op, const char *src,
		  const char *fmt, const char *ifstring, const char *elsestring,
		  unsigned long data, format_flag flags)
{
  char tmp[SHORT_STRING], adr[SHORT_STRING];
  ALIAS *alias = (ALIAS *) data;

  switch (op)
  {
49 50 51 52
    case 'f':
      snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
      snprintf (dest, destlen, tmp, alias->del ? "D" : " ");
      break;
Thomas Roessler's avatar
Thomas Roessler committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    case 'a':
      snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
      snprintf (dest, destlen, tmp, alias->name);
      break;
    case 'r':
      adr[0] = 0;
      rfc822_write_address (adr, sizeof (adr), alias->addr);
      snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
      snprintf (dest, destlen, tmp, adr);
      break;
    case 'n':
      snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
      snprintf (dest, destlen, tmp, alias->num + 1);
      break;
    case 't':
      dest[0] = alias->tagged ? '*' : ' ';
      dest[1] = 0;
      break;
  }

  return (src);
}

void alias_entry (char *s, size_t slen, MUTTMENU *m, int num)
{
78
  mutt_FormatString (s, slen, NONULL (AliasFmt), alias_format_str, (unsigned long) ((ALIAS **) m->data)[num], M_FORMAT_ARROWCURSOR);
Thomas Roessler's avatar
Thomas Roessler committed
79 80
}

81
int alias_tag (MUTTMENU *menu, int n, int m)
Thomas Roessler's avatar
Thomas Roessler committed
82
{
83 84 85 86 87 88
  ALIAS *cur = ((ALIAS **) menu->data)[n];
  int ot = cur->tagged;
  
  cur->tagged = (m >= 0 ? m : !cur->tagged);
  
  return cur->tagged - ot;
Thomas Roessler's avatar
Thomas Roessler committed
89 90 91 92 93 94
}

static int alias_SortAlias (const void *a, const void *b)
{
  ALIAS *pa = *(ALIAS **) a;
  ALIAS *pb = *(ALIAS **) b;
95
  int r = mutt_strcasecmp (pa->name, pb->name);
Thomas Roessler's avatar
Thomas Roessler committed
96 97 98 99 100 101 102 103 104 105

  return (RSORT (r));
}

static int alias_SortAddress (const void *a, const void *b)
{
  ADDRESS *pa = (*(ALIAS **) a)->addr;
  ADDRESS *pb = (*(ALIAS **) b)->addr;
  int r;

Thomas Roessler's avatar
Thomas Roessler committed
106 107 108 109 110 111 112
  if (pa == pb)
    r = 0;
  else if (pa == NULL)
    r = -1;
  else if (pb == NULL)
    r = 1;
  else if (pa->personal)
Thomas Roessler's avatar
Thomas Roessler committed
113 114
  { 
    if (pb->personal)
115
      r = mutt_strcasecmp (pa->personal, pb->personal);
Thomas Roessler's avatar
Thomas Roessler committed
116 117 118 119 120 121
    else
      r = 1;
  }
  else if (pb->personal)
    r = -1;
  else
122
    r = ascii_strcasecmp (pa->mailbox, pb->mailbox);
Thomas Roessler's avatar
Thomas Roessler committed
123 124 125 126 127
  return (RSORT (r));
}

void mutt_alias_menu (char *buf, size_t buflen, ALIAS *aliases)
{
128
  ALIAS *aliasp;
Thomas Roessler's avatar
Thomas Roessler committed
129 130 131 132
  MUTTMENU *menu;
  ALIAS **AliasTable = NULL;
  int t = -1;
  int i, done = 0;
133
  int op;
Thomas Roessler's avatar
Thomas Roessler committed
134 135
  char helpstr[SHORT_STRING];

136 137
  int omax;
  
Thomas Roessler's avatar
Thomas Roessler committed
138 139
  if (!aliases)
  {
140
    mutt_error _("You have no aliases!");
Thomas Roessler's avatar
Thomas Roessler committed
141 142
    return;
  }
143
  
Thomas Roessler's avatar
Thomas Roessler committed
144 145
  /* tell whoever called me to redraw the screen when I return */
  set_option (OPTNEEDREDRAW);
146
  
Thomas Roessler's avatar
Thomas Roessler committed
147 148 149
  menu = mutt_new_menu ();
  menu->make_entry = alias_entry;
  menu->tag = alias_tag;
150
  menu->menu = MENU_ALIAS;
151
  menu->title = _("Aliases");
Thomas Roessler's avatar
Thomas Roessler committed
152 153
  menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_ALIAS, AliasHelp);

154 155 156 157
new_aliases:

  omax = menu->max;
  
Thomas Roessler's avatar
Thomas Roessler committed
158 159
  /* count the number of aliases */
  for (aliasp = aliases; aliasp; aliasp = aliasp->next)
Thomas Roessler's avatar
Thomas Roessler committed
160
  {
161 162
    aliasp->self->del    = 0;
    aliasp->self->tagged = 0;
Thomas Roessler's avatar
Thomas Roessler committed
163
    menu->max++;
Thomas Roessler's avatar
Thomas Roessler committed
164
  }
Thomas Roessler's avatar
Thomas Roessler committed
165

166 167
  safe_realloc ((void **) &AliasTable, menu->max * sizeof (ALIAS *));
  menu->data = AliasTable;
Thomas Roessler's avatar
Thomas Roessler committed
168

169 170 171 172 173
  for (i = omax, aliasp = aliases; aliasp; aliasp = aliasp->next, i++)
  {
    AliasTable[i] = aliasp->self;
    aliases       = aliasp;
  }
Thomas Roessler's avatar
Thomas Roessler committed
174 175 176 177 178 179 180 181 182 183 184

  if ((SortAlias & SORT_MASK) != SORT_ORDER)
  {
    qsort (AliasTable, i, sizeof (ALIAS *),
	 (SortAlias & SORT_MASK) == SORT_ADDRESS ? alias_SortAddress : alias_SortAlias);
  }

  for (i=0; i<menu->max; i++) AliasTable[i]->num = i;

  while (!done)
  {
185 186 187 188 189 190 191
    if (aliases->next)
    {
      menu->redraw |= REDRAW_FULL;
      aliases       = aliases->next;
      goto new_aliases;
    }
    
192
    switch ((op = mutt_menuLoop (menu)))
Thomas Roessler's avatar
Thomas Roessler committed
193
    {
194 195 196 197 198 199 200 201 202 203 204
      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
        {
205
	  AliasTable[menu->current]->self->del = (op == OP_DELETE) ? 1 : 0;
206 207 208 209
	  menu->redraw |= REDRAW_CURRENT;
	  if (option (OPTRESOLVE) && menu->current < menu->max - 1)
	  {
	    menu->current++;
210
	    menu->redraw |= REDRAW_INDEX;
211 212 213
	  }
	}
        break;
Thomas Roessler's avatar
Thomas Roessler committed
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
      case OP_GENERIC_SELECT_ENTRY:
        t = menu->current;
      case OP_EXIT:
	done = 1;
	break;
    }
  }

  for (i = 0; i < menu->max; i++)
  {
    if (AliasTable[i]->tagged)
    {
      rfc822_write_address (buf, buflen, AliasTable[i]->addr);
      t = -1;
    }
  }

  if(t != -1)
    rfc822_write_address (buf, buflen, AliasTable[t]->addr);
233

Thomas Roessler's avatar
Thomas Roessler committed
234 235
  mutt_menuDestroy (&menu);
  safe_free ((void **) &AliasTable);
236
  
Thomas Roessler's avatar
Thomas Roessler committed
237
}