NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
GUI: Dialog Windows

A Dialog is an interactive set of windows allowing the user to perform some task. More...

Functions

static bool dlg_alias (struct AliasMenuData *mdata)
 Display a menu of Aliases -.
 
static bool dlg_query (struct Buffer *buf, struct AliasMenuData *mdata)
 Get the user to enter an Address Query -.
 
void dlg_attach (struct ConfigSubset *sub, struct MailboxView *mv, struct Email *e, FILE *fp, bool attach_msg)
 Show the attachments in a Menu -.
 
void dlg_autocrypt (void)
 Display the Autocrypt account Menu -.
 
void dlg_browser (struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
 Let the user select a file -.
 
int dlg_compose (struct Email *e, struct Buffer *fcc, uint8_t flags, struct ConfigSubset *sub)
 Allow the user to edit the message envelope -.
 
int dlg_certificate (const char *title, struct StringArray *carr, bool allow_always, bool allow_skip)
 Ask the user to validate the certificate -.
 
void dlg_history (struct Buffer *buf, struct StringArray *matches)
 Select an item from a history list -.
 
struct Mailboxdlg_index (struct MuttWindow *dlg, struct Mailbox *m_init)
 Display a list of emails -.
 
void dlg_list (struct Mailbox *m, struct Email *e)
 Display mailing-list actions for an email -.
 
struct CryptKeyInfodlg_gpgme (struct CryptKeyInfo *keys, struct Address *p, const char *s, unsigned int app, bool *forced_valid)
 Get the user to select a key -.
 
struct PgpKeyInfodlg_pgp (struct PgpKeyInfo *keys, struct Address *p, const char *s)
 Let the user select a key to use -.
 
struct SmimeKeydlg_smime (struct SmimeKey *keys, const char *query)
 Get the user to select a key -.
 
int dlg_pager (struct PagerView *pview)
 Display an email, attachment, or help, in a window -.
 
bool dlg_pattern (struct Buffer *buf)
 Show menu to select a Pattern -.
 
struct Emaildlg_postpone (struct Mailbox *m)
 Create a Menu to select a postponed message -.
 

Detailed Description

A Dialog is an interactive set of windows allowing the user to perform some task.

The All Dialogs window is a container window and not visible. All active dialogs will be children of this window, though only one will be active at a time.

Windows

Name Type Constructor
All Dialogs WT_ALL_DIALOGS alldialogs_new()

Parent

Children

The All Dialogs window has many possible children, e.g.

Data

The All Dialogs window has no data.

Events

Once constructed, it is controlled by the following events:

Event Type Handler
NT_WINDOW alldialogs_window_observer()

The All Dialogs window does not implement MuttWindow::recalc() or MuttWindow::repaint().

Function Documentation

◆ dlg_alias()

static bool dlg_alias ( struct AliasMenuData * mdata)
static

Display a menu of Aliases -.

Parameters
mdataMenu data holding Aliases
Return values
trueSelection was made

The Alias Dialog is an Address Book. The user can select addresses to add to an Email.

Definition at line 271 of file dlg_alias.c.

272{
274 ASSERT(mod_data);
275
276 if (ARRAY_EMPTY(&mdata->ava))
277 {
278 mutt_warning(_("You have no aliases"));
279 return false;
280 }
281
282 mdata->title = mutt_str_dup(_("Aliases"));
283
284 struct SimpleDialogWindows sdw = alias_dialog_new(mdata);
285 struct Menu *menu = sdw.menu;
286 mdata->menu = menu;
287 mdata->sbar = sdw.sbar;
288
289 alias_array_sort(&mdata->ava, mdata->sub);
290
291 struct AliasView *avp = NULL;
292 ARRAY_FOREACH(avp, &mdata->ava)
293 {
294 avp->num = ARRAY_FOREACH_IDX_avp;
295 }
296
297 struct MuttWindow *old_focus = window_set_focus(menu->win);
298 // ---------------------------------------------------------------------------
299 // Event Loop
300 int rc = 0;
301 int op = OP_NULL;
302 struct KeyEvent event = { 0, OP_NULL };
303 do
304 {
305 menu_tagging_dispatcher(menu->win, &event);
306 window_redraw(NULL);
307
308 event = km_dokey(mod_data->menu_alias, GETCH_NONE);
309 op = event.op;
310 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
311 if (op < 0)
312 continue;
313 if (op == OP_NULL)
314 {
315 km_error_key(mod_data->menu_alias);
316 continue;
317 }
319
320 rc = alias_function_dispatcher(sdw.dlg, &event);
321 if (rc == FR_UNKNOWN)
322 rc = menu_function_dispatcher(menu->win, &event);
323 if (rc == FR_UNKNOWN)
324 rc = global_function_dispatcher(menu->win, &event);
325 } while ((rc != FR_DONE) && (rc != FR_CONTINUE));
326 // ---------------------------------------------------------------------------
327
328 window_set_focus(old_focus);
330 window_redraw(NULL);
331 return (rc == FR_CONTINUE); // Was a selection made?
332}
void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
Sort and reindex an AliasViewArray.
Definition sort.c:235
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
@ FR_DONE
Exit the Dialog.
Definition dispatcher.h:36
@ FR_UNKNOWN
Unknown function.
Definition dispatcher.h:34
@ FR_CONTINUE
Remain in the Dialog.
Definition dispatcher.h:35
static struct SimpleDialogWindows alias_dialog_new(struct AliasMenuData *mdata)
Create an Alias Selection Dialog.
Definition dlg_alias.c:232
struct KeyEvent km_dokey(const struct MenuDefinition *md, GetChFlags flags)
Determine what a keypress should do.
Definition get.c:518
void km_error_key(const struct MenuDefinition *md)
Handle an unbound key sequence.
Definition get.c:328
@ GETCH_NONE
No flags are set.
Definition get.h:38
int alias_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Alias function - Implements function_dispatcher_t -.
Definition functions.c:640
int menu_tagging_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform tagging operations on the Menu - Implements function_dispatcher_t -.
Definition tagging.c:239
int global_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Global function - Implements function_dispatcher_t -.
Definition global.c:182
int menu_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Menu function - Implements function_dispatcher_t -.
Definition functions.c:366
#define mutt_warning(...)
Definition logging2.h:92
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition simple.c:169
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
@ MODULE_ID_ALIAS
ModuleAlias, Alias
Definition module_api.h:48
#define _(a)
Definition message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition opcodes.c:48
#define ASSERT(COND)
Definition signal2.h:59
struct AliasViewArray ava
All Aliases/Queries.
Definition gui.h:56
char * title
Title for the status bar.
Definition gui.h:63
Alias private Module data.
Definition module_data.h:33
struct MenuDefinition * menu_alias
Alias menu definition.
Definition module_data.h:42
GUI data wrapping an Alias.
Definition gui.h:38
int num
Index number in list.
Definition gui.h:39
An event such as a keypress.
Definition get.h:75
int op
Function opcode, e.g. OP_HELP.
Definition get.h:77
Definition lib.h:86
struct MuttWindow * win
Window holding the Menu.
Definition lib.h:94
void * mdata
Private data.
Definition lib.h:155
Container for Accounts, Notifications.
Definition neomutt.h:41
Tuple for the results of simple_dialog_new()
Definition simple.h:35
struct MuttWindow * sbar
Simple Bar.
Definition simple.h:37
struct Menu * menu
Menu.
Definition simple.h:38
struct MuttWindow * dlg
Main Dialog Window.
Definition simple.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_query()

static bool dlg_query ( struct Buffer * buf,
struct AliasMenuData * mdata )
static

Get the user to enter an Address Query -.

Parameters
bufBuffer for the query
mdataMenu data holding Aliases
Return values
trueSelection was made

The Select Query Dialog is an Address Book. It is dynamically created from an external source using $query_command.

The user can select addresses to add to an Email.

Definition at line 352 of file dlg_query.c.

353{
355 ASSERT(mod_data);
356
357 struct SimpleDialogWindows sdw = query_dialog_new(mdata, buf_string(buf));
358 struct Menu *menu = sdw.menu;
359 mdata->menu = menu;
360 mdata->sbar = sdw.sbar;
361 mdata->query = buf;
362
363 alias_array_sort(&mdata->ava, mdata->sub);
364
365 struct AliasView *avp = NULL;
366 ARRAY_FOREACH(avp, &mdata->ava)
367 {
368 avp->num = ARRAY_FOREACH_IDX_avp;
369 }
370
371 struct MuttWindow *old_focus = window_set_focus(menu->win);
372 // ---------------------------------------------------------------------------
373 // Event Loop
374 int rc = 0;
375 int op = OP_NULL;
376 struct KeyEvent event = { 0, OP_NULL };
377 do
378 {
379 menu_tagging_dispatcher(menu->win, &event);
380 window_redraw(NULL);
381
382 event = km_dokey(mod_data->menu_query, GETCH_NONE);
383 op = event.op;
384 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
385 if (op < 0)
386 continue;
387 if (op == OP_NULL)
388 {
389 km_error_key(mod_data->menu_query);
390 continue;
391 }
393
394 rc = alias_function_dispatcher(sdw.dlg, &event);
395 if (rc == FR_UNKNOWN)
396 rc = menu_function_dispatcher(menu->win, &event);
397 if (rc == FR_UNKNOWN)
398 rc = global_function_dispatcher(menu->win, &event);
399 } while ((rc != FR_DONE) && (rc != FR_CONTINUE));
400 // ---------------------------------------------------------------------------
401
402 window_set_focus(old_focus);
404 window_redraw(NULL);
405 return (rc == FR_CONTINUE); // Was a selection made?
406}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
static struct SimpleDialogWindows query_dialog_new(struct AliasMenuData *mdata, const char *query)
Create an Query Selection Dialog.
Definition dlg_query.c:307
struct MenuDefinition * menu_query
Query menu definition.
Definition module_data.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_attach()

void dlg_attach ( struct ConfigSubset * sub,
struct MailboxView * mv,
struct Email * e,
FILE * fp,
bool attach_msg )

Show the attachments in a Menu -.

Parameters
subConfig Subset
mvMailbox view
eEmail
fpFile with the content of the email, or NULL
attach_msgAre we in "attach message" mode?

The Select Attachment dialog shows an Email's attachments. They can be viewed using the Pager or Mailcap programs. They can also be saved, printed, deleted, etc.

Definition at line 208 of file dlg_attach.c.

210{
212 ASSERT(mod_data);
213
214 if (!mv || !mv->mailbox || !e || !fp)
215 return;
216
217 struct Mailbox *m = mv->mailbox;
218
219 /* make sure we have parsed this message */
222
225 struct Menu *menu = sdw.menu;
227 menu->tag = attach_tag;
228
229 struct AttachCtx *actx = mutt_actx_new();
230 actx->email = e;
231 actx->fp_root = fp;
232 mutt_update_recvattach_menu(actx, menu, true);
233
235 priv->menu = menu;
236 priv->actx = actx;
237 priv->sub = sub;
238 priv->mailbox = m;
239 priv->attach_msg = attach_msg;
240 menu->mdata = priv;
242
243 // NT_COLOR is handled by the SimpleDialog
246
247 sbar_set_title(sdw.sbar, _("Attachments"));
248
249 struct MuttWindow *old_focus = window_set_focus(menu->win);
250 // ---------------------------------------------------------------------------
251 // Event Loop
252 int rc = 0;
253 int op = OP_NULL;
254 struct KeyEvent event = { 0, OP_NULL };
255 do
256 {
257 menu_tagging_dispatcher(menu->win, &event);
258 window_redraw(NULL);
259
260 event = km_dokey(mod_data->menu_attach, GETCH_NONE);
261 op = event.op;
262 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
263 if (op < 0)
264 continue;
265 if (op == OP_NULL)
266 {
267 km_error_key(mod_data->menu_attach);
268 continue;
269 }
271
272 rc = attach_function_dispatcher(sdw.dlg, &event);
273 if (rc == FR_UNKNOWN)
274 rc = menu_function_dispatcher(menu->win, &event);
275 if (rc == FR_UNKNOWN)
276 rc = global_function_dispatcher(menu->win, &event);
277
278 if (rc == FR_CONTINUE)
279 {
280 event.op = priv->op;
281 }
282
283 } while (rc != FR_DONE);
284 // ---------------------------------------------------------------------------
285
286 window_set_focus(old_focus);
288}
struct AttachCtx * mutt_actx_new(void)
Create a new Attachment Context.
Definition attach.c:189
void mutt_parse_mime_message(struct Email *e, FILE *fp)
Parse a MIME email.
Definition commands.c:627
struct AttachPrivateData * attach_private_data_new(void)
Create new Attach Data.
@ CMD_MESSAGE_HOOK
:message-hook
Definition command.h:97
static const struct Mapping AttachmentHelp[]
Help Bar for the Attachment selection dialog.
Definition dlg_attach.c:92
int attach_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Attach function - Implements function_dispatcher_t -.
Definition functions.c:829
static int attach_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format an Attachment for the Menu - Implements Menu::make_entry() -.
Definition dlg_attach.c:132
void attach_private_data_free(struct Menu *menu, void **ptr)
Free the Attach Data - Implements Menu::mdata_free() -.
static int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::tag() -.
Definition dlg_attach.c:154
static int attach_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition dlg_attach.c:108
static int attach_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition dlg_attach.c:173
struct SimpleDialogWindows simple_dialog_new(const struct MenuDefinition *md, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition simple.c:132
void exec_message_hook(struct Mailbox *m, struct Email *e, enum CommandId id)
Perform a message hook.
Definition exec.c:137
@ MODULE_ID_ATTACH
ModuleAttach, Attachments
Definition module_api.h:49
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:191
@ WT_DLG_ATTACH
Attach Dialog, dlg_attach()
Definition mutt_window.h:78
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition notify_type.h:58
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition notify_type.h:43
void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition sbar.c:227
A set of attachments.
Definition attach.h:65
FILE * fp_root
Used by recvattach for updating.
Definition attach.h:67
struct Email * email
Used by recvattach for updating.
Definition attach.h:66
Attach private Module data.
Definition module_data.h:32
struct MenuDefinition * menu_attach
Attach menu definition.
Definition module_data.h:40
Private state data for Attachments.
int op
Op returned from the Pager, e.g. OP_NEXT_ENTRY.
struct Menu * menu
Current Menu.
struct ConfigSubset * sub
Config subset.
struct AttachCtx * actx
List of all Attachments.
bool attach_msg
Are we in "attach message" mode?
struct Mailbox * mailbox
Current Mailbox.
struct Notify * notify
Notifications: NotifyConfig, EventConfig.
Definition subset.h:51
struct Mailbox * mailbox
Current Mailbox.
Definition mview.h:51
A mailbox.
Definition mailbox.h:81
void(* mdata_free)(struct Menu *menu, void **ptr)
Definition lib.h:169
int(* tag)(struct Menu *menu, int sel, int act)
Definition lib.h:139
int(* make_entry)(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Definition lib.h:114
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_autocrypt()

void dlg_autocrypt ( void )

Display the Autocrypt account Menu -.

The Autocrypt Dialog lets the user select an Autocrypt Account to use.

Definition at line 241 of file dlg_autocrypt.c.

242{
244 ASSERT(mod_data);
245
246 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
247 if (!c_autocrypt)
248 return;
249
250 if (mutt_autocrypt_init(false) != 0)
251 return;
252
255
256 struct Menu *menu = sdw.menu;
257
258 struct AutocryptData *ad = autocrypt_data_new();
259 ad->menu = menu;
260
262 menu->mdata = ad;
264
266
267 // L10N: Autocrypt Account Management Menu title
268 sbar_set_title(sdw.sbar, _("Autocrypt Accounts"));
269
270 // NT_COLOR is handled by the SimpleDialog
273
274 struct MuttWindow *old_focus = window_set_focus(menu->win);
275 // ---------------------------------------------------------------------------
276 // Event Loop
277 int op = OP_NULL;
278 struct KeyEvent event = { 0, OP_NULL };
279 do
280 {
281 menu_tagging_dispatcher(menu->win, &event);
282 window_redraw(NULL);
283
284 event = km_dokey(mod_data->menu_autocrypt, GETCH_NONE);
285 op = event.op;
286 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
287 if (op < 0)
288 continue;
289 if (op == OP_NULL)
290 {
291 km_error_key(mod_data->menu_autocrypt);
292 continue;
293 }
295
296 int rc = autocrypt_function_dispatcher(sdw.dlg, &event);
297
298 if (rc == FR_UNKNOWN)
299 rc = menu_function_dispatcher(menu->win, &event);
300 if (rc == FR_UNKNOWN)
301 rc = global_function_dispatcher(menu->win, &event);
302 } while (!ad->done);
303 // ---------------------------------------------------------------------------
304
305 window_set_focus(old_focus);
307}
int mutt_autocrypt_init(bool can_create)
Initialise Autocrypt.
Definition autocrypt.c:104
struct AutocryptData * autocrypt_data_new(void)
Create new Autocrypt Data.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
static const struct Mapping AutocryptHelp[]
Help Bar for the Autocrypt Account selection dialog.
bool populate_menu(struct Menu *menu)
Add the Autocrypt data to a Menu.
int autocrypt_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Autocrypt function - Implements function_dispatcher_t -.
Definition functions.c:239
static int autocrypt_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format an Autocrypt Account for the Menu - Implements Menu::make_entry() -.
void autocrypt_data_free(struct Menu *menu, void **ptr)
Free Autocrypt Data - Implements Menu::mdata_free() -.
static int autocrypt_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
static int autocrypt_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
@ MODULE_ID_AUTOCRYPT
ModuleAutocrypt, Autocrypt
Definition module_api.h:50
@ WT_DLG_AUTOCRYPT
Autocrypt Dialog, dlg_autocrypt()
Definition mutt_window.h:79
Data to pass to the Autocrypt Functions.
bool done
Should we close the Dialog?
struct Menu * menu
Autocrypt Menu.
Autocrypt private Module data.
Definition module_data.h:32
struct MenuDefinition * menu_autocrypt
Autocrypt menu definition.
Definition module_data.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_browser()

void dlg_browser ( struct Buffer * file,
SelectFileFlags flags,
struct Mailbox * m,
char *** files,
int * numfiles )

Let the user select a file -.

Parameters
[in]fileBuffer for the result
[in]flagsFlags, see SelectFileFlags
[in]mMailbox
[out]filesArray of selected files
[out]numfilesNumber of selected files

The Select File Dialog is a file browser. It allows the user to select a file or directory to use.

Definition at line 846 of file dlg_browser.c.

848{
850 ASSERT(mod_data);
852 priv->file = file;
853 priv->mailbox = m;
854 priv->files = files;
855 priv->numfiles = numfiles;
856 priv->multiple = (flags & MUTT_SEL_MULTI);
857 priv->folder = (flags & MUTT_SEL_FOLDER);
858 priv->state.is_mailbox_list = (flags & MUTT_SEL_MAILBOX) && priv->folder;
859 priv->last_selected_mailbox = -1;
860
861 if (OptNews)
862 {
863 if (buf_is_empty(file))
864 {
865 priv->state.is_mailbox_list = true;
866 // struct NntpModuleData *nntp_mod_data = neomutt_get_module_data(NeoMutt, MODULE_ID_NNTP);
867 // struct NntpAccountData *adata = nntp_mod_data->current_news_srv;
868
869 // /* default state for news reader mode is browse subscribed newsgroups */
870 // priv->state.is_mailbox_list = false;
871 // for (size_t i = 0; i < adata->groups_num; i++)
872 // {
873 // struct NntpMboxData *mdata = adata->groups_list[i];
874 // if (mdata && mdata->subscribed)
875 // {
876 // priv->state.is_mailbox_list = true;
877 // break;
878 // }
879 // }
880 }
881 else
882 {
883 buf_copy(priv->prefix, file);
884 }
885 }
886 else if (!buf_is_empty(file))
887 {
888 expand_path(file, false);
890 {
891 init_state(&priv->state);
892 priv->state.imap_browse = true;
893 if (imap_browse(buf_string(file), &priv->state) == 0)
894 {
895 buf_strcpy(&mod_data->last_dir, priv->state.folder);
896 browser_sort(&priv->state);
897 }
898 }
899 else
900 {
901 int i = buf_len(file);
902 i--;
903 for (; (i > 0) && ((buf_string(file))[i] != '/'); i--)
904 {
905 ; // do nothing
906 }
907
908 if (i > 0)
909 {
910 if ((buf_string(file))[0] == '/')
911 {
912 buf_strcpy_n(&mod_data->last_dir, buf_string(file), i);
913 }
914 else
915 {
916 mutt_path_getcwd(&mod_data->last_dir);
917 buf_addch(&mod_data->last_dir, '/');
918 buf_addstr_n(&mod_data->last_dir, buf_string(file), i);
919 }
920 }
921 else
922 {
923 if ((buf_string(file))[0] == '/')
924 buf_strcpy(&mod_data->last_dir, "/");
925 else
926 mutt_path_getcwd(&mod_data->last_dir);
927 }
928
929 if ((i <= 0) && (buf_string(file)[0] != '/'))
930 buf_copy(priv->prefix, file);
931 else
932 buf_strcpy(priv->prefix, buf_string(file) + i + 1);
933 priv->kill_prefix = true;
934 }
935 }
936 else
937 {
938 if (priv->folder)
939 {
940 /* Whether we use the tracking feature of the browser depends
941 * on which sort method we chose to use. This variable is defined
942 * only to help readability of the code. */
943 bool browser_track = false;
944
945 const enum EmailSortType c_browser_sort = cs_subset_sort(NeoMutt->sub, "browser_sort");
946 switch (c_browser_sort & SORT_MASK)
947 {
951 browser_track = true;
952 break;
953 }
954
955 /* We use mutt_browser_select_dir to initialize the two
956 * variables (LastDir, LastDirBackup) at the appropriate
957 * values.
958 *
959 * We do it only when LastDir is not set (first pass there)
960 * or when CurrentFolder and LastDirBackup are not the same.
961 * This code is executed only when we list files, not when
962 * we press up/down keys to navigate in a displayed list.
963 *
964 * We only do this when CurrentFolder has been set (ie, not
965 * when listing folders on startup with "neomutt -y").
966 *
967 * This tracker is only used when browser_track is true,
968 * meaning only with sort methods SUBJECT/DESC for now. */
969 if (CurrentFolder)
970 {
971 if (buf_is_empty(&mod_data->last_dir))
972 {
973 /* If browsing in "local"-mode, than we chose to define LastDir to
974 * MailDir */
976 {
977 case MUTT_IMAP:
978 case MUTT_MAILDIR:
979 case MUTT_MBOX:
980 case MUTT_MH:
981 case MUTT_MMDF:
982 {
983 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
984 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
985 if (c_folder)
986 buf_strcpy(&mod_data->last_dir, c_folder);
987 else if (c_spool_file)
988 mutt_browser_select_dir(c_spool_file);
989 break;
990 }
991 default:
993 break;
994 }
995 }
996 else if (!mutt_str_equal(CurrentFolder, buf_string(&mod_data->last_dir_backup)))
997 {
999 }
1000 }
1001
1002 /* When browser tracking feature is disabled, clear LastDirBackup */
1003 if (!browser_track)
1004 buf_reset(&mod_data->last_dir_backup);
1005 }
1006 else
1007 {
1008 mutt_path_getcwd(&mod_data->last_dir);
1009 }
1010
1011 if (!priv->state.is_mailbox_list &&
1012 (imap_path_probe(buf_string(&mod_data->last_dir), NULL) == MUTT_IMAP))
1013 {
1014 init_state(&priv->state);
1015 priv->state.imap_browse = true;
1016 imap_browse(buf_string(&mod_data->last_dir), &priv->state);
1017 browser_sort(&priv->state);
1018 }
1019 else
1020 {
1021 size_t i = buf_len(&mod_data->last_dir);
1022 while ((i > 0) && (buf_string(&mod_data->last_dir)[--i] == '/'))
1023 mod_data->last_dir.data[i] = '\0';
1024 buf_fix_dptr(&mod_data->last_dir);
1025 if (buf_is_empty(&mod_data->last_dir))
1026 mutt_path_getcwd(&mod_data->last_dir);
1027 }
1028 }
1029
1030 buf_reset(file);
1031
1032 const struct Mapping *help_data = NULL;
1033
1034 if (OptNews)
1035 help_data = FolderNewsHelp;
1036 else
1037 help_data = FolderHelp;
1038
1039 struct SimpleDialogWindows sdw = simple_dialog_new(mod_data->menu_browser,
1040 WT_DLG_BROWSER, help_data);
1041
1042 struct Menu *menu = sdw.menu;
1044 menu->search = select_file_search;
1045 menu->mdata = priv;
1046
1047 priv->menu = menu;
1048 /* Enable tagging for file selection (multiple) and mailbox/newsgroup lists */
1049 if (priv->multiple || priv->state.is_mailbox_list)
1050 priv->menu->tag = file_tag;
1051
1052 priv->sbar = sdw.sbar;
1053
1054 struct MuttWindow *win_menu = priv->menu->win;
1055
1056 // NT_COLOR is handled by the SimpleDialog
1060
1061 struct MuttWindow *old_focus = window_set_focus(priv->menu->win);
1062
1063 if (priv->state.is_mailbox_list)
1064 {
1065 examine_mailboxes(m, NULL, &priv->state);
1066 }
1067 else if (!priv->state.imap_browse)
1068 {
1069 // examine_directory() calls browser_add_folder() which needs the menu
1070 if (examine_directory(m, priv->menu, &priv->state, buf_string(&mod_data->last_dir),
1071 buf_string(priv->prefix)) == -1)
1072 {
1073 goto bail;
1074 }
1075 }
1076
1077 init_menu(&priv->state, priv->menu, m, priv->sbar);
1078
1079 // ---------------------------------------------------------------------------
1080 // Event Loop
1081 int op = OP_NULL;
1082 struct KeyEvent event = { 0, OP_NULL };
1083 do
1084 {
1085 menu_tagging_dispatcher(priv->menu->win, &event);
1086 window_redraw(NULL);
1087
1088 event = km_dokey(mod_data->menu_browser, GETCH_NONE);
1089 op = event.op;
1090 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
1091 if (op < 0)
1092 continue;
1093 if (op == OP_NULL)
1094 {
1095 km_error_key(mod_data->menu_browser);
1096 continue;
1097 }
1099
1100 int rc = browser_function_dispatcher(sdw.dlg, &event);
1101
1102 if (rc == FR_UNKNOWN)
1103 rc = menu_function_dispatcher(menu->win, &event);
1104 if (rc == FR_UNKNOWN)
1105 rc = global_function_dispatcher(menu->win, &event);
1106 } while (!priv->done);
1107 // ---------------------------------------------------------------------------
1108
1109bail:
1110 window_set_focus(old_focus);
1111 simple_dialog_free(&sdw.dlg);
1113}
int imap_browse(const char *path, struct BrowserState *state)
IMAP hook into the folder browser.
Definition browse.c:196
int browser_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Browser function.
Definition functions.c:1442
void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition sort.c:186
@ MUTT_SEL_MAILBOX
Select a mailbox.
Definition lib.h:60
@ MUTT_SEL_MULTI
Multi-selection is enabled.
Definition lib.h:61
@ MUTT_SEL_FOLDER
Select a local directory.
Definition lib.h:62
struct BrowserPrivateData * browser_private_data_new(void)
Create new Browser Data.
@ BROWSER_SORT_ALPHA
Sort by name.
Definition sort.h:31
@ BROWSER_SORT_UNSORTED
Sort into the raw order.
Definition sort.h:37
@ BROWSER_SORT_DESC
Sort by description.
Definition sort.h:34
size_t buf_addstr_n(struct Buffer *buf, const char *s, size_t len)
Add a string to a Buffer, expanding it if necessary.
Definition buffer.c:96
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition buffer.c:491
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition buffer.c:182
size_t buf_strcpy_n(struct Buffer *buf, const char *s, size_t len)
Copy a string into a Buffer.
Definition buffer.c:416
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition buffer.c:601
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition helpers.c:266
#define SORT_MASK
Mask for the sort id.
Definition sort.h:39
@ MUTT_MMDF
'mmdf' Mailbox type
Definition mailbox.h:45
@ MUTT_MH
'MH' Mailbox type
Definition mailbox.h:46
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
@ MUTT_MBOX
'mbox' Mailbox type
Definition mailbox.h:44
@ MUTT_MAILDIR
'Maildir' Mailbox type
Definition mailbox.h:47
int examine_directory(struct Mailbox *m, struct Menu *menu, struct BrowserState *state, const char *dirname, const char *prefix)
Get list of all files/newsgroups with mask.
void init_menu(struct BrowserState *state, struct Menu *menu, struct Mailbox *m, struct MuttWindow *sbar)
Set up a new menu.
static const struct Mapping FolderNewsHelp[]
Help Bar for the NNTP Mailbox browser dialog.
void mutt_browser_select_dir(const char *f)
Remember the last directory selected.
void init_state(struct BrowserState *state)
Initialise a browser state.
static const struct Mapping FolderHelp[]
Help Bar for the File/Dir/Mailbox browser dialog.
int examine_mailboxes(struct Mailbox *m, struct Menu *menu, struct BrowserState *state)
Get list of mailboxes/subscribed newsgroups.
EmailSortType
Methods for sorting Emails.
Definition sort.h:53
bool OptNews
(pseudo) used to change reader mode
Definition globals.c:53
char * CurrentFolder
Currently selected mailbox.
Definition globals.c:38
static int folder_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format a Folder for the Menu - Implements Menu::make_entry() -.
static int select_file_search(struct Menu *menu, regex_t *rx, int line)
Menu search callback for matching files - Implements Menu::search() -.
static int file_tag(struct Menu *menu, int sel, int act)
Tag an entry in the menu - Implements Menu::tag() -.
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox?
Definition imap.c:2681
static int browser_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
static int browser_mailbox_observer(struct NotifyCallback *nc)
Notification that a Mailbox has changed - Implements observer_t -.
static int browser_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
void browser_private_data_free(struct BrowserPrivateData **ptr)
Free Private Browser Data - Implements MuttWindow::wdata_free() -.
@ MODULE_ID_BROWSER
ModuleBrowser, Mailbox Browser
Definition module_api.h:52
const char * mutt_path_getcwd(struct Buffer *cwd)
Get the current working directory.
Definition path.c:476
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
@ WT_DLG_BROWSER
Browser Dialog, dlg_browser()
Definition mutt_window.h:80
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:122
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition mx.c:1323
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition notify_type.h:50
Browser private Module data.
Definition module_data.h:32
Private state data for the Browser.
char *** files
Array of selected files.
bool folder
Select folders.
int * numfiles
Number of selected files.
struct Mailbox * mailbox
Mailbox.
struct BrowserState state
State containing list of files/dir/mailboxes.
struct Buffer * file
Buffer for the result.
bool multiple
Allow multiple selections.
bool is_mailbox_list
Viewing mailboxes.
Definition lib.h:152
Mapping between user-readable string and a constant.
Definition mapping.h:33
int(* search)(struct Menu *menu, regex_t *rx, int line)
Definition lib.h:127
struct Notify * notify
Notifications handler.
Definition neomutt.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_compose()

int dlg_compose ( struct Email * e,
struct Buffer * fcc,
uint8_t flags,
struct ConfigSubset * sub )

Allow the user to edit the message envelope -.

Parameters
eEmail to fill
fccBuffer to save FCC
flagsFlags, e.g. MUTT_COMPOSE_NOFREEHEADER
subConfigSubset
Return values
1Message should be postponed
0Normal exit
-1Abort message

The Compose Dialog allows the user to edit the email envelope before sending.

Definition at line 412 of file dlg_compose.c.

413{
415 ASSERT(mod_data);
416
417 struct MuttWindow *dlg = compose_dlg_init(sub, e, fcc);
418 struct ComposeSharedData *shared = dlg->wdata;
419 shared->mailbox = get_current_mailbox();
420 shared->email = e;
421 shared->sub = sub;
422 shared->fcc = fcc;
423 shared->fcc_set = false;
424 shared->flags = flags;
425 shared->rc = -1;
426
430
431 if (OptNewsSend)
433 else
434 dlg->help_data = ComposeHelp;
435 dlg->help_md = mod_data->md_compose;
436
437 struct Menu *menu = shared->adata->menu;
438 update_menu(shared->adata->actx, menu, true);
440
441 struct MuttWindow *win_env = window_find_child(dlg, WT_CUSTOM);
442
443 dialog_push(dlg);
444 struct MuttWindow *old_focus = window_set_focus(menu->win);
445 // ---------------------------------------------------------------------------
446 // Event Loop
447 int rc = 0;
448 int op = OP_NULL;
449 struct KeyEvent event = { 0, OP_NULL };
450 do
451 {
452 OptNews = false; /* for any case */
453 menu_tagging_dispatcher(menu->win, &event);
454 window_redraw(NULL);
455
456 event = km_dokey(mod_data->md_compose, GETCH_NONE);
457 op = event.op;
458 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
459 if (op < 0)
460 continue;
461 if (op == OP_NULL)
462 {
463 km_error_key(mod_data->md_compose);
464 continue;
465 }
467
468 rc = compose_function_dispatcher(dlg, &event);
469 if (rc == FR_UNKNOWN)
470 rc = env_function_dispatcher(win_env, &event);
471 if (rc == FR_UNKNOWN)
472 rc = preview_function_dispatcher(shared->win_preview, &event);
473 if (rc == FR_UNKNOWN)
474 rc = menu_function_dispatcher(menu->win, &event);
475 if (rc == FR_UNKNOWN)
476 rc = global_function_dispatcher(menu->win, &event);
477 } while (rc != FR_DONE);
478 // ---------------------------------------------------------------------------
479
480#ifdef USE_AUTOCRYPT
481 /* This is a fail-safe to make sure the bit isn't somehow turned
482 * on. The user could have disabled the option after setting SEC_AUTOCRYPT,
483 * or perhaps resuming or replying to an autocrypt message. */
484 const bool c_autocrypt = cs_subset_bool(sub, "autocrypt");
485 if (!c_autocrypt)
487#endif
488
489 if (shared->adata->actx->idxlen)
490 e->body = shared->adata->actx->idx[0]->body;
491 else
492 e->body = NULL;
493
494 rc = shared->rc;
495
496 window_set_focus(old_focus);
497 dialog_pop();
498 mutt_window_free(&dlg);
499
500 return rc;
501}
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition dialog.c:109
void dialog_pop(void)
Hide a Window from the user.
Definition dialog.c:148
void update_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Redraw the compose window.
static const struct Mapping ComposeHelp[]
Help Bar for the Compose dialog.
Definition dlg_compose.c:94
static const struct Mapping ComposeNewsHelp[]
Help Bar for the News Compose dialog.
static struct MuttWindow * compose_dlg_init(struct ConfigSubset *sub, struct Email *e, struct Buffer *fcc)
Allocate the Windows for Compose.
@ NT_EMAIL_CHANGE
Email has changed.
Definition email.h:186
bool OptNewsSend
(pseudo) used to change behavior when posting
Definition globals.c:54
int compose_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Compose function - Implements function_dispatcher_t -.
Definition functions.c:2713
int preview_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a preview function - Implements function_dispatcher_t -.
Definition preview.c:439
int env_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform an Envelope function - Implements function_dispatcher_t -.
Definition functions.c:536
static int compose_email_observer(struct NotifyCallback *nc)
Notification that an Email has changed - Implements observer_t -.
static int compose_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
static int compose_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition index.c:726
@ MODULE_ID_COMPOSE
ModuleCompose, Compose an Email
Definition module_api.h:57
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition notify.c:173
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
@ WT_CUSTOM
Window with a custom drawing function.
Definition mutt_window.h:95
@ SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition lib.h:101
@ NT_EMAIL
Email has changed, NotifyEmail, EventEmail.
Definition notify_type.h:44
@ NT_ENVELOPE
Envelope has changed, NotifyEnvelope.
Definition notify_type.h:45
struct AttachPtr ** idx
Array of attachments.
Definition attach.h:69
short idxlen
Number of attachmentes.
Definition attach.h:70
struct Body * body
Attachment.
Definition attach.h:37
struct Menu * menu
Menu displaying the attachments.
Definition attach_data.h:35
struct AttachCtx * actx
Set of attachments.
Definition attach_data.h:34
Compose private Module data.
Definition module_data.h:30
struct MenuDefinition * md_compose
Compose Menu Definition.
Definition module_data.h:32
Shared Compose Data.
Definition shared_data.h:35
struct ConfigSubset * sub
Config set to use.
Definition shared_data.h:36
struct Mailbox * mailbox
Current Mailbox.
Definition shared_data.h:37
int flags
Flags, e.g. MUTT_COMPOSE_NOFREEHEADER.
Definition shared_data.h:45
struct MuttWindow * win_preview
Message preview window.
Definition shared_data.h:41
bool fcc_set
User has edited the Fcc: field.
Definition shared_data.h:46
int rc
Return code to leave compose.
Definition shared_data.h:47
struct ComposeAttachData * adata
Attachments.
Definition shared_data.h:39
struct Email * email
Email being composed.
Definition shared_data.h:38
struct Buffer * fcc
Buffer to save FCC.
Definition shared_data.h:44
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition email.h:43
struct Body * body
List of MIME parts.
Definition email.h:69
struct Notify * notify
Notifications: NotifyEmail, EventEmail.
Definition email.h:73
const struct Mapping * help_data
Data for the Help Bar.
const struct MenuDefinition * help_md
Menu Definition for key bindings.
void * wdata
Private data.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_certificate()

int dlg_certificate ( const char * title,
struct StringArray * carr,
bool allow_always,
bool allow_skip )

Ask the user to validate the certificate -.

Parameters
titleMenu title
carrCertificate text to display
allow_alwaysIf true, allow the user to always accept the certificate
allow_skipIf true, allow the user to skip the verification
Return values
1Reject certificate (or menu aborted)
2Accept certificate once
3Accept certificate always/skip (see notes)
4Accept certificate skip

The Verify Certificate Dialog shows a list of signatures for a domain certificate. They can choose whether to accept or reject it.

The possible retvals will depend on the parameters. The options are given in the order: Reject, Once, Always, Skip. The retval represents the chosen option.

Definition at line 166 of file dlg_verifycert.c.

167{
169
170 struct CertMenuData mdata = { carr };
171
172 struct Menu *menu = sdw.menu;
173 menu->mdata = &mdata;
174 menu->mdata_free = NULL; // Menu doesn't own the data
176 menu->max = ARRAY_SIZE(carr);
177 menu->show_indicator = false;
178
179 sbar_set_title(sdw.sbar, title);
180
181 if (allow_always)
182 {
183 if (allow_skip)
184 {
185 mdata.prompt = _("(r)eject, accept (o)nce, (a)ccept always, (s)kip");
186 /* L10N: The letters correspond to the choices in the string:
187 "(r)eject, accept (o)nce, (a)ccept always, (s)kip"
188 This is an interactive certificate confirmation prompt for an SSL connection. */
189 mdata.keys = _("roas");
190 }
191 else
192 {
193 mdata.prompt = _("(r)eject, accept (o)nce, (a)ccept always");
194 /* L10N: The letters correspond to the choices in the string:
195 "(r)eject, accept (o)nce, (a)ccept always"
196 This is an interactive certificate confirmation prompt for an SSL connection. */
197 mdata.keys = _("roa");
198 }
199 }
200 else
201 {
202 if (allow_skip)
203 {
204 mdata.prompt = _("(r)eject, accept (o)nce, (s)kip");
205 /* L10N: The letters correspond to the choices in the string:
206 "(r)eject, accept (o)nce, (s)kip"
207 This is an interactive certificate confirmation prompt for an SSL connection. */
208 mdata.keys = _("ros");
209 }
210 else
211 {
212 mdata.prompt = _("(r)eject, accept (o)nce");
213 /* L10N: The letters correspond to the choices in the string:
214 "(r)eject, accept (o)nce"
215 This is an interactive certificate confirmation prompt for an SSL connection. */
216 mdata.keys = _("ro");
217 }
218 }
220
221 struct MuttWindow *old_focus = window_set_focus(menu->win);
222 // ---------------------------------------------------------------------------
223 // Event Loop
224 int choice = 0;
225 int op = OP_NULL;
226 struct KeyEvent event = { 0, OP_NULL };
227 do
228 {
229 window_redraw(NULL);
231
232 // Try to catch dialog keys before ops
233 if (menu_dialog_dokey(menu, &op) != 0)
234 {
236 op = event.op;
237 }
238
239 if (op == OP_TIMEOUT)
240 continue;
241
242 // Convert menubar movement to scrolling
244
245 if (op <= OP_MAX)
246 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
247 else
248 mutt_debug(LL_DEBUG1, "Got choice %d\n", op - OP_MAX);
249
250 switch (op)
251 {
252 case OP_ABORT: // Abort: Ctrl-G
253 case OP_QUIT: // Q)uit
254 case OP_MAX + 1: // R)eject
255 choice = 1;
256 break;
257 case OP_MAX + 2: // O)nce
258 choice = 2;
259 break;
260 case OP_MAX + 3: // A)lways / S)kip
261 choice = 3;
262 break;
263 case OP_MAX + 4: // S)kip
264 choice = 4;
265 break;
266
267 case OP_JUMP:
268 mutt_error(_("Jumping is not implemented for dialogs"));
269 continue;
270
271 case OP_SEARCH:
272 case OP_SEARCH_NEXT:
273 case OP_SEARCH_OPPOSITE:
274 case OP_SEARCH_REVERSE:
275 mutt_error(_("Search is not implemented for this menu"));
276 continue;
277 }
278
279 (void) menu_function_dispatcher(menu->win, &event);
280 } while (choice == 0);
281 // ---------------------------------------------------------------------------
282
283 window_set_focus(old_focus);
285
286 return choice;
287}
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
@ MT_COLOR_PROMPT
Question/user input.
Definition color.h:56
static int menu_dialog_dokey(struct Menu *menu, int *id)
Check if there are any menu key events to process.
static int menu_dialog_translate_op(int op)
Convert menubar movement to scrolling.
static const struct Mapping VerifyHelp[]
Help Bar for the Certificate Verification dialog.
@ GETCH_IGNORE_MACRO
Don't use MacroEvents.
Definition get.h:39
#define mutt_error(...)
Definition logging2.h:94
static int cert_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Create a Certificate for the Menu - Implements Menu::make_entry() -.
#define MdGeneric
Definition functions.h:33
#define MdDialog
Definition functions.h:34
void msgwin_set_text(struct MuttWindow *win, const char *text, enum ColorId color)
Set the text for the Message Window.
Definition msgwin.c:500
@ WT_DLG_CERTIFICATE
Certificate Dialog, dlg_certificate()
Definition mutt_window.h:81
#define OP_TIMEOUT
1 second with no events
Definition opcodes.h:35
#define OP_ABORT
$abort_key pressed (Ctrl-G)
Definition opcodes.h:36
@ OP_MAX
Definition opcodes.h:1033
Certificate data to use in the Menu.
Definition ssl.h:37
char * prompt
Prompt for user, similar to mw_multi_choice.
Definition ssl.h:39
struct StringArray * carr
Lines of the Certificate.
Definition ssl.h:38
bool show_indicator
Show the Indicator colour.
Definition lib.h:93
int max
Number of entries in the menu.
Definition lib.h:88
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_history()

void dlg_history ( struct Buffer * buf,
struct StringArray * matches )

Select an item from a history list -.

Parameters
[in]bufBuffer in which to save string
[out]matchesItems to choose from

The History Dialog lets the user select from the history of commands, functions or files.

Definition at line 119 of file dlg_history.c.

120{
122 struct Menu *menu = sdw.menu;
123
124 struct HistoryData hd = { false, false, buf, menu, matches };
125
126 char title[256] = { 0 };
127 snprintf(title, sizeof(title), _("History '%s'"), buf_string(buf));
128 sbar_set_title(sdw.sbar, title);
129
132 menu->mdata = &hd;
133 menu->mdata_free = NULL; // Menu doesn't own the data
134
135 struct MuttWindow *old_focus = window_set_focus(menu->win);
136 // ---------------------------------------------------------------------------
137 // Event Loop
138 int op = OP_NULL;
139 struct KeyEvent event = { 0, OP_NULL };
140 do
141 {
142 menu_tagging_dispatcher(menu->win, &event);
143 window_redraw(NULL);
144
145 event = km_dokey(MdDialog, GETCH_NONE);
146 op = event.op;
147 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
148 if (op < 0)
149 continue;
150 if (op == OP_NULL)
151 {
153 continue;
154 }
156
157 int rc = history_function_dispatcher(sdw.dlg, &event);
158 if (rc == FR_UNKNOWN)
159 rc = menu_function_dispatcher(menu->win, &event);
160 if (rc == FR_UNKNOWN)
161 rc = global_function_dispatcher(menu->win, &event);
162 } while (!hd.done);
163 // ---------------------------------------------------------------------------
164
165 window_set_focus(old_focus);
167}
static const struct Mapping HistoryHelp[]
Help Bar for the History Selection dialog.
Definition dlg_history.c:75
int history_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a History function - Implements function_dispatcher_t -.
Definition functions.c:85
static int history_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format a History Item for the Menu - Implements Menu::make_entry() -.
Definition dlg_history.c:88
@ WT_DLG_HISTORY
History Dialog, dlg_history()
Definition mutt_window.h:85
Data to pass to the History Functions.
Definition functions.h:35
struct Menu * menu
History Menu.
Definition functions.h:39
struct Buffer * buf
Buffer for the results.
Definition functions.h:38
struct StringArray * matches
History entries.
Definition functions.h:40
bool done
Should we close the Dialog?
Definition functions.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_index()

struct Mailbox * dlg_index ( struct MuttWindow * dlg,
struct Mailbox * m_init )

Display a list of emails -.

Parameters
dlgDialog containing Windows to draw on
m_initInitial mailbox
Return values
ptrMailbox open in the index

The Index Dialog is the heart of NeoMutt. From here, the user can read and reply to emails, organise them into folders, set labels, etc.

Definition at line 1121 of file dlg_index.c.

1122{
1123 /* Make sure use_threads/sort/sort_aux are coherent */
1125
1126 struct IndexSharedData *shared = dlg->wdata;
1128
1129 struct MuttWindow *panel_index = window_find_child(dlg, WT_INDEX);
1130
1131 struct IndexPrivateData *priv = panel_index->wdata;
1132 priv->win_index = window_find_child(panel_index, WT_MENU);
1133
1134 int op = OP_NULL;
1135
1137 ASSERT(mod_data);
1138
1139 if (shared->mailbox && (shared->mailbox->type == MUTT_NNTP))
1140 dlg->help_data = IndexNewsHelp;
1141 else
1142 dlg->help_data = IndexHelp;
1143 dlg->help_md = mod_data->menu_index;
1144
1145 priv->menu = priv->win_index->wdata;
1147 priv->menu->color = index_color;
1148 priv->menu->max = shared->mailbox ? shared->mailbox->vcount : 0;
1150
1151 struct MuttWindow *old_focus = window_set_focus(priv->menu->win);
1152 mutt_window_reflow(NULL);
1153
1154 if (!shared->attach_msg)
1155 {
1156 /* force the mailbox check after we enter the folder */
1158 }
1159#ifdef USE_INOTIFY
1160 mutt_monitor_add(NULL);
1161#endif
1162
1163 const bool c_collapse_all = cs_subset_bool(shared->sub, "collapse_all");
1164 if (mutt_using_threads() && c_collapse_all)
1165 {
1168 }
1169
1170 int rc = 0;
1171 do
1172 {
1173 /* Clear the tag prefix unless we just started it.
1174 * Don't clear the prefix on a timeout, but do clear on an abort */
1175 if (priv->tag_prefix && (op != OP_TAG_PREFIX) &&
1176 (op != OP_TAG_PREFIX_COND) && (op != OP_TIMEOUT))
1177 {
1178 priv->tag_prefix = false;
1179 }
1180
1181 /* check if we need to resort the index because just about
1182 * any 'op' below could do mutt_enter_command(), either here or
1183 * from any new priv->menu launched, and change $sort/$sort_aux */
1184 if (OptNeedResort && shared->mailbox && (shared->mailbox->msg_count != 0) &&
1185 (menu_get_index(priv->menu) >= 0))
1186 {
1187 resort_index(shared->mailbox_view, priv->menu);
1188 }
1189
1190 priv->menu->max = shared->mailbox ? shared->mailbox->vcount : 0;
1191 priv->oldcount = shared->mailbox ? shared->mailbox->msg_count : 0;
1192
1193 if (shared->mailbox && shared->mailbox_view)
1194 {
1196
1197 shared->mailbox_view->menu = priv->menu;
1198 /* check for new mail in the mailbox. If nonzero, then something has
1199 * changed about the file (either we got new mail or the file was
1200 * modified underneath us.) */
1201 enum MxStatus check = mx_mbox_check(shared->mailbox);
1202
1203 if (check == MX_STATUS_ERROR)
1204 {
1205 if (buf_is_empty(&shared->mailbox->pathbuf))
1206 {
1207 /* fatal error occurred */
1208 mview_free(&shared->mailbox_view);
1210 }
1211
1213 }
1214 else if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED) ||
1215 (check == MX_STATUS_FLAGS))
1216 {
1217 /* notify the user of new mail */
1218 if (check == MX_STATUS_REOPENED)
1219 {
1220 mutt_error(_("Mailbox was externally modified. Flags may be wrong."));
1221 }
1222 else if (check == MX_STATUS_NEW_MAIL)
1223 {
1224 for (size_t i = 0; i < shared->mailbox->msg_count; i++)
1225 {
1226 const struct Email *e = shared->mailbox->emails[i];
1227 if (e && !e->read && !e->old)
1228 {
1229 mutt_message(_("New mail in this mailbox"));
1230 const bool c_beep_new = cs_subset_bool(shared->sub, "beep_new");
1231 if (c_beep_new)
1232 mutt_beep(true);
1233 const struct Expando *c_new_mail_command =
1234 cs_subset_expando(shared->sub, "new_mail_command");
1235 if (c_new_mail_command)
1236 {
1237 struct Buffer *cmd = buf_pool_get();
1238 menu_status_line(cmd, shared, NULL, -1, c_new_mail_command);
1239 if (mutt_system(buf_string(cmd)) != 0)
1240 mutt_error(_("Error running \"%s\""), buf_string(cmd));
1241 buf_pool_release(&cmd);
1242 }
1243 break;
1244 }
1245 }
1246 }
1247 else if (check == MX_STATUS_FLAGS)
1248 {
1249 mutt_message(_("Mailbox was externally modified"));
1250 }
1251
1252 /* avoid the message being overwritten by mailbox */
1253 priv->do_mailbox_notify = false;
1254
1255 bool verbose = shared->mailbox->verbose;
1256 shared->mailbox->verbose = false;
1257 update_index(priv->menu, shared->mailbox_view, check, priv->oldcount, shared);
1258 shared->mailbox->verbose = verbose;
1259 priv->menu->max = shared->mailbox->vcount;
1262 }
1263
1265 menu_get_index(priv->menu)));
1266 }
1267
1268 if (!shared->attach_msg)
1269 {
1270 /* check for new mail in the incoming folders */
1272 if (priv->do_mailbox_notify)
1273 {
1274 if (mutt_mailbox_notify(shared->mailbox))
1275 {
1276 const bool c_beep_new = cs_subset_bool(shared->sub, "beep_new");
1277 if (c_beep_new)
1278 mutt_beep(true);
1279 const struct Expando *c_new_mail_command = cs_subset_expando(shared->sub, "new_mail_command");
1280 if (c_new_mail_command)
1281 {
1282 struct Buffer *cmd = buf_pool_get();
1283 menu_status_line(cmd, shared, priv->menu, -1, c_new_mail_command);
1284 if (mutt_system(buf_string(cmd)) != 0)
1285 mutt_error(_("Error running \"%s\""), buf_string(cmd));
1286 buf_pool_release(&cmd);
1287 }
1288 }
1289 }
1290 else
1291 {
1292 priv->do_mailbox_notify = true;
1293 }
1294 }
1295
1296 window_redraw(NULL);
1297
1298 /* give visual indication that the next command is a tag- command */
1299 if (priv->tag_prefix)
1300 {
1301 msgwin_set_text(NULL, "tag-", MT_COLOR_NORMAL);
1302 }
1303
1304 const bool c_arrow_cursor = cs_subset_bool(shared->sub, "arrow_cursor");
1305 const bool c_braille_friendly = cs_subset_bool(shared->sub, "braille_friendly");
1306 const int index = menu_get_index(priv->menu);
1307 if (c_arrow_cursor)
1308 {
1309 const char *const c_arrow_string = cs_subset_string(shared->sub, "arrow_string");
1310 const int arrow_width = mutt_strwidth(c_arrow_string);
1311 mutt_window_move(priv->menu->win, index - priv->menu->top, arrow_width);
1312 }
1313 else if (c_braille_friendly)
1314 {
1315 mutt_window_move(priv->menu->win, index - priv->menu->top, 0);
1316 }
1317 else
1318 {
1319 mutt_window_move(priv->menu->win, index - priv->menu->top,
1320 priv->menu->win->state.cols - 1);
1321 }
1322 mutt_refresh();
1323
1324 window_redraw(NULL);
1325 struct KeyEvent event = km_dokey(mod_data->menu_index, GETCH_NONE);
1326 op = event.op;
1327
1328 if (op == OP_REPAINT)
1329 {
1330 /* force a real complete redraw. clrtobot() doesn't seem to be able
1331 * to handle every case without this. */
1332 msgwin_clear_text(NULL);
1333 mutt_refresh();
1334 continue;
1335 }
1336
1337 /* either user abort or timeout */
1338 if (op < OP_NULL)
1339 {
1340 if (priv->tag_prefix)
1341 msgwin_clear_text(NULL);
1342 continue;
1343 }
1344
1345 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
1346
1347 /* special handling for the priv->tag-prefix function */
1348 const bool c_auto_tag = cs_subset_bool(shared->sub, "auto_tag");
1349 if ((op == OP_TAG_PREFIX) || (op == OP_TAG_PREFIX_COND))
1350 {
1351 /* A second priv->tag-prefix command aborts */
1352 if (priv->tag_prefix)
1353 {
1354 priv->tag_prefix = false;
1355 msgwin_clear_text(NULL);
1356 continue;
1357 }
1358
1359 if (!shared->mailbox)
1360 {
1361 mutt_error(_("No mailbox is open"));
1362 continue;
1363 }
1364
1365 if (shared->mailbox->msg_tagged == 0)
1366 {
1367 if (op == OP_TAG_PREFIX)
1368 {
1369 mutt_error(_("No tagged messages"));
1370 }
1371 else if (op == OP_TAG_PREFIX_COND)
1372 {
1374 mutt_message(_("Nothing to do"));
1375 }
1376 continue;
1377 }
1378
1379 /* get the real command */
1380 priv->tag_prefix = true;
1381 continue;
1382 }
1383 else if (c_auto_tag && shared->mailbox && (shared->mailbox->msg_tagged != 0))
1384 {
1385 priv->tag_prefix = true;
1386 }
1387
1389
1390 OptNews = false; /* for any case */
1391
1392#ifdef USE_NOTMUCH
1393 nm_db_debug_check(shared->mailbox);
1394#endif
1395
1396 rc = index_function_dispatcher(priv->win_index, &event);
1397
1398 if (rc == FR_UNKNOWN)
1399 rc = menu_function_dispatcher(priv->win_index, &event);
1400
1401 if (rc == FR_UNKNOWN)
1402 {
1403 struct MuttWindow *win_sidebar = window_find_child(dlg, WT_SIDEBAR);
1404 rc = sb_function_dispatcher(win_sidebar, &event);
1405 }
1406 if (rc == FR_UNKNOWN)
1407 rc = global_function_dispatcher(priv->menu->win, &event);
1408
1409 if (rc == FR_UNKNOWN)
1410 km_error_key(mod_data->menu_index);
1411
1412#ifdef USE_NOTMUCH
1413 nm_db_debug_check(shared->mailbox);
1414#endif
1415 } while (rc != FR_DONE);
1416
1417 mview_free(&shared->mailbox_view);
1418 window_set_focus(old_focus);
1419
1420 return shared->mailbox;
1421}
@ MT_COLOR_NORMAL
Plain text.
Definition color.h:53
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition compile.c:836
const struct Expando * cs_subset_expando(const struct ConfigSubset *sub, const char *name)
Get an Expando config item by name.
void mailbox_gc_run(void)
Run the garbage-collection.
Definition mailbox.c:311
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition mailbox.h:48
void mutt_refresh(void)
Force a refresh of the screen.
Definition curs_lib.c:79
void mutt_beep(bool force)
Irritate the user.
Definition curs_lib.c:69
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition curs_lib.c:446
const struct Mapping IndexNewsHelp[]
Help Bar for the News Index dialog.
Definition dlg_index.c:116
void update_index(struct Menu *menu, struct MailboxView *mv, enum MxStatus check, int oldcount, const struct IndexSharedData *shared)
Update the index.
Definition dlg_index.c:562
int find_first_message(struct MailboxView *mv)
Get index of first new message.
Definition dlg_index.c:327
static const struct Mapping IndexHelp[]
Help Bar for the Index dialog.
Definition dlg_index.c:101
void resort_index(struct MailboxView *mv, struct Menu *menu)
Resort the index.
Definition dlg_index.c:387
void collapse_all(struct MailboxView *mv, struct Menu *menu, enum CollapseMode mode)
Collapse/uncollapse all threads.
Definition dlg_index.c:161
bool OptNeedResort
(pseudo) used to force a re-sort
Definition globals.c:52
void mutt_flush_macro_to_endcond(void)
Drop a macro from the input buffer.
Definition get.c:185
int sb_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Sidebar function - Implements function_dispatcher_t -.
Definition functions.c:714
int index_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform an Index function - Implements function_dispatcher_t -.
Definition functions.c:4067
#define mutt_message(...)
Definition logging2.h:93
const struct AttrColor * index_color(struct Menu *menu, int line)
Calculate the colour for a line of the index - Implements Menu::color() -.
Definition dlg_index.c:948
int index_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format an Email for the Menu - Implements Menu::make_entry() -.
Definition dlg_index.c:847
#define mutt_using_threads()
Definition thread.h:119
@ COLLAPSE_MODE_CLOSE
Collapse all threads.
Definition lib.h:105
void index_shared_data_set_email(struct IndexSharedData *shared, struct Email *e)
Set the current Email for the Index and friends.
void index_shared_data_set_mview(struct IndexSharedData *shared, struct MailboxView *mv)
Set the MailboxView for the Index and friends.
void index_adjust_sort_threads(const struct ConfigSubset *sub)
Adjust use_threads/sort/sort_aux.
Definition index.c:185
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition menu.c:179
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition menu.c:155
@ MENU_REDRAW_FULL
Redraw everything.
Definition lib.h:64
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition menu.c:169
@ MODULE_ID_INDEX
ModuleIndex, Index
Definition module_api.h:72
int mutt_monitor_add(struct Mailbox *m)
Add a watch for a mailbox.
Definition monitor.c:484
void msgwin_clear_text(struct MuttWindow *win)
Clear the text in the Message Window.
Definition msgwin.c:554
int mutt_system(const char *cmd)
Run an external command.
Definition system.c:51
int mutt_mailbox_check(struct Mailbox *m_cur, CheckStatsFlags flags)
Check all all Mailboxes for new mail.
bool mutt_mailbox_notify(struct Mailbox *m_cur)
Notify the user if there's new mail.
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
@ WT_INDEX
A panel containing the Index Window.
Definition mutt_window.h:97
@ WT_SIDEBAR
Side panel containing Accounts or groups of data.
@ WT_MENU
An Window containing a Menu.
Definition mutt_window.h:98
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition mview.c:376
void mview_free(struct MailboxView **ptr)
Free a MailboxView.
Definition mview.c:47
struct MailboxView * mview_new(struct Mailbox *m, struct Notify *parent)
Create a new MailboxView.
Definition mview.c:88
enum MxStatus mx_mbox_check(struct Mailbox *m)
Check for new mail - Wrapper for MxOps::mbox_check()
Definition mx.c:1107
@ MUTT_MAILBOX_CHECK_POSTPONED
Make sure the number of postponed messages is updated.
Definition mxapi.h:59
@ MUTT_MAILBOX_CHECK_NONE
No flags are set.
Definition mxapi.h:58
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_sync(), and mbox_close()
Definition mxapi.h:70
@ MX_STATUS_ERROR
An error occurred.
Definition mxapi.h:71
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
Definition mxapi.h:76
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition mxapi.h:75
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition mxapi.h:73
void nm_db_debug_check(struct Mailbox *m)
Check if the database is open.
Definition db.c:411
#define OP_REPAINT
Repaint is needed.
Definition opcodes.h:34
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
void menu_status_line(struct Buffer *buf, struct IndexSharedData *shared, struct Menu *menu, int max_cols, const struct Expando *exp)
Create the status line.
Definition status.c:51
String manipulation buffer.
Definition buffer.h:36
The envelope/body of an email.
Definition email.h:39
bool read
Email is read.
Definition email.h:50
bool old
Email is seen, but unread.
Definition email.h:49
Parsed Expando trees.
Definition expando.h:41
Index private Module data.
Definition module_data.h:32
struct MenuDefinition * menu_index
Index menu definition.
Definition module_data.h:34
Private state data for the Index.
struct MuttWindow * win_index
Window for the Index.
bool tag_prefix
tag-prefix has been pressed
bool do_mailbox_notify
Do we need to notify the user of new mail?
struct Menu * menu
Menu controlling the index.
int oldcount
Old count of mails in the mailbox.
Data shared between Index, Pager and Sidebar.
Definition shared_data.h:37
struct Mailbox * mailbox
Current Mailbox.
Definition shared_data.h:41
bool attach_msg
Are we in "attach message" mode?
Definition shared_data.h:46
struct ConfigSubset * sub
Config set to use.
Definition shared_data.h:38
struct MailboxView * mailbox_view
Current Mailbox view.
Definition shared_data.h:40
struct SearchState * search_state
State of the current search.
Definition shared_data.h:45
struct Menu * menu
Needed for pattern compilation.
Definition mview.h:47
int vcount
The number of virtual messages.
Definition mailbox.h:101
int msg_count
Total number of messages.
Definition mailbox.h:90
enum MailboxType type
Mailbox type.
Definition mailbox.h:104
struct Email ** emails
Array of Emails.
Definition mailbox.h:98
struct Buffer pathbuf
Path of the Mailbox.
Definition mailbox.h:82
int msg_tagged
How many messages are tagged?
Definition mailbox.h:96
bool verbose
Display status messages?
Definition mailbox.h:119
const struct AttrColor *(* color)(struct Menu *menu, int line)
Definition lib.h:151
int top
Entry that is the top of the current page.
Definition lib.h:98
struct WindowState state
Current state of the Window.
struct PatternList * pattern
compiled search pattern
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition mutt_window.h:60
+ Here is the caller graph for this function:

◆ dlg_list()

void dlg_list ( struct Mailbox * m,
struct Email * e )

Display mailing-list actions for an email -.

Parameters
mMailbox containing the email
eEmail to inspect

Definition at line 293 of file dlg_list.c.

294{
295 if (!m || !e)
296 return;
297
299 ASSERT(mod_data);
300
301 struct ListData *ld = MUTT_MEM_CALLOC(1, struct ListData);
302 ld->mailbox = m;
303
304 struct Message *msg = mx_msg_open(m, e);
305 if (!msg)
306 {
307 FREE(&ld);
308 return;
309 }
310
311 if (!mutt_file_seek(msg->fp, e->offset, SEEK_SET))
312 {
313 mutt_error(_("Unable to read mailing list headers"));
314 mx_msg_close(m, &msg);
315 FREE(&ld);
316 return;
317 }
318
320 mx_msg_close(m, &msg);
321
322 for (size_t i = 0; i < countof(ListActions); i++)
324
325 struct SimpleDialogWindows sdw = simple_dialog_new(mod_data->menu_list,
327 struct Menu *menu = sdw.menu;
328 ld->menu = menu;
329 menu->max = countof(ListActions);
331 menu->mdata = ld;
333
334 sbar_set_title(sdw.sbar, _("Available mailing list actions"));
335
336 struct MuttWindow *old_focus = window_set_focus(menu->win);
337 // ---------------------------------------------------------------------------
338 // Event Loop
339 int op = OP_NULL;
340 struct KeyEvent event = { 0, OP_NULL };
341 do
342 {
343 menu_tagging_dispatcher(menu->win, &event);
344 window_redraw(NULL);
345
346 event = km_dokey(mod_data->menu_list, GETCH_NONE);
347 op = event.op;
348 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
349 if (op < 0)
350 continue;
351 if (op == OP_NULL)
352 {
353 km_error_key(mod_data->menu_list);
354 continue;
355 }
357
358 int rc = list_function_dispatcher(sdw.dlg, &event);
359 if (rc == FR_UNKNOWN)
360 rc = menu_function_dispatcher(menu->win, &event);
361 if (rc == FR_UNKNOWN)
362 rc = global_function_dispatcher(menu->win, &event);
363 } while (!ld->done);
364 // ---------------------------------------------------------------------------
365
366 window_set_focus(old_focus);
368}
static const struct Mapping ListHelp[]
Help Bar for the Mailing-list action dialog.
Definition dlg_list.c:39
static const struct ListAction ListActions[]
Mailing-list actions shown in the dialog.
Definition dlg_list.c:63
void mutt_rfc2369_read_headers(FILE *fp, struct Rfc2369ListHeaders *headers)
Read RFC 2369 mailing-list headers.
Definition parse.c:657
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:648
static int list_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a List dialog function - Implements function_dispatcher_t -.
Definition dlg_list.c:252
static int list_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format a mailing-list action for the dialog - Implements Menu::make_entry() -.
Definition dlg_list.c:114
static void list_data_free(struct Menu *menu, void **ptr)
Free list dialog data - Implements Menu::mdata_free() -.
Definition dlg_list.c:101
#define countof(x)
Definition memory.h:49
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
#define MAX(a, b)
Return the maximum of two values.
Definition memory.h:38
@ WT_DLG_LIST
List Dialog, dlg_list()
Definition mutt_window.h:87
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition mx.c:1182
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition mx.c:1136
LOFF_T offset
Where in the stream does this message begin?
Definition email.h:71
struct MenuDefinition * menu_list
Mailing-list action menu definition.
Definition module_data.h:35
Private data for the Mailing-list action dialog.
Definition dlg_list.c:78
int label_width
Width of the longest action label.
Definition dlg_list.c:82
struct Menu * menu
Dialog menu.
Definition dlg_list.c:79
struct Mailbox * mailbox
Source mailbox.
Definition dlg_list.c:80
struct Rfc2369ListHeaders headers
Parsed List-* headers.
Definition dlg_list.c:81
bool done
Exit the dialog.
Definition dlg_list.c:83
A local copy of an email.
Definition message.h:34
FILE * fp
pointer to the message data
Definition message.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_gpgme()

struct CryptKeyInfo * dlg_gpgme ( struct CryptKeyInfo * keys,
struct Address * p,
const char * s,
unsigned int app,
bool * forced_valid )

Get the user to select a key -.

Parameters
[in]keysList of keys to select from
[in]pAddress to match
[in]sReal name to display
[in]appFlags, e.g. APPLICATION_PGP
[out]forced_validSet to true if user overrode key's validity
Return values
ptrKey selected by user

The Select GPGME Key Dialog lets the user select a PGP Key to use.

Definition at line 195 of file dlg_gpgme.c.

197{
198 /* build the key table */
199 struct CryptKeyInfoArray ckia = ARRAY_HEAD_INITIALIZER;
200 const bool c_pgp_show_unusable = cs_subset_bool(NeoMutt->sub, "pgp_show_unusable");
201 bool unusable = false;
202 for (struct CryptKeyInfo *k = keys; k; k = k->next)
203 {
204 if (!c_pgp_show_unusable && (k->flags & KEYFLAG_CANTUSE))
205 {
206 unusable = true;
207 continue;
208 }
209
210 ARRAY_ADD(&ckia, k);
211 }
212
213 if ((ARRAY_SIZE(&ckia) == 0) && unusable)
214 {
215 mutt_error(_("All matching keys are marked expired/revoked"));
216 return NULL;
217 }
218
219 gpgme_sort_keys(&ckia);
220
222 ASSERT(mod_data);
223
224 struct MenuDefinition *md = NULL;
225 if (app & APPLICATION_PGP)
226 md = mod_data->menu_pgp;
227 else if (app & APPLICATION_SMIME)
228 md = mod_data->menu_smime;
229
231
232 struct Menu *menu = sdw.menu;
233 struct GpgmeData gd = { false, menu, &ckia, NULL, forced_valid };
234
235 menu->max = ARRAY_SIZE(&ckia);
237 menu->mdata = &gd;
238 menu->mdata_free = NULL; // Menu doesn't own the data
239
240 // NT_COLOR is handled by the SimpleDialog
243
244 const char *ts = NULL;
245
246 if ((app & APPLICATION_PGP) && (app & APPLICATION_SMIME))
247 ts = _("PGP and S/MIME keys matching");
248 else if ((app & APPLICATION_PGP))
249 ts = _("PGP keys matching");
250 else if ((app & APPLICATION_SMIME))
251 ts = _("S/MIME keys matching");
252 else
253 ts = _("keys matching");
254
255 char buf[1024] = { 0 };
256 if (p)
257 {
258 /* L10N: 1$s is one of the previous four entries.
259 %2$s is an address.
260 e.g. "S/MIME keys matching <john.doe@example.com>" */
261 snprintf(buf, sizeof(buf), _("%s <%s>"), ts, buf_string(p->mailbox));
262 }
263 else
264 {
265 /* L10N: e.g. 'S/MIME keys matching "John Doe".' */
266 snprintf(buf, sizeof(buf), _("%s \"%s\""), ts, s);
267 }
268
269 sbar_set_title(sdw.sbar, buf);
270
272
273 struct MuttWindow *old_focus = window_set_focus(menu->win);
274 // ---------------------------------------------------------------------------
275 // Event Loop
276 int op = OP_NULL;
277 struct KeyEvent event = { 0, OP_NULL };
278 do
279 {
280 menu_tagging_dispatcher(menu->win, &event);
281 window_redraw(NULL);
282
283 event = km_dokey(md, GETCH_NONE);
284 op = event.op;
285 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
286 if (op < 0)
287 continue;
288 if (op == OP_NULL)
289 {
290 km_error_key(md);
291 continue;
292 }
294
295 int rc = gpgme_function_dispatcher(sdw.dlg, &event);
296
297 if (rc == FR_UNKNOWN)
298 rc = menu_function_dispatcher(menu->win, &event);
299 if (rc == FR_UNKNOWN)
300 rc = global_function_dispatcher(menu->win, &event);
301 } while (!gd.done);
302 // ---------------------------------------------------------------------------
303
304 ARRAY_FREE(&ckia);
305 window_set_focus(old_focus);
307 return gd.key;
308}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
static const struct Mapping GpgmeHelp[]
Help Bar for the GPGME key selection dialog.
Definition dlg_gpgme.c:92
int gpgme_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Gpgme function - Implements function_dispatcher_t -.
static int crypt_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format a PGP Key for the Menu - Implements Menu::make_entry() -.
Definition dlg_gpgme.c:107
static int gpgme_key_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition dlg_gpgme.c:132
static int gpgme_key_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition dlg_gpgme.c:161
@ MODULE_ID_NCRYPT
ModuleNcrypt, Ncrypt
Definition module_api.h:80
@ WT_DLG_GPGME
GPGME Dialog, dlg_gpgme()
Definition mutt_window.h:83
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:106
#define KEYFLAG_CANTUSE
Definition lib.h:161
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition lib.h:107
void gpgme_sort_keys(struct CryptKeyInfoArray *ckia)
Sort an array of GPGME keys.
Definition sort_gpgme.c:175
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:37
A stored PGP key.
Definition crypt_gpgme.h:44
struct CryptKeyInfo * next
Linked list.
Definition crypt_gpgme.h:45
Data to pass to the Gpgme Functions.
bool * forced_valid
User insists on out-of-date key.
struct CryptKeyInfo * key
Selected Key.
bool done
Should we close the Dialog?
struct Menu * menu
Gpgme Menu.
Functions for a Dialog or Window.
Definition menu.h:77
Ncrypt private Module data.
Definition module_data.h:38
struct MenuDefinition * menu_smime
S/MIME menu definition.
Definition module_data.h:41
struct MenuDefinition * menu_pgp
PGP menu definition.
Definition module_data.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_pgp()

struct PgpKeyInfo * dlg_pgp ( struct PgpKeyInfo * keys,
struct Address * p,
const char * s )

Let the user select a key to use -.

Parameters
keysList of PGP keys
pAddress to match
sString to match
Return values
ptrSelected PGP key

The Select PGP Key Dialog lets the user select an PGP Key to use.

Definition at line 192 of file dlg_pgp.c.

193{
194 struct Menu *menu = NULL;
195 char buf[1024] = { 0 };
196 bool unusable = false;
197 struct PgpUidArray pua = ARRAY_HEAD_INITIALIZER;
198
199 const bool c_pgp_show_unusable = cs_subset_bool(NeoMutt->sub, "pgp_show_unusable");
200 for (struct PgpKeyInfo *kp = keys; kp; kp = kp->next)
201 {
202 if (!c_pgp_show_unusable && (kp->flags & KEYFLAG_CANTUSE))
203 {
204 unusable = true;
205 continue;
206 }
207
208 for (struct PgpUid *a = kp->address; a; a = a->next)
209 {
210 if (!c_pgp_show_unusable && (a->flags & KEYFLAG_CANTUSE))
211 {
212 unusable = true;
213 continue;
214 }
215
216 ARRAY_ADD(&pua, a);
217 }
218 }
219
220 if ((ARRAY_SIZE(&pua) == 0) && unusable)
221 {
222 mutt_error(_("All matching keys are expired, revoked, or disabled"));
223 return NULL;
224 }
225
226 pgp_sort_keys(&pua);
227
229 ASSERT(mod_data);
230
232 menu = sdw.menu;
233 struct PgpData pd = { false, menu, &pua, NULL };
234
235 menu->max = ARRAY_SIZE(&pua);
237 menu->mdata = &pd;
238 menu->mdata_free = NULL; // Menu doesn't own the data
239
240 // NT_COLOR is handled by the SimpleDialog
243
244 if (p)
245 snprintf(buf, sizeof(buf), _("PGP keys matching <%s>"), buf_string(p->mailbox));
246 else
247 snprintf(buf, sizeof(buf), _("PGP keys matching \"%s\""), s);
248
249 sbar_set_title(sdw.sbar, buf);
250
252
253 struct MuttWindow *old_focus = window_set_focus(menu->win);
254 // ---------------------------------------------------------------------------
255 // Event Loop
256 int op = OP_NULL;
257 struct KeyEvent event = { 0, OP_NULL };
258 do
259 {
260 menu_tagging_dispatcher(menu->win, &event);
261 window_redraw(NULL);
262
263 event = km_dokey(mod_data->menu_pgp, GETCH_NONE);
264 op = event.op;
265 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
266 if (op < 0)
267 continue;
268 if (op == OP_NULL)
269 {
270 km_error_key(mod_data->menu_pgp);
271 continue;
272 }
274
275 int rc = pgp_function_dispatcher(sdw.dlg, &event);
276
277 if (rc == FR_UNKNOWN)
278 rc = menu_function_dispatcher(menu->win, &event);
279 if (rc == FR_UNKNOWN)
280 rc = global_function_dispatcher(menu->win, &event);
281 } while (!pd.done);
282 // ---------------------------------------------------------------------------
283
284 ARRAY_FREE(&pua);
285 window_set_focus(old_focus);
287 return pd.key;
288}
static const struct Mapping PgpHelp[]
Help Bar for the PGP key selection dialog.
Definition dlg_pgp.c:91
int pgp_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Pgp function - Implements function_dispatcher_t -.
static int pgp_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format a PGP Key for the Menu - Implements Menu::make_entry() -.
Definition dlg_pgp.c:106
static int pgp_key_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition dlg_pgp.c:160
static int pgp_key_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition dlg_pgp.c:131
@ WT_DLG_PGP
Pgp Dialog, dlg_pgp()
Definition mutt_window.h:89
void pgp_sort_keys(struct PgpUidArray *pua)
Sort an array of PGP keys.
Definition sort_pgp.c:142
Data to pass to the Pgp Functions.
struct Menu * menu
Pgp Menu.
bool done
Should we close the Dialog?
struct PgpKeyInfo * key
Selected Key.
Information about a PGP key.
Definition pgplib.h:49
struct PgpKeyInfo * next
Linked list.
Definition pgplib.h:59
PGP User ID.
Definition pgplib.h:36
struct PgpUid * next
Linked list.
Definition pgplib.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_smime()

struct SmimeKey * dlg_smime ( struct SmimeKey * keys,
const char * query )

Get the user to select a key -.

Parameters
keysList of keys to select from
queryString to match
Return values
ptrKey selected by user

The Select SMIME Key Dialog lets the user select an SMIME Key to use.

Definition at line 195 of file dlg_smime.c.

196{
197 struct SmimeKeyArray ska = ARRAY_HEAD_INITIALIZER;
198 for (struct SmimeKey *key = keys; key; key = key->next)
199 {
200 ARRAY_ADD(&ska, key);
201 }
202 /* sorting keys might be done later - TODO */
203
205 ASSERT(mod_data);
206
207 struct SimpleDialogWindows sdw = simple_dialog_new(mod_data->menu_smime,
209 struct Menu *menu = sdw.menu;
210
211 struct SmimeData sd = { false, menu, &ska, NULL };
212
213 menu->max = ARRAY_SIZE(&ska);
215 menu->mdata = &sd;
216 menu->mdata_free = NULL; // Menu doesn't own the data
217
218 char title[256] = { 0 };
219 snprintf(title, sizeof(title), _("S/MIME certificates matching \"%s\""), query);
220 sbar_set_title(sdw.sbar, title);
221
223
224 struct MuttWindow *old_focus = window_set_focus(menu->win);
225 // ---------------------------------------------------------------------------
226 // Event Loop
227 int op = OP_NULL;
228 struct KeyEvent event = { 0, OP_NULL };
229 do
230 {
231 menu_tagging_dispatcher(menu->win, &event);
232 window_redraw(NULL);
233
234 event = km_dokey(mod_data->menu_smime, GETCH_NONE);
235 op = event.op;
236 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
237 if (op < 0)
238 continue;
239 if (op == OP_NULL)
240 {
241 km_error_key(mod_data->menu_smime);
242 continue;
243 }
245
246 int rc = smime_function_dispatcher(sdw.dlg, &event);
247
248 if (rc == FR_UNKNOWN)
249 rc = menu_function_dispatcher(menu->win, &event);
250 if (rc == FR_UNKNOWN)
251 rc = global_function_dispatcher(menu->win, &event);
252 } while (!sd.done);
253
254 window_set_focus(old_focus);
256 return sd.key;
257}
static const struct Mapping SmimeHelp[]
Help Bar for the Smime key selection dialog.
Definition dlg_smime.c:73
int smime_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Smime function - Implements function_dispatcher_t -.
static int smime_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format an S/MIME Key for the Menu - Implements Menu::make_entry() -.
Definition dlg_smime.c:111
@ WT_DLG_SMIME
Smime Dialog, dlg_smime()
Definition mutt_window.h:92
Data to pass to the Smime Functions.
struct SmimeKey * key
Selected Key.
bool done
Should we close the Dialog?
struct Menu * menu
Smime Menu.
struct SmimeKeyArray * ska
Array of Keys.
An SIME key.
Definition smime.h:43
struct SmimeKey * next
Linked list.
Definition smime.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_pager()

int dlg_pager ( struct PagerView * pview)

Display an email, attachment, or help, in a window -.

Parameters
pviewPager view settings
Return values
0Success
-1Error

The Pager Dialog displays an Email to the user.

They can navigate through the Email, search through it and user color commands to highlight it.

From the Pager, the user can also use some Index functions, such as <next-entry> or <delete>.

This pager is actually not so simple as it once was. But it will be again. Currently it operates in 3 modes:

  • viewing messages. (PAGER_MODE_EMAIL)
  • viewing attachments. (PAGER_MODE_ATTACH)
  • viewing other stuff (e.g. help). (PAGER_MODE_OTHER) These can be distinguished by PagerMode in PagerView. Data is not yet polymorphic and is fused into a single struct (PagerData). Different elements of PagerData are expected to be present depending on the mode:
  • PAGER_MODE_EMAIL expects data->email and not expects data->body
  • PAGER_MODE_ATTACH expects data->email and data->body special sub-case of this mode is viewing attached email message it is recognized by presence of data->fp and data->body->email
  • PAGER_MODE_OTHER does not expect data->email or data->body

Definition at line 211 of file dlg_pager.c.

212{
213 //===========================================================================
214 // ACT 1 - Ensure sanity of the caller and determine the mode
215 //===========================================================================
216 ASSERT(pview);
217 ASSERT((pview->mode > PAGER_MODE_UNKNOWN) && (pview->mode < PAGER_MODE_MAX));
218 ASSERT(pview->pdata); // view can't exist in a vacuum
219 ASSERT(pview->win_pager);
220 ASSERT(pview->win_pbar);
221
222 struct MuttWindow *dlg = dialog_find(pview->win_pager);
223 struct IndexSharedData *shared = dlg->wdata;
224 struct MuttWindow *win_sidebar = window_find_child(dlg, WT_SIDEBAR);
225
226 switch (pview->mode)
227 {
228 case PAGER_MODE_EMAIL:
229 // This case was previously identified by IsEmail macro
230 // we expect data to contain email and not contain body
231 // We also expect email to always belong to some mailbox
232 ASSERT(shared->mailbox_view);
233 ASSERT(shared->mailbox);
234 ASSERT(shared->email);
235 ASSERT(!pview->pdata->body);
236 break;
237
239 // this case was previously identified by IsAttach and IsMsgAttach
240 // macros, we expect data to contain:
241 // - body (viewing regular attachment)
242 // - fp and body->email in special case of viewing an attached email.
243 ASSERT(pview->pdata->body);
244 if (pview->pdata->fp && pview->pdata->body->email)
245 {
246 // Special case: attachment is a full-blown email message.
247 // Yes, emails can contain other emails.
248 pview->mode = PAGER_MODE_ATTACH_E;
249 }
250 break;
251
252 case PAGER_MODE_HELP:
253 case PAGER_MODE_OTHER:
254 ASSERT(!shared->mailbox_view);
255 ASSERT(!shared->email);
256 ASSERT(!pview->pdata->body);
257 break;
258
260 case PAGER_MODE_MAX:
261 default:
262 // Unexpected mode. Catch fire and explode.
263 // This *should* happen if mode is PAGER_MODE_ATTACH_E, since
264 // we do not expect any caller to pass it to us.
265 ASSERT(false);
266 break;
267 }
268
269 //===========================================================================
270 // ACT 2 - Declare, initialize local variables, read config, etc.
271 //===========================================================================
272
273 //---------- local variables ------------------------------------------------
274 int op = 0;
275 enum MailboxType mailbox_type = shared->mailbox ? shared->mailbox->type : MUTT_UNKNOWN;
276 struct PagerPrivateData *priv = pview->win_pager->parent->wdata;
277 priv->rc = -1;
278 priv->searchctx = 0;
279 priv->first = true;
280 priv->wrapped = false;
281 priv->delay_read_timestamp = 0;
282 priv->pager_redraw = false;
283
284 // Wipe any previous state info
285 struct Notify *notify = priv->notify;
286 int prc = priv->rc;
287 memset(priv, 0, sizeof(*priv));
288 priv->rc = prc;
289 priv->notify = notify;
290 TAILQ_INIT(&priv->ansi_list);
291
292 //---------- setup flags ----------------------------------------------------
293 if (!(pview->flags & MUTT_SHOWCOLOR))
294 pview->flags |= MUTT_SHOWFLAT;
295
296 if ((pview->mode == PAGER_MODE_EMAIL) && !shared->email->read)
297 {
298 if (shared->mailbox_view)
299 shared->mailbox_view->msg_in_pager = shared->email->msgno;
300 const short c_pager_read_delay = cs_subset_number(NeoMutt->sub, "pager_read_delay");
301 if (c_pager_read_delay == 0)
302 {
303 mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true, true);
304 }
305 else
306 {
307 priv->delay_read_timestamp = mutt_date_now_ms() + (1000 * c_pager_read_delay);
308 }
309 }
310 //---------- setup help menu ------------------------------------------------
312 ASSERT(mod_data);
313
314 pview->win_pager->help_data = pager_resolve_help_mapping(pview->mode, mailbox_type);
315 pview->win_pager->help_md = mod_data->menu_pager;
316
317 //---------- initialize redraw pdata -----------------------------------------
319 priv->lines_max = LINES; // number of lines on screen, from curses
320 priv->lines = MUTT_MEM_CALLOC(priv->lines_max, struct Line);
321 priv->fp = mutt_file_fopen(pview->pdata->fname, "r");
322 priv->has_types = ((pview->mode == PAGER_MODE_EMAIL) || (pview->flags & MUTT_SHOWCOLOR)) ?
323 MUTT_TYPES :
324 0; // main message or rfc822 attachment
325
326 for (size_t i = 0; i < priv->lines_max; i++)
327 {
328 priv->lines[i].cid = -1;
329 priv->lines[i].search_arr_size = -1;
330 priv->lines[i].syntax = MUTT_MEM_CALLOC(1, struct TextSyntax);
331 (priv->lines[i].syntax)[0].first = -1;
332 (priv->lines[i].syntax)[0].last = -1;
333 }
334
335 // ---------- try to open the pdata file -------------------------------------
336 if (!priv->fp)
337 {
338 mutt_perror("%s", pview->pdata->fname);
339 for (size_t i = 0; i < priv->lines_max; i++)
340 FREE(&priv->lines[i].syntax);
341 FREE(&priv->lines);
342 return -1;
343 }
344
345 if (stat(pview->pdata->fname, &priv->st) != 0)
346 {
347 mutt_perror("%s", pview->pdata->fname);
348 mutt_file_fclose(&priv->fp);
349 for (size_t i = 0; i < priv->lines_max; i++)
350 FREE(&priv->lines[i].syntax);
351 FREE(&priv->lines);
352 return -1;
353 }
354 unlink(pview->pdata->fname);
355 priv->pview = pview;
356
357 //---------- show windows, set focus and visibility --------------------------
358 window_set_visible(pview->win_pager->parent, true);
361
362 struct MuttWindow *old_focus = window_set_focus(pview->win_pager);
363
364 //---------- jump to the bottom if requested ------------------------------
365 if (pview->flags & MUTT_PAGER_BOTTOM)
366 {
367 jump_to_bottom(priv, pview);
368 }
369
370 //-------------------------------------------------------------------------
371 // ACT 3: Read user input and decide what to do with it
372 // ...but also do a whole lot of other things.
373 //-------------------------------------------------------------------------
374
375 // Force an initial paint, which will populate priv->lines
377 window_redraw(NULL);
378
380 do
381 {
382 window_redraw(NULL);
383
384 const bool c_braille_friendly = cs_subset_bool(NeoMutt->sub, "braille_friendly");
385 if (c_braille_friendly)
386 {
387 if (mod_data->braille_row != -1)
388 {
389 mutt_window_move(priv->pview->win_pager, mod_data->braille_row + 1,
390 mod_data->braille_col);
391 mod_data->braille_row = -1;
392 }
393 }
394 else
395 {
396 mutt_window_move(priv->pview->win_pbar, 0, priv->pview->win_pager->state.cols - 1);
397 }
398
399 // force redraw of the screen at every iteration of the event loop
400 mutt_refresh();
401
402 //-------------------------------------------------------------------------
403 // Check if information in the status bar needs an update
404 // This is done because pager is a single-threaded application, which
405 // tries to emulate concurrency.
406 //-------------------------------------------------------------------------
407 bool do_new_mail = false;
408 if (shared->mailbox && !shared->attach_msg)
409 {
410 int oldcount = shared->mailbox->msg_count;
411 /* check for new mail */
412 enum MxStatus check = mx_mbox_check(shared->mailbox);
413 if (check == MX_STATUS_ERROR)
414 {
415 if (!shared->mailbox || buf_is_empty(&shared->mailbox->pathbuf))
416 {
417 /* fatal error occurred */
419 break;
420 }
421 }
422 else if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED) ||
423 (check == MX_STATUS_FLAGS))
424 {
425 /* notify user of newly arrived mail */
426 if (check == MX_STATUS_NEW_MAIL)
427 {
428 for (size_t i = oldcount; i < shared->mailbox->msg_count; i++)
429 {
430 struct Email *e = shared->mailbox->emails[i];
431
432 if (e && !e->read)
433 {
434 mutt_message(_("New mail in this mailbox"));
435 do_new_mail = true;
436 break;
437 }
438 }
439 }
440
441 if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED))
442 {
445 }
446 }
447
448 if (mutt_mailbox_notify(shared->mailbox) || do_new_mail)
449 {
450 const bool c_beep_new = cs_subset_bool(NeoMutt->sub, "beep_new");
451 if (c_beep_new)
452 mutt_beep(true);
453 const struct Expando *c_new_mail_command = cs_subset_expando(NeoMutt->sub, "new_mail_command");
454 if (c_new_mail_command)
455 {
456 struct Buffer *cmd = buf_pool_get();
457 menu_status_line(cmd, shared, NULL, -1, c_new_mail_command);
458 if (mutt_system(buf_string(cmd)) != 0)
459 mutt_error(_("Error running \"%s\""), buf_string(cmd));
460 buf_pool_release(&cmd);
461 }
462 }
463 }
464 //-------------------------------------------------------------------------
465
466 if (priv->pager_redraw)
467 {
468 priv->pager_redraw = false;
470 clearok(stdscr, true); /* force complete redraw */
471 msgwin_clear_text(NULL);
472
474
475 /* note: mutt_resize_screen() -> mutt_window_reflow() sets
476 * PAGER_REDRAW_PAGER and PAGER_REDRAW_FLOW */
477 continue;
478 }
479
480 dump_pager(priv);
481
482 //-------------------------------------------------------------------------
483 // Finally, read user's key press
484 //-------------------------------------------------------------------------
485 // km_dokey() reads not only user's key strokes, but also a MacroBuffer
486 // MacroBuffer may contain OP codes of the operations.
487 // MacroBuffer is global
488 // OP codes inserted into the MacroBuffer by various functions.
489 // One of such functions is `mutt_enter_command()`
490 // Some OP codes are not handled by pager, they cause pager to quit returning
491 // OP code to index. Index handles the operation and then restarts pager
492 struct KeyEvent event = km_dokey(mod_data->menu_pager, GETCH_NONE);
493 op = event.op;
494
495 // km_dokey() can block, so recheck the timer.
496 // Note: This check must occur before handling the operations of the index
497 // as those can change the currently selected message/entry yielding to
498 // marking the wrong message as read.
500 {
501 if (shared->mailbox && shared->email)
502 mutt_set_flag(shared->mailbox, shared->email, MUTT_READ, true, true);
503 }
504
505 if (SigWinch)
506 priv->pager_redraw = true;
507
508 if (op >= OP_NULL)
510
511 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
512
513 if (op < OP_NULL)
514 continue;
515
516 if (op == OP_NULL)
517 {
518 km_error_key(mod_data->menu_pager);
519 continue;
520 }
521
522 int rc = pager_function_dispatcher(priv->pview->win_pager, &event);
523
524 if (pview->mode == PAGER_MODE_EMAIL)
525 {
526 if ((rc == FR_UNKNOWN) && priv->pview->win_index)
527 rc = index_function_dispatcher(priv->pview->win_index, &event);
528 if (rc == FR_UNKNOWN)
529 rc = sb_function_dispatcher(win_sidebar, &event);
530 }
531 if (rc == FR_UNKNOWN)
532 rc = global_function_dispatcher(priv->pview->win_pager, &event);
533
534 if ((rc == FR_UNKNOWN) &&
535 ((pview->mode == PAGER_MODE_ATTACH) || (pview->mode == PAGER_MODE_ATTACH_E)))
536 {
537 // Some attachment functions still need to be delegated
538 priv->rc = op;
539 break;
540 }
541
542 if ((pview->mode != PAGER_MODE_EMAIL) && (rc == FR_UNKNOWN))
544
545 } while (priv->loop == PAGER_LOOP_CONTINUE);
546 window_set_focus(old_focus);
547
548 //-------------------------------------------------------------------------
549 // END OF ACT 3: Read user input loop - while (op != OP_ABORT)
550 //-------------------------------------------------------------------------
551
552 mutt_file_fclose(&priv->fp);
553 if (pview->mode == PAGER_MODE_EMAIL)
554 {
555 if (shared->mailbox_view)
556 shared->mailbox_view->msg_in_pager = -1;
557 }
558
560
561 for (size_t i = 0; i < priv->lines_max; i++)
562 {
563 FREE(&(priv->lines[i].syntax));
564 if (priv->search_compiled && priv->lines[i].search)
565 FREE(&(priv->lines[i].search));
566 }
567 if (priv->search_compiled)
568 {
569 regfree(&priv->search_re);
570 priv->search_compiled = false;
571 }
572 FREE(&priv->lines);
573 {
574 struct AttrColor *ac = NULL;
575 int count = 0;
576 TAILQ_FOREACH(ac, &priv->ansi_list, entries)
577 {
578 count++;
579 }
580 color_debug(LL_DEBUG5, "AnsiColors %d\n", count);
581 }
583
584 priv->pview = NULL;
585
586 if (priv->loop == PAGER_LOOP_RELOAD)
587 return PAGER_LOOP_RELOAD;
588
589 return (priv->rc != -1) ? priv->rc : 0;
590}
void attr_color_list_clear(struct AttrColorList *acl)
Free the contents of an AttrColorList.
Definition attr.c:116
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
MailboxType
Supported mailbox formats.
Definition mailbox.h:40
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition mailbox.h:43
static void dump_pager(struct PagerPrivateData *priv)
Definition lib.h:151
static int color_debug(enum LogLevel level, const char *format,...)
Definition debug.h:51
struct MuttWindow * dialog_find(struct MuttWindow *win)
Find the parent Dialog of a Window.
Definition dialog.c:89
static bool check_read_delay(uint64_t *timestamp)
Is it time to mark the message read?
Definition dlg_pager.c:172
void pager_queue_redraw(struct PagerPrivateData *priv, PagerRedrawFlags redraw)
Queue a request for a redraw.
Definition dlg_pager.c:121
static const struct Mapping * pager_resolve_help_mapping(enum PagerMode mode, enum MailboxType type)
Determine help mapping based on pager mode and mailbox type.
Definition dlg_pager.c:135
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
void mutt_set_flag(struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
Set a flag on an email.
Definition flags.c:54
void mutt_flushinp(void)
MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.
Definition get.c:81
int pager_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Pager function - Implements function_dispatcher_t -.
Definition functions.c:1207
#define mutt_perror(...)
Definition logging2.h:95
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
@ MODULE_ID_PAGER
ModulePager, Pager
Definition module_api.h:83
uint64_t mutt_date_now_ms(void)
Return the number of milliseconds since the Unix epoch.
Definition date.c:466
@ MUTT_READ
Messages that have been read.
Definition mutt.h:92
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size.
Definition resize.c:76
void window_set_visible(struct MuttWindow *win, bool visible)
Set a Window visible or hidden.
void window_invalidate_all(void)
Mark all windows as in need of repaint.
@ MUTT_WIN_SIZE_MAXIMISE
Window wants as much space as possible.
Definition mutt_window.h:48
bool jump_to_bottom(struct PagerPrivateData *priv, struct PagerView *pview)
Make sure the bottom line is displayed.
Definition functions.c:388
@ PAGER_LOOP_RELOAD
Reload the Pager from scratch.
Definition lib.h:155
@ PAGER_LOOP_CONTINUE
Stay in the Pager Event Loop.
Definition lib.h:153
@ PAGER_REDRAW_FLOW
Reflow the pager.
Definition lib.h:203
@ PAGER_REDRAW_PAGER
Redraw the pager.
Definition lib.h:202
#define MUTT_TYPES
Compute line's type.
Definition lib.h:68
#define MUTT_SHOWCOLOR
Show characters in color otherwise don't show characters.
Definition lib.h:65
#define MUTT_PAGER_BOTTOM
Start at the bottom.
Definition lib.h:76
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition lib.h:143
@ PAGER_MODE_HELP
Pager is invoked via 3rd path to show help.
Definition lib.h:142
@ PAGER_MODE_ATTACH
Pager is invoked via 2nd path. A user-selected attachment (mime part or a nested email) will be shown...
Definition lib.h:140
@ PAGER_MODE_EMAIL
Pager is invoked via 1st path. The mime part is selected automatically.
Definition lib.h:139
@ PAGER_MODE_ATTACH_E
A special case of PAGER_MODE_ATTACH - attachment is a full-blown email message.
Definition lib.h:141
@ PAGER_MODE_UNKNOWN
A default and invalid mode, should never be used.
Definition lib.h:137
@ PAGER_MODE_MAX
Another invalid mode, should never be used.
Definition lib.h:145
#define MUTT_SHOWFLAT
Show characters (used for displaying help)
Definition lib.h:64
void qstyle_free_tree(struct QuoteStyle **quote_list)
Free an entire tree of QuoteStyle.
Definition qstyle.c:58
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define TAILQ_INIT(head)
Definition queue.h:822
volatile sig_atomic_t SigWinch
true after SIGWINCH is received
Definition signal.c:69
A curses colour and its attributes.
Definition attr.h:65
struct Email * email
header information for message/rfc822
Definition body.h:74
int msgno
Number displayed to the user.
Definition email.h:111
struct Email * email
Currently selected Email.
Definition shared_data.h:42
A line of text in the pager.
Definition display.h:50
short search_arr_size
Number of items in search array.
Definition display.h:59
struct TextSyntax * search
Array of search text in the line.
Definition display.h:60
short cid
Default line colour, e.g. MT_COLOR_SIGNATURE.
Definition display.h:52
struct TextSyntax * syntax
Array of coloured text in the line.
Definition display.h:57
int msg_in_pager
Message currently shown in the pager.
Definition mview.h:45
struct MuttWindow * parent
Parent Window.
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
Notification API.
Definition notify.c:53
const char * fname
Name of the file to read.
Definition lib.h:166
FILE * fp
Source stream.
Definition lib.h:164
struct Body * body
Current attachment.
Definition lib.h:163
Pager private Module data.
Definition module_data.h:30
int braille_row
Braille strobe row.
Definition module_data.h:33
struct MenuDefinition * menu_pager
Pager menu definition.
Definition module_data.h:32
int braille_col
Braille strobe column.
Definition module_data.h:34
Private state data for the Pager.
int rc
Return code from functions.
bool wrapped
Has the search/next wrapped around?
bool pager_redraw
Force a complete redraw.
int lines_max
Capacity of lines array (total entries)
uint64_t delay_read_timestamp
Time that email was first shown.
enum PagerLoopMode loop
What the Event Loop should do next, e.g. PAGER_LOOP_CONTINUE.
struct Line * lines
Array of text lines in pager.
int has_types
Set to MUTT_TYPES for PAGER_MODE_EMAIL or MUTT_SHOWCOLOR.
struct Notify * notify
Notifications: NotifyPager, PagerPrivateData.
struct stat st
Stats about Email file.
bool first
First time flag for toggle-new.
struct QuoteStyle * quote_list
Tree of quoting levels.
struct PagerView * pview
Object to view in the pager.
struct AttrColorList ansi_list
List of ANSI colours used in the Pager.
int searchctx
Space to show around search matches.
regex_t search_re
Compiled search string.
FILE * fp
File containing decrypted/decoded/weeded Email.
bool search_compiled
Search regex is in use.
struct MuttWindow * win_index
Index Window.
Definition lib.h:179
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition lib.h:174
enum PagerMode mode
Pager mode.
Definition lib.h:175
PagerFlags flags
Additional settings to tweak pager's function.
Definition lib.h:176
struct MuttWindow * win_pbar
Pager Bar Window.
Definition lib.h:180
struct MuttWindow * win_pager
Pager Window.
Definition lib.h:181
Highlighting for a piece of text.
Definition display.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_pattern()

bool dlg_pattern ( struct Buffer * buf)

Show menu to select a Pattern -.

Parameters
bufBuffer for the selected Pattern
Return values
trueA selection was made

The Select Pattern Dialog shows the user a help page of Patterns. They can select one to auto-complete some functions, e.g. <limit>

Definition at line 302 of file dlg_pattern.c.

303{
304 struct PatternData *pd = pattern_data_new();
305
308
309 struct Menu *menu = sdw.menu;
310 pd->menu = menu;
311 pd->buf = buf;
312
313 menu->mdata = pd;
316 menu->max = ARRAY_SIZE(&pd->entries);
317
318 // L10N: Pattern completion menu title
319 sbar_set_title(sdw.sbar, _("Patterns"));
320
321 // NT_COLOR is handled by the SimpleDialog
324
325 struct MuttWindow *old_focus = window_set_focus(menu->win);
326 // ---------------------------------------------------------------------------
327 // Event Loop
328 int op = OP_NULL;
329 struct KeyEvent event = { 0, OP_NULL };
330 do
331 {
332 menu_tagging_dispatcher(menu->win, &event);
333 window_redraw(NULL);
334
335 event = km_dokey(MdDialog, GETCH_NONE);
336 op = event.op;
337 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
338 if (op < 0)
339 continue;
340 if (op == OP_NULL)
341 {
343 continue;
344 }
346
347 int rc = pattern_function_dispatcher(sdw.dlg, &event);
348 if (rc == FR_UNKNOWN)
349 rc = menu_function_dispatcher(menu->win, &event);
350 if (rc == FR_UNKNOWN)
351 rc = global_function_dispatcher(menu->win, &event);
352 } while (!pd->done);
353 // ---------------------------------------------------------------------------
354
355 bool rc = pd->selection;
356
357 window_set_focus(old_focus);
359
360 return rc;
361}
static const struct Mapping PatternHelp[]
Help Bar for the Pattern selection dialog.
Definition dlg_pattern.c:88
static void create_pattern_entries(struct PatternEntryArray *pea)
Create the Pattern Entries.
int pattern_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Pattern function - Implements function_dispatcher_t -.
Definition functions.c:90
static int pattern_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Create a Pattern for the Menu - Implements Menu::make_entry() -.
void pattern_data_free(struct Menu *menu, void **ptr)
Free Pattern Data - Implements Menu::mdata_free() -.
static int pattern_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
static int pattern_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
@ WT_DLG_PATTERN
Pattern Dialog, dlg_pattern()
Definition mutt_window.h:88
struct PatternData * pattern_data_new(void)
Create new Pattern Data.
Data to pass to the Pattern Functions.
struct Menu * menu
Pattern Menu.
struct PatternEntryArray entries
Patterns for the Menu.
bool done
Should we close the Dialog?
struct Buffer * buf
Buffer for the results.
bool selection
Was a selection made?
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_postpone()

struct Email * dlg_postpone ( struct Mailbox * m)

Create a Menu to select a postponed message -.

Parameters
mMailbox
Return values
ptrEmail

The Select Postponed Email Dialog shows the user a list of draft emails. They can select one to use in the Compose Dialog.

This dialog is only shown if there are two or more postponed emails.

Definition at line 244 of file dlg_postpone.c.

245{
247 ASSERT(mod_data);
248
251 // Required to number the emails
252 struct MailboxView *mv = mview_new(m, NeoMutt->notify);
253
254 struct Menu *menu = sdw.menu;
256 menu->color = post_color;
257 menu->tag = post_tag;
258 menu->max = m->msg_count;
259
260 struct PostponeData pd = { mv, menu, NULL, false, search_state_new() };
261 menu->mdata = &pd;
262 menu->mdata_free = NULL; // Menu doesn't own the data
263
264 // NT_COLOR is handled by the SimpleDialog
267
268 sbar_set_title(sdw.sbar, _("Postponed Messages"));
269
270 /* The postponed mailbox is setup to have sorting disabled, but the global
271 * `$sort` variable may indicate something different. Sorting has to be
272 * disabled while the postpone menu is being displayed. */
273 const enum EmailSortType c_sort = cs_subset_sort(NeoMutt->sub, "sort");
275
276 struct MuttWindow *old_focus = window_set_focus(menu->win);
277 // ---------------------------------------------------------------------------
278 // Event Loop
279 int op = OP_NULL;
280 struct KeyEvent event = { 0, OP_NULL };
281 do
282 {
283 menu_tagging_dispatcher(menu->win, &event);
284 window_redraw(NULL);
285
286 event = km_dokey(mod_data->menu_postpone, GETCH_NONE);
287 op = event.op;
288 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
289 if (op < 0)
290 continue;
291 if (op == OP_NULL)
292 {
293 km_error_key(mod_data->menu_postpone);
294 continue;
295 }
297
298 int rc = postpone_function_dispatcher(sdw.dlg, &event);
299
300 if (rc == FR_UNKNOWN)
301 rc = menu_function_dispatcher(menu->win, &event);
302 if (rc == FR_UNKNOWN)
303 rc = global_function_dispatcher(menu->win, &event);
304 } while (!pd.done);
305 // ---------------------------------------------------------------------------
306
307 mview_free(&mv);
308 cs_subset_str_native_set(NeoMutt->sub, "sort", c_sort, NULL);
310 window_set_focus(old_focus);
312
313 return pd.email;
314}
static const struct Mapping PostponedHelp[]
Help Bar for the Postponed email selection dialog.
@ EMAIL_SORT_UNSORTED
Sort by the order the messages appear in the mailbox.
Definition sort.h:64
int postpone_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Postpone function - Implements function_dispatcher_t -.
Definition functions.c:292
static const struct AttrColor * post_color(struct Menu *menu, int line)
Calculate the colour for a line of the postpone index - Implements Menu::color() -.
static int post_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format an Email for the Menu - Implements Menu::make_entry() -.
static int post_tag(struct Menu *menu, int sel, int act)
Tag an email in the postpone menu - Implements Menu::tag() -.
static int postponed_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
static int postponed_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
@ MODULE_ID_POSTPONE
ModulePostpone, Postponed Emails
Definition module_api.h:87
@ WT_DLG_POSTPONE
Postpone Dialog, dlg_postpone()
Definition mutt_window.h:90
void search_state_free(struct SearchState **ptr)
Free a SearchState.
struct SearchState * search_state_new(void)
Create a new SearchState.
View of a Mailbox.
Definition mview.h:40
Data to pass to the Postpone Functions.
Definition functions.h:35
struct Email * email
Selected Email.
Definition functions.h:38
struct SearchState * search_state
State of the current search.
Definition functions.h:40
bool done
Should we close the Dialog?
Definition functions.h:39
struct Menu * menu
Postponed Menu.
Definition functions.h:37
Postpone private Module data.
Definition module_data.h:32
struct MenuDefinition * menu_postpone
Postpone menu definition.
Definition module_data.h:34
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:303
+ Here is the call graph for this function:
+ Here is the caller graph for this function: