NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
dlgquery.c File Reference

Routines for querying an external address book. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.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 "mutt.h"
#include "lib.h"
#include "menu/lib.h"
#include "pattern/lib.h"
#include "question/lib.h"
#include "send/lib.h"
#include "alias.h"
#include "context.h"
#include "format_flags.h"
#include "gui.h"
#include "mutt_globals.h"
#include "mutt_logging.h"
#include "muttlib.h"
#include "opcodes.h"
+ Include dependency graph for dlgquery.c:

Go to the source code of this file.

Functions

static bool alias_to_addrlist (struct AddressList *al, struct Alias *alias)
 Turn an Alias into an AddressList. More...
 
static int query_search (struct Menu *menu, regex_t *rx, int line)
 Search a Address menu item - Implements Menu::search() -Try to match various Address fields. More...
 
static const char * query_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 query menu - Implements format_t -
Expando Description
%a Destination address
%c Current entry number
%e Extra information
%n Destination name
%t * if current entry is tagged, a space otherwise
More...
 
static void query_make_entry (struct Menu *menu, char *buf, size_t buflen, int line)
 Format a menu item for the query list - Implements Menu::make_entry() -. More...
 
static int query_tag (struct Menu *menu, int sel, int act)
 Tag an entry in the Query Menu - Implements Menu::tag() -. More...
 
static int query_run (char *s, bool verbose, struct AliasList *al, const struct ConfigSubset *sub)
 Run an external program to find Addresses. More...
 
int query_window_observer (struct NotifyCallback *nc)
 Notification that a Window has changed - Implements observer_t. More...
 
struct MuttWindowquery_dialog_new (struct AliasMenuData *mdata, char *query)
 Create an Query Selection Dialog. More...
 
static void dlg_select_query (char *buf, size_t buflen, struct AliasList *all, bool retbuf, struct ConfigSubset *sub)
 Get the user to enter an Address Query. More...
 
int query_complete (char *buf, size_t buflen, struct ConfigSubset *sub)
 Perform auto-complete using an Address Query. More...
 
void query_index (struct ConfigSubset *sub)
 Perform an Alias Query and display the results. More...
 

Variables

static const struct Mapping QueryHelp []
 Help Bar for the Address Query dialog. More...
 

Detailed Description

Routines for querying an external address book.

Authors
  • 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 http://www.gnu.org/licenses/.

Definition in file dlgquery.c.

Function Documentation

◆ alias_to_addrlist()

static bool alias_to_addrlist ( struct AddressList *  al,
struct Alias alias 
)
static

Turn an Alias into an AddressList.

Parameters
alAddressList to fill (must be empty)
aliasAlias to use
Return values
trueSuccess

Definition at line 121 of file dlgquery.c.

122 {
123  if (!al || !TAILQ_EMPTY(al) || !alias)
124  return false;
125 
126  mutt_addrlist_copy(al, &alias->addr, false);
127  if (!TAILQ_EMPTY(al))
128  {
129  struct Address *first = TAILQ_FIRST(al);
130  struct Address *second = TAILQ_NEXT(first, entries);
131  if (!second && !first->personal)
132  first->personal = mutt_str_dup(alias->name);
133 
134  mutt_addrlist_to_intl(al, NULL);
135  }
136 
137  return true;
138 }
char * name
Short name.
Definition: alias.h:35
#define TAILQ_FIRST(head)
Definition: queue.h:723
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
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
An email address.
Definition: address.h:35
char * personal
Real name of address.
Definition: address.h:37
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1305
#define TAILQ_NEXT(elm, field)
Definition: queue.h:832
#define TAILQ_EMPTY(head)
Definition: queue.h:721
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:

◆ query_run()

static int query_run ( char *  s,
bool  verbose,
struct AliasList *  al,
const struct ConfigSubset sub 
)
static

Run an external program to find Addresses.

Parameters
sString to match
verboseIf true, print progress messages
alAlias list to fill
subConfig items
Return values
0Success
-1Error

Definition at line 283 of file dlgquery.c.

285 {
286  FILE *fp = NULL;
287  char *buf = NULL;
288  size_t buflen;
289  char *msg = NULL;
290  size_t msglen = 0;
291  char *p = NULL;
292  struct Buffer *cmd = mutt_buffer_pool_get();
293 
294  const char *const query_command = cs_subset_string(sub, "query_command");
295  mutt_buffer_file_expand_fmt_quote(cmd, query_command, s);
296 
297  pid_t pid = filter_create(mutt_buffer_string(cmd), NULL, &fp, NULL);
298  if (pid < 0)
299  {
300  mutt_debug(LL_DEBUG1, "unable to fork command: %s\n", mutt_buffer_string(cmd));
302  return -1;
303  }
305 
306  if (verbose)
307  mutt_message(_("Waiting for response..."));
308 
309  /* The query protocol first reads one NL-terminated line. If an error
310  * occurs, this is assumed to be an error message. Otherwise it's ignored. */
311  msg = mutt_file_read_line(msg, &msglen, fp, NULL, MUTT_RL_NO_FLAGS);
312  while ((buf = mutt_file_read_line(buf, &buflen, fp, NULL, MUTT_RL_NO_FLAGS)))
313  {
314  p = strtok(buf, "\t\n");
315  if (p)
316  {
317  struct Alias *alias = alias_new();
318 
319  mutt_addrlist_parse(&alias->addr, p);
320  p = strtok(NULL, "\t\n");
321  if (p)
322  {
323  alias->name = mutt_str_dup(p);
324  p = strtok(NULL, "\t\n");
325  if (p)
326  alias->comment = mutt_str_dup(p);
327  }
328  TAILQ_INSERT_TAIL(al, alias, entries);
329  }
330  }
331  FREE(&buf);
332  mutt_file_fclose(&fp);
333  if (filter_wait(pid))
334  {
335  mutt_debug(LL_DEBUG1, "Error: %s\n", msg);
336  if (verbose)
337  mutt_error("%s", msg);
338  }
339  else
340  {
341  if (verbose)
342  mutt_message("%s", msg);
343  }
344  FREE(&msg);
345 
346  return 0;
347 }
A shortcut for an email address or addresses.
Definition: alias.h:33
char * name
Short name.
Definition: alias.h:35
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_error(...)
Definition: logging.h:88
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition: file.c:667
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Alias * alias_new(void)
Create a new Alias.
Definition: alias.c:618
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
char * comment
Free-form comment string.
Definition: alias.h:37
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:809
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Log at debug level 1.
Definition: logging.h:40
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:38
void mutt_buffer_file_expand_fmt_quote(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1435
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_window_observer()

int query_window_observer ( struct NotifyCallback nc)

Notification that a Window has changed - Implements observer_t.

Definition at line 352 of file dlgquery.c.

353 {
354  if ((nc->event_type != NT_WINDOW) || !nc->global_data || !nc->event_data)
355  return -1;
356 
357  if (nc->event_subtype != NT_WINDOW_DELETE)
358  return 0;
359 
360  struct MuttWindow *win_menu = nc->global_data;
361  struct EventWindow *ev_w = nc->event_data;
362  if (ev_w->win != win_menu)
363  return 0;
364 
365  struct Menu *menu = win_menu->wdata;
366 
369 
370  mutt_debug(LL_DEBUG5, "window delete done\n");
371  return 0;
372 }
Definition: lib.h:67
struct MuttWindow * win
Window that changed.
Definition: mutt_window.h:217
An Event that happened to a Window.
Definition: mutt_window.h:215
Window is about to be deleted.
Definition: mutt_window.h:206
Container for Accounts, Notifications.
Definition: neomutt.h:36
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition: observer.h:43
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
int alias_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: gui.c:43
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void * event_data
Data from notify_send()
Definition: observer.h:44
int query_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: dlgquery.c:352
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:228
Log at debug level 5.
Definition: logging.h:44
void * wdata
Private data.
Definition: mutt_window.h:145
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_dialog_new()

struct MuttWindow* query_dialog_new ( struct AliasMenuData mdata,
char *  query 
)

Create an Query Selection Dialog.

Parameters
mdataMenu data holding Aliases
queryInitial query string
Return values
ptrNew Dialog

Definition at line 380 of file dlgquery.c.

381 {
383  struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
384 
385  struct Menu *menu = dlg->wdata;
386 
388  menu->search = query_search;
389  menu->custom_search = true;
390  menu->tag = query_tag;
391  menu->max = ARRAY_SIZE(&mdata->ava);
392  menu->mdata = mdata;
393 
394  struct MuttWindow *win_menu = menu->win;
395 
396  // Override the Simple Dialog's recalc()
397  win_menu->recalc = alias_recalc;
398 
399  char title[256];
400  snprintf(title, sizeof(title), "%s%s", _("Query: "), query);
401  sbar_set_title(sbar, title);
402 
403  // NT_COLOR is handled by the SimpleDialog
406 
407  return dlg;
408 }
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:550
Definition: lib.h:67
Query Dialog, dlg_select_query()
Definition: mutt_window.h:90
#define _(a)
Definition: message.h:28
Container for Accounts, Notifications.
Definition: neomutt.h:36
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:105
static const struct Mapping QueryHelp[]
Help Bar for the Address Query dialog.
Definition: dlgquery.c:101
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
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
int alias_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: gui.c:43
Select from results of external query.
Definition: type.h:57
static int query_search(struct Menu *menu, regex_t *rx, int line)
Search a Address menu item - Implements Menu::search() -Try to match various Address fields...
Definition: dlgquery.c:145
static int query_tag(struct Menu *menu, int sel, int act)
Tag an entry in the Query Menu - Implements Menu::tag() -.
Definition: dlgquery.c:262
void * mdata
Private data.
Definition: lib.h:155
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:221
static void query_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
Format a menu item for the query list - Implements Menu::make_entry() -.
Definition: dlgquery.c:247
int(* tag)(struct Menu *menu, int sel, int act)
Definition: lib.h:130
bool custom_search
The menu implements its own non-Menusearch()-compatible search, trickle OP_SEARCH*.
Definition: lib.h:93
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
int max
Number of entries in the menu.
Definition: lib.h:71
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
int query_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: dlgquery.c:352
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:128
struct AliasViewArray ava
Array of AliasView.
Definition: gui.h:55
int(* recalc)(struct MuttWindow *win)
Definition: mutt_window.h:171
void * wdata
Private data.
Definition: mutt_window.h:145
int(* search)(struct Menu *menu, regex_t *rx, int line)
Definition: lib.h:118
int alias_recalc(struct MuttWindow *win)
Recalculate the display of the Alias Window - Implements MuttWindow::recalc() -.
Definition: gui.c:87
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_select_query()

static void dlg_select_query ( char *  buf,
size_t  buflen,
struct AliasList *  all,
bool  retbuf,
struct ConfigSubset sub 
)
static

Get the user to enter an Address Query.

Parameters
bufBuffer for the query
buflenLength of buffer
allAlias List
retbufIf true, populate the results
subConfig items

Definition at line 418 of file dlgquery.c.

420 {
421  struct AliasMenuData mdata = { NULL, ARRAY_HEAD_INITIALIZER, sub };
422  struct Alias *np = NULL;
423  TAILQ_FOREACH(np, all, entries)
424  {
425  alias_array_alias_add(&mdata.ava, np);
426  }
427  alias_array_sort(&mdata.ava, mdata.sub);
428 
429  struct MuttWindow *dlg = query_dialog_new(&mdata, buf);
430  struct Menu *menu = dlg->wdata;
431  struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
432 
433  int done = 0;
434  while (done == 0)
435  {
436  const int op = menu_loop(menu);
437  switch (op)
438  {
439  case OP_QUERY_APPEND:
440  case OP_QUERY:
441  {
442  if ((mutt_get_field(_("Query: "), buf, buflen, MUTT_COMP_NO_FLAGS,
443  false, NULL, NULL) != 0) ||
444  (buf[0] == '\0'))
445  {
446  break;
447  }
448 
449  if (op == OP_QUERY)
450  {
451  ARRAY_FREE(&mdata.ava);
452  aliaslist_free(all);
453  }
454 
455  struct AliasList al = TAILQ_HEAD_INITIALIZER(al);
456  query_run(buf, true, &al, sub);
458  char title[256];
459  snprintf(title, sizeof(title), "%s%s", _("Query: "), buf);
460  sbar_set_title(sbar, title);
461 
462  if (TAILQ_EMPTY(&al))
463  {
464  menu->max = 0;
465  break;
466  }
467 
468  struct Alias *tmp = NULL;
469  TAILQ_FOREACH_SAFE(np, &al, entries, tmp)
470  {
471  alias_array_alias_add(&mdata.ava, np);
472  TAILQ_REMOVE(&al, np, entries);
473  TAILQ_INSERT_TAIL(all, np, entries); // Transfer
474  }
475  alias_array_sort(&mdata.ava, mdata.sub);
476  menu->max = ARRAY_SIZE(&mdata.ava);
477  break;
478  }
479 
480  case OP_CREATE_ALIAS:
481  if (menu->tagprefix)
482  {
483  struct AddressList naddr = TAILQ_HEAD_INITIALIZER(naddr);
484 
485  struct AliasView *avp = NULL;
486  ARRAY_FOREACH(avp, &mdata.ava)
487  {
488  if (avp->is_tagged)
489  {
490  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
491  if (alias_to_addrlist(&al, avp->alias))
492  {
493  mutt_addrlist_copy(&naddr, &al, false);
494  mutt_addrlist_clear(&al);
495  }
496  }
497  }
498 
499  alias_create(&naddr, sub);
500  mutt_addrlist_clear(&naddr);
501  }
502  else
503  {
504  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
505  if (alias_to_addrlist(&al, ARRAY_GET(&mdata.ava, menu_get_index(menu))->alias))
506  {
507  alias_create(&al, sub);
508  mutt_addrlist_clear(&al);
509  }
510  }
511  break;
512 
513  case OP_GENERIC_SELECT_ENTRY:
514  if (retbuf)
515  {
516  done = 2;
517  break;
518  }
519  /* fallthrough */
520  case OP_MAIL:
521  {
522  struct Email *e = email_new();
523  e->env = mutt_env_new();
524  if (menu->tagprefix)
525  {
526  struct AliasView *avp = NULL;
527  ARRAY_FOREACH(avp, &mdata.ava)
528  {
529  if (avp->is_tagged)
530  {
531  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
532  if (alias_to_addrlist(&al, avp->alias))
533  {
534  mutt_addrlist_copy(&e->env->to, &al, false);
535  mutt_addrlist_clear(&al);
536  }
537  }
538  }
539  }
540  else
541  {
542  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
543  if (alias_to_addrlist(&al, ARRAY_GET(&mdata.ava, menu_get_index(menu))->alias))
544  {
545  mutt_addrlist_copy(&e->env->to, &al, false);
546  mutt_addrlist_clear(&al);
547  }
548  }
550  NeoMutt->sub);
552  break;
553  }
554 
555  case OP_SORT:
556  case OP_SORT_REVERSE:
557  {
558  int sort = cs_subset_sort(sub, "sort_alias");
559 
560  bool resort = true;
561  bool reverse = (op == OP_SORT_REVERSE);
562 
563  switch (mutt_multi_choice(
564  reverse ?
565  /* L10N: The highlighted letters must match the "Sort" options */
566  _("Rev-Sort (a)lias, a(d)dress or (u)nsorted?") :
567  /* L10N: The highlighted letters must match the "Rev-Sort" options */
568  _("Sort (a)lias, a(d)dress or (u)nsorted?"),
569  /* L10N: These must match the highlighted letters from "Sort" and "Rev-Sort" */
570  _("adu")))
571  {
572  case -1: /* abort */
573  resort = false;
574  break;
575 
576  case 1: /* (a)lias */
577  sort = SORT_ALIAS;
578  break;
579 
580  case 2: /* a(d)dress */
581  sort = SORT_ADDRESS;
582  break;
583 
584  case 3: /* (u)nsorted */
585  sort = SORT_ORDER;
586  break;
587  }
588 
589  if (resort)
590  {
591  sort |= reverse ? SORT_REVERSE : 0;
592 
593  cs_subset_str_native_set(sub, "sort_alias", sort, NULL);
595  }
596 
597  break;
598  }
599 
600  case OP_SEARCH_REVERSE:
601  case OP_SEARCH_NEXT:
602  case OP_SEARCH_OPPOSITE:
603  case OP_SEARCH:
604  {
605  int index = mutt_search_alias_command(menu, menu_get_index(menu), op);
606  if (index == -1)
607  break;
608 
609  menu_set_index(menu, index);
610  break;
611  }
612 
613  case OP_MAIN_LIMIT:
614  {
615  int rc = mutt_pattern_alias_func(MUTT_LIMIT, _("Limit to messages matching: "),
616  &mdata, menu);
617  if (rc == 0)
618  {
619  alias_array_sort(&mdata.ava, mdata.sub);
620  alias_set_title(sbar, _("Query"), mdata.str);
622  }
623 
624  break;
625  }
626 
627  case OP_EXIT:
628  done = 1;
629  break;
630  }
631  }
632 
633  /* if we need to return the selected entries */
634  if (retbuf && (done == 2))
635  {
636  bool tagged = false;
637  size_t curpos = 0;
638 
639  memset(buf, 0, buflen);
640 
641  /* check for tagged entries */
642  struct AliasView *avp = NULL;
643  ARRAY_FOREACH(avp, &mdata.ava)
644  {
645  if (!avp->is_tagged)
646  continue;
647 
648  if (curpos == 0)
649  {
650  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
651  if (alias_to_addrlist(&al, avp->alias))
652  {
654  tagged = true;
655  mutt_addrlist_write(&al, buf, buflen, false);
656  curpos = mutt_str_len(buf);
657  mutt_addrlist_clear(&al);
658  }
659  }
660  else if (curpos + 2 < buflen)
661  {
662  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
663  if (alias_to_addrlist(&al, avp->alias))
664  {
666  strcat(buf, ", ");
667  mutt_addrlist_write(&al, buf + curpos + 2, buflen - curpos - 2, false);
668  curpos = mutt_str_len(buf);
669  mutt_addrlist_clear(&al);
670  }
671  }
672  }
673  /* then enter current message */
674  if (!tagged)
675  {
676  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
677  if (alias_to_addrlist(&al, ARRAY_GET(&mdata.ava, menu_get_index(menu))->alias))
678  {
680  mutt_addrlist_write(&al, buf, buflen, false);
681  mutt_addrlist_clear(&al);
682  }
683  }
684  }
685 
686  simple_dialog_free(&dlg);
687  ARRAY_FREE(&mdata.ava);
688 }
static bool alias_to_addrlist(struct AddressList *al, struct Alias *alias)
Turn an Alias into an AddressList.
Definition: dlgquery.c:121
A shortcut for an email address or addresses.
Definition: alias.h:33
The "current" mailbox.
Definition: context.h:37
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:550
The envelope/body of an email.
Definition: email.h:37
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:165
Definition: lib.h:67
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
struct Mailbox * ctx_mailbox(struct Context *ctx)
wrapper to get the mailbox in a Context, or NULL
Definition: context.c:444
AliasView array wrapper with Pattern information -.
Definition: gui.h:52
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1388
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:198
Messages in limited view.
Definition: mutt.h:101
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
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
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:105
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:735
#define _(a)
Definition: message.h:28
Sort by email address.
Definition: sort2.h:54
GUI data wrapping an Alias.
Definition: gui.h:35
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
int alias_array_alias_add(struct AliasViewArray *ava, struct Alias *alias)
Add an Alias to the AliasViewArray.
Definition: array.c:45
int mutt_pattern_alias_func(int op, char *prompt, struct AliasMenuData *mdata, struct Menu *menu)
Perform some Pattern matching for Alias.
Definition: pattern.c:241
Container for Accounts, Notifications.
Definition: neomutt.h:36
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
void alias_set_title(struct MuttWindow *sbar, char *menu_name, char *limit)
Create a title string for the Menu.
Definition: gui.c:67
void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
Sort and reindex an AliasViewArray.
Definition: sort.c:157
struct Email * email_new(void)
Create a new Email.
Definition: email.c:78
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:39
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:52
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:48
struct Envelope * env
Envelope information.
Definition: email.h:90
void alias_create(struct AddressList *al, const struct ConfigSubset *sub)
Create a new Alias from an Address.
Definition: alias.c:372
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:2125
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:54
char * str
String representing the limit being used.
Definition: gui.h:54
static int query_run(char *s, bool verbose, struct AliasList *al, const struct ConfigSubset *sub)
Run an external program to find Addresses.
Definition: dlgquery.c:283
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
struct Alias * alias
Alias.
Definition: gui.h:44
void * mdata
Private data.
Definition: lib.h:155
bool tagprefix
User has pressed <tag-prefix>
Definition: lib.h:75
struct MuttWindow * query_dialog_new(struct AliasMenuData *mdata, char *query)
Create an Query Selection Dialog.
Definition: dlgquery.c:380
Sort by email alias.
Definition: sort2.h:53
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: question.c:49
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:809
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:221
int max
Number of entries in the menu.
Definition: lib.h:71
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:650
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
bool is_tagged
Is it tagged?
Definition: gui.h:41
struct ConfigSubset * sub
Config items.
Definition: gui.h:56
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct AliasViewArray ava
Array of AliasView.
Definition: gui.h:55
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define TAILQ_EMPTY(head)
Definition: queue.h:721
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
void * wdata
Private data.
Definition: mutt_window.h:145
int mutt_search_alias_command(struct Menu *menu, int cur, int op)
Perform a search.
Definition: pattern.c:652
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
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_complete()

int query_complete ( char *  buf,
size_t  buflen,
struct ConfigSubset sub 
)

Perform auto-complete using an Address Query.

Parameters
bufBuffer for completion
buflenLength of buffer
subConfig item
Return values
0Always

Definition at line 697 of file dlgquery.c.

698 {
699  const char *const query_command = cs_subset_string(sub, "query_command");
700  if (!query_command)
701  {
702  mutt_warning(_("Query command not defined"));
703  return 0;
704  }
705 
706  struct AliasList al = TAILQ_HEAD_INITIALIZER(al);
707  query_run(buf, true, &al, sub);
708  if (TAILQ_EMPTY(&al))
709  return 0;
710 
711  struct Alias *a_first = TAILQ_FIRST(&al);
712  if (!TAILQ_NEXT(a_first, entries)) // only one response?
713  {
714  struct AddressList addr = TAILQ_HEAD_INITIALIZER(addr);
715  if (alias_to_addrlist(&addr, a_first))
716  {
717  mutt_addrlist_to_local(&addr);
718  buf[0] = '\0';
719  mutt_addrlist_write(&addr, buf, buflen, false);
720  mutt_addrlist_clear(&addr);
721  aliaslist_free(&al);
723  }
724  return 0;
725  }
726 
727  /* multiple results, choose from query menu */
728  dlg_select_query(buf, buflen, &al, true, sub);
729  aliaslist_free(&al);
730  return 0;
731 }
static bool alias_to_addrlist(struct AddressList *al, struct Alias *alias)
Turn an Alias into an AddressList.
Definition: dlgquery.c:121
A shortcut for an email address or addresses.
Definition: alias.h:33
#define TAILQ_FIRST(head)
Definition: queue.h:723
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1388
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
#define _(a)
Definition: message.h:28
static void dlg_select_query(char *buf, size_t buflen, struct AliasList *all, bool retbuf, struct ConfigSubset *sub)
Get the user to enter an Address Query.
Definition: dlgquery.c:418
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:112
#define mutt_warning(...)
Definition: logging.h:86
static int query_run(char *s, bool verbose, struct AliasList *al, const struct ConfigSubset *sub)
Run an external program to find Addresses.
Definition: dlgquery.c:283
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:650
#define TAILQ_NEXT(elm, field)
Definition: queue.h:832
#define TAILQ_EMPTY(head)
Definition: queue.h:721
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_index()

void query_index ( struct ConfigSubset sub)

Perform an Alias Query and display the results.

Parameters
subConfig item

Definition at line 737 of file dlgquery.c.

738 {
739  const char *const query_command = cs_subset_string(sub, "query_command");
740  if (!query_command)
741  {
742  mutt_warning(_("Query command not defined"));
743  return;
744  }
745 
746  char buf[256] = { 0 };
747  if ((mutt_get_field(_("Query: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS, false,
748  NULL, NULL) != 0) ||
749  (buf[0] == '\0'))
750  {
751  return;
752  }
753 
754  struct AliasList al = TAILQ_HEAD_INITIALIZER(al);
755  query_run(buf, false, &al, sub);
756  if (TAILQ_EMPTY(&al))
757  return;
758 
759  dlg_select_query(buf, sizeof(buf), &al, false, sub);
760  aliaslist_free(&al);
761 }
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
#define _(a)
Definition: message.h:28
static void dlg_select_query(char *buf, size_t buflen, struct AliasList *all, bool retbuf, struct ConfigSubset *sub)
Get the user to enter an Address Query.
Definition: dlgquery.c:418
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:52
#define mutt_warning(...)
Definition: logging.h:86
static int query_run(char *s, bool verbose, struct AliasList *al, const struct ConfigSubset *sub)
Run an external program to find Addresses.
Definition: dlgquery.c:283
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:650
#define TAILQ_EMPTY(head)
Definition: queue.h:721
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ QueryHelp

const struct Mapping QueryHelp[]
static
Initial value:
= {
{ N_("Exit"), OP_EXIT },
{ N_("Mail"), OP_MAIL },
{ N_("New Query"), OP_QUERY },
{ N_("Make Alias"), OP_CREATE_ALIAS },
{ N_("Sort"), OP_SORT },
{ N_("Rev-Sort"), OP_SORT_REVERSE },
{ N_("Search"), OP_SEARCH },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Help Bar for the Address Query dialog.

Definition at line 101 of file dlgquery.c.