NeoMutt  2022-04-29-249-gaae397
Teaching an old dog new tricks
dlg_alias.c File Reference

Address book. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "lib.h"
#include "menu/lib.h"
#include "pattern/lib.h"
#include "send/lib.h"
#include "alias.h"
#include "format_flags.h"
#include "functions.h"
#include "gui.h"
#include "keymap.h"
#include "mutt_logging.h"
#include "muttlib.h"
#include "opcodes.h"
+ Include dependency graph for dlg_alias.c:

Go to the source code of this file.


static const char * alias_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the alias list - Implements format_t -. More...
static void alias_make_entry (struct Menu *menu, char *buf, size_t buflen, int line)
 Format a menu item for the alias list - Implements Menu::make_entry() -. More...
static int alias_tag (struct Menu *menu, int sel, int act)
 Tag some aliases - Implements Menu::tag() -. More...
static int alias_alias_observer (struct NotifyCallback *nc)
 Notification that an Alias has changed - Implements observer_t -. More...
static int alias_window_observer (struct NotifyCallback *nc)
 Notification that a Window has changed - Implements observer_t -. More...
static struct MuttWindowalias_dialog_new (struct AliasMenuData *mdata)
 Create an Alias Selection Dialog. More...
static bool dlg_select_alias (struct Buffer *buf, struct AliasMenuData *mdata)
 Display a menu of Aliases. More...
int alias_complete (char *buf, size_t buflen, struct ConfigSubset *sub)
 Alias completion routine. More...
void alias_dialog (struct Mailbox *m, struct ConfigSubset *sub)
 Open the aliases dialog. More...


static const struct Mapping AliasHelp []
 Help Bar for the Alias dialog (address book) More...

Detailed Description

Address book.

  • Michael R. Elkins
  • Pietro Cerutti
  • Richard Russon

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, see

Definition in file dlg_alias.c.

Function Documentation

◆ alias_dialog_new()

static struct MuttWindow * alias_dialog_new ( struct AliasMenuData mdata)

Create an Alias Selection Dialog.

mdataMenu data holding Aliases
Return values
ptrNew Dialog

Definition at line 275 of file dlg_alias.c.

279 struct Menu *menu = dlg->wdata;
282 menu->custom_search = true;
283 menu->tag = alias_tag;
284 menu->max = alias_array_count_visible(&mdata->ava);
285 menu->mdata = mdata;
286 menu->mdata_free = NULL; // Menu doesn't own the data
288 struct MuttWindow *win_menu = menu->win;
290 // Override the Simple Dialog's recalc()
291 win_menu->recalc = alias_recalc;
293 struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
294 alias_set_title(sbar, mdata->title, mdata->limit);
296 // NT_COLOR is handled by the SimpleDialog
301 return dlg;
int alias_array_count_visible(struct AliasViewArray *ava)
Count number of visible Aliases.
Definition: array.c:95
static const struct Mapping AliasHelp[]
Help Bar for the Alias dialog (address book)
Definition: dlg_alias.c:99
static void alias_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
Format a menu item for the alias list - Implements Menu::make_entry() -.
Definition: dlg_alias.c:168
static int alias_tag(struct Menu *menu, int sel, int act)
Tag some aliases - Implements Menu::tag() -.
Definition: dlg_alias.c:183
static int alias_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: dlg_alias.c:246
static int alias_alias_observer(struct NotifyCallback *nc)
Notification that an Alias has changed - Implements observer_t -.
Definition: dlg_alias.c:199
int alias_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: gui.c:43
int alias_recalc(struct MuttWindow *win)
Recalculate the display of the Alias Window - Implements MuttWindow::recalc() -.
Definition: gui.c:89
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:129
void alias_set_title(struct MuttWindow *sbar, char *menu_name, char *limit)
Create a title string for the Menu.
Definition: gui.c:69
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:522
Alias Dialog, dlg_select_alias()
Definition: mutt_window.h:77
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:55
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:43
Alias has changed, NotifyAlias, EventAlias.
Definition: notify_type.h:37
char * limit
Limit being used.
Definition: gui.h:58
char * title
Title for the status bar.
Definition: gui.h:60
Definition: lib.h:69
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:96
void(* mdata_free)(struct Menu *menu, void **ptr)
Definition: lib.h:152
int(* tag)(struct Menu *menu, int sel, int act)
Definition: lib.h:121
void * mdata
Private data.
Definition: lib.h:137
int max
Number of entries in the menu.
Definition: lib.h:71
bool custom_search
The menu implements its own non-Menusearch()-compatible search, trickle OP_SEARCH*.
Definition: lib.h:84
void * wdata
Private data.
Definition: mutt_window.h:145
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
int(* recalc)(struct MuttWindow *win)
Definition: mutt_window.h:171
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
Select an email address by its alias.
Definition: type.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_select_alias()

static bool dlg_select_alias ( struct Buffer buf,
struct AliasMenuData mdata 

Display a menu of Aliases.

bufBuffer for expanded aliases
mdataMenu data holding Aliases
Return values
trueSelection was made

Definition at line 310 of file dlg_alias.c.

312 if (ARRAY_EMPTY(&mdata->ava))
313 {
314 mutt_warning(_("You have no aliases"));
315 return false;
316 }
318 mdata->query = buf;
319 mdata->title = mutt_str_dup(_("Aliases"));
321 struct MuttWindow *dlg = alias_dialog_new(mdata);
322 struct Menu *menu = dlg->wdata;
323 struct MuttWindow *win_sbar = window_find_child(dlg, WT_STATUS_BAR);
324 mdata->menu = menu;
325 mdata->sbar = win_sbar;
327 alias_array_sort(&mdata->ava, mdata->sub);
329 struct AliasView *avp = NULL;
330 ARRAY_FOREACH(avp, &mdata->ava)
331 {
332 avp->num = ARRAY_FOREACH_IDX;
333 }
335 // ---------------------------------------------------------------------------
336 // Event Loop
337 int rc = 0;
338 int op = OP_NULL;
339 do
340 {
341 menu_tagging_dispatcher(menu->win, op);
342 window_redraw(NULL);
344 op = km_dokey(MENU_ALIAS);
345 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
346 if (op < 0)
347 continue;
348 if (op == OP_NULL)
349 {
351 continue;
352 }
355 rc = alias_function_dispatcher(dlg, op);
356 if (rc == FR_UNKNOWN)
357 rc = menu_function_dispatcher(menu->win, op);
358 if (rc == FR_UNKNOWN)
359 rc = global_function_dispatcher(NULL, op);
360 } while ((rc != FR_DONE) && (rc != FR_CONTINUE));
361 // ---------------------------------------------------------------------------
363 simple_dialog_free(&dlg);
364 window_redraw(NULL);
365 return (rc == FR_CONTINUE); // Was a selection made?
void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
Sort and reindex an AliasViewArray.
Definition: sort.c:156
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:211
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:73
Exit the Dialog.
Definition: dispatcher.h:35
Unknown function.
Definition: dispatcher.h:33
Remain in the Dialog.
Definition: dispatcher.h:34
static struct MuttWindow * alias_dialog_new(struct AliasMenuData *mdata)
Create an Alias Selection Dialog.
Definition: dlg_alias.c:275
int menu_tagging_dispatcher(struct MuttWindow *win, int op)
Perform tagging operations on the Menu - Implements function_dispatcher_t -.
Definition: tagging.c:223
int global_function_dispatcher(struct MuttWindow *win, int op)
Perform a Global function - Implements function_dispatcher_t -.
Definition: global.c:164
int menu_function_dispatcher(struct MuttWindow *win, int op)
Perform a Menu function - Implements function_dispatcher_t -.
Definition: functions.c:320
int alias_function_dispatcher(struct MuttWindow *win, int op)
Perform a Alias function - Implements function_dispatcher_t -.
Definition: functions.c:333
#define mutt_warning(...)
Definition: logging.h:85
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:166
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:795
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1061
Log at debug level 1.
Definition: logging.h:40
#define _(a)
Definition: message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:604
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:46
struct AliasViewArray ava
All Aliases/Queries.
Definition: gui.h:53
struct MuttWindow * sbar
Status Bar.
Definition: gui.h:59
struct Menu * menu
Definition: gui.h:56
struct Buffer * query
Query string.
Definition: gui.h:57
struct ConfigSubset * sub
Config items.
Definition: gui.h:55
GUI data wrapping an Alias.
Definition: gui.h:36
int num
Index number in list.
Definition: gui.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_complete()

int alias_complete ( char *  buf,
size_t  buflen,
struct ConfigSubset sub 

Alias completion routine.

bufPartial Alias to complete
buflenLength of buffer
subConfig items
Return values

Given a partial alias, this routine attempts to fill in the alias from the alias list as much as possible. if given empty search string or found nothing, present all aliases

Definition at line 380 of file dlg_alias.c.

382 struct Alias *np = NULL;
383 char bestname[8192] = { 0 };
385 struct AliasMenuData mdata = { ARRAY_HEAD_INITIALIZER, NULL, sub };
386 mdata.limit = mutt_str_dup(buf);
388 if (buf[0] != '\0')
389 {
390 TAILQ_FOREACH(np, &Aliases, entries)
391 {
392 if (np->name && mutt_strn_equal(np->name, buf, strlen(buf)))
393 {
394 if (bestname[0] == '\0') /* init */
395 {
396 mutt_str_copy(bestname, np->name,
397 MIN(mutt_str_len(np->name) + 1, sizeof(bestname)));
398 }
399 else
400 {
401 int i;
402 for (i = 0; np->name[i] && (np->name[i] == bestname[i]); i++)
403 ; // do nothing
405 bestname[i] = '\0';
406 }
407 }
408 }
410 if (bestname[0] == '\0')
411 {
412 // Create a View Array of all the Aliases
413 FREE(&mdata.limit);
414 TAILQ_FOREACH(np, &Aliases, entries)
415 {
417 }
418 }
419 else
420 {
421 /* fake the pattern for menu title */
422 char *mtitle = NULL;
423 mutt_str_asprintf(&mtitle, "~f ^%s", buf);
424 FREE(&mdata.limit);
425 mdata.limit = mtitle;
427 if (!mutt_str_equal(bestname, buf))
428 {
429 /* we are adding something to the completion */
430 mutt_str_copy(buf, bestname, mutt_str_len(bestname) + 1);
431 FREE(&mdata.limit);
432 return 1;
433 }
435 /* build alias list and show it */
436 TAILQ_FOREACH(np, &Aliases, entries)
437 {
438 int aasize = alias_array_alias_add(&mdata.ava, np);
440 struct AliasView *av = ARRAY_GET(&mdata.ava, aasize - 1);
442 if (np->name && !mutt_strn_equal(np->name, buf, strlen(buf)))
443 {
444 av->is_visible = false;
445 }
446 }
447 }
448 }
450 if (ARRAY_EMPTY(&mdata.ava))
451 {
452 TAILQ_FOREACH(np, &Aliases, entries)
453 {
454 alias_array_alias_add(&mdata.ava, np);
455 }
457 mutt_pattern_alias_func(NULL, &mdata, NULL);
458 }
460 if (!dlg_select_alias(NULL, &mdata))
461 goto done;
463 buf[0] = '\0';
465 // Extract the selected aliases
466 struct AliasView *avp = NULL;
467 ARRAY_FOREACH(avp, &mdata.ava)
468 {
469 if (!avp->is_tagged)
470 continue;
472 mutt_addrlist_write(&avp->alias->addr, buf, buflen, true);
473 }
476 // Process any deleted aliases
477 ARRAY_FOREACH(avp, &mdata.ava)
478 {
479 if (!avp->is_deleted)
480 continue;
482 TAILQ_REMOVE(&Aliases, avp->alias, entries);
483 alias_free(&avp->alias);
484 }
486 ARRAY_FREE(&mdata.ava);
487 FREE(&mdata.limit);
488 FREE(&mdata.title);
490 return 0;
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1150
void alias_free(struct Alias **ptr)
Free an Alias.
Definition: alias.c:641
struct AliasList Aliases
List of all the user's email aliases.
Definition: alias.c:58
int alias_array_alias_add(struct AliasViewArray *ava, struct Alias *alias)
Add an Alias to the AliasViewArray.
Definition: array.c:47
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:203
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:108
Static initializer for arrays.
Definition: array.h:57
static bool dlg_select_alias(struct Buffer *buf, struct AliasMenuData *mdata)
Display a menu of Aliases.
Definition: dlg_alias.c:310
#define FREE(x)
Definition: memory.h:43
#define MIN(a, b)
Definition: memory.h:31
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1031
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:496
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:567
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:652
int mutt_pattern_alias_func(char *prompt, struct AliasMenuData *mdata, struct Menu *menu)
Perform some Pattern matching for Alias.
Definition: pattern.c:243
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
AliasView array wrapper with Pattern information -.
Definition: gui.h:52
bool is_visible
Is visible?
Definition: gui.h:43
struct Alias * alias
Definition: gui.h:44
bool is_deleted
Is it deleted?
Definition: gui.h:42
bool is_tagged
Is it tagged?
Definition: gui.h:41
A shortcut for an email address or addresses.
Definition: alias.h:34
char * name
Short name.
Definition: alias.h:35
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_dialog()

void alias_dialog ( struct Mailbox m,
struct ConfigSubset sub 

Open the aliases dialog.

subConfig item

Definition at line 498 of file dlg_alias.c.

500 struct Alias *np = NULL;
502 struct AliasMenuData mdata = { ARRAY_HEAD_INITIALIZER, NULL, sub };
504 // Create a View Array of all the Aliases
505 TAILQ_FOREACH(np, &Aliases, entries)
506 {
508 }
510 if (!dlg_select_alias(NULL, &mdata))
511 goto done;
513 // Prepare the "To:" field of a new email
514 struct Email *e = email_new();
515 e->env = mutt_env_new();
517 struct AliasView *avp = NULL;
518 ARRAY_FOREACH(avp, &mdata.ava)
519 {
520 if (!avp->is_tagged)
521 continue;
523 struct AddressList al_copy = TAILQ_HEAD_INITIALIZER(al_copy);
524 if (alias_to_addrlist(&al_copy, avp->alias))
525 {
526 mutt_addrlist_copy(&e->env->to, &al_copy, false);
527 mutt_addrlist_clear(&al_copy);
528 }
529 }
531 mutt_send_message(SEND_REVIEW_TO, e, NULL, m, NULL, sub);
534 // Process any deleted aliases
535 ARRAY_FOREACH(avp, &mdata.ava)
536 {
537 if (avp->is_deleted)
538 {
539 TAILQ_REMOVE(&Aliases, avp->alias, entries);
540 alias_free(&avp->alias);
541 }
542 }
544 ARRAY_FREE(&mdata.ava);
545 FREE(&mdata.limit);
546 FREE(&mdata.title);
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
bool alias_to_addrlist(struct AddressList *al, struct Alias *alias)
Turn an Alias into an AddressList.
Definition: dlg_query.c:118
struct Email * email_new(void)
Create a new Email.
Definition: email.c:78
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:43
Definition: queue.h:637
int mutt_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Mailbox *m, struct EmailList *el, struct ConfigSubset *sub)
Send an email.
Definition: send.c:2126
Allow the user to edit the To field.
Definition: send.h:54
The envelope/body of an email.
Definition: email.h:37
struct Envelope * env
Envelope information.
Definition: email.h:66
struct AddressList to
Email's 'To' list.
Definition: envelope.h:60
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ AliasHelp

const struct Mapping AliasHelp[]
Initial value:
= {
{ N_("Exit"), OP_EXIT },
{ N_("Del"), OP_DELETE },
{ N_("Undel"), OP_UNDELETE },
{ N_("Sort"), OP_SORT },
{ N_("Rev-Sort"), OP_SORT_REVERSE },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
#define N_(a)
Definition: message.h:32

Help Bar for the Alias dialog (address book)

Definition at line 99 of file dlg_alias.c.