NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
functions.c
Go to the documentation of this file.
1
23
29
30#include "config.h"
31#include <stdbool.h>
32#include <stddef.h>
33#include "mutt/lib.h"
34#include "config/lib.h"
35#include "email/lib.h"
36#include "core/lib.h"
37#include "gui/lib.h"
38#include "mutt.h"
39#include "functions.h"
40#include "key/lib.h"
41#include "menu/lib.h"
42#include "pattern/lib.h"
43#include "module_data.h"
44
45// clang-format off
49static const struct MenuFuncOp OpPostpone[] = { /* map: postpone */
50 { "delete-entry", OP_DELETE },
51 { "undelete-entry", OP_UNDELETE },
52 { NULL, 0 },
53};
54
58static const struct MenuOpSeq PostponeDefaultBindings[] = { /* map: postpone */
59 { OP_DELETE, "d" },
60 { OP_TAG, "t" },
61 { OP_UNDELETE, "u" },
62 { 0, NULL },
63};
64// clang-format on
65
69void postpone_init_keys(struct NeoMutt *n, struct SubMenu *sm_generic)
70{
71 struct MenuDefinition *md = NULL;
72 struct SubMenu *sm = NULL;
73
75 md = km_register_menu(MENU_POSTPONE, "postpone");
76 km_menu_add_submenu(md, sm);
77 km_menu_add_submenu(md, sm_generic);
79
81 ASSERT(mod_data);
82 mod_data->menu_postpone = md;
83}
84
100static int postpone_add_selection(struct EmailArray *ea, struct Menu *menu,
101 struct Mailbox *m, bool tagged, int count)
102{
103 if (!ea || !menu || !m || !m->emails)
104 return 0;
105
106 if (tagged)
107 {
108 for (int i = 0; i < m->msg_count; i++)
109 {
110 struct Email *e = m->emails[i];
111 if (e && e->tagged)
112 ARRAY_ADD(ea, e);
113 }
114 }
115 else
116 {
117 const int index = menu_get_index(menu);
118 if ((index < 0) || (index >= m->msg_count))
119 return 0;
120
121 int n = (count > 1) ? count : 1;
122 if ((index + n) > m->msg_count)
123 n = m->msg_count - index;
124
125 for (int i = 0; i < n; i++)
126 {
127 struct Email *e = m->emails[index + i];
128 if (e)
129 ARRAY_ADD(ea, e);
130 }
131 }
132
133 return ARRAY_SIZE(ea);
134}
135
144static void postpone_apply_set_deleted(struct Mailbox *m, struct EmailArray *ea, bool deleted)
145{
146 if (!m || !ea)
147 return;
148
149 struct Email **ep = NULL;
150 ARRAY_FOREACH(ep, ea)
151 {
152 if (*ep)
153 mutt_set_flag(m, *ep, MUTT_DELETE, deleted, true);
154 }
155
157 if (mod_data)
158 mod_data->post_count = m->msg_count - m->msg_deleted;
159}
160
171static int op_delete(struct PostponeData *pd, const struct KeyEvent *event)
172{
173 struct Menu *menu = pd->menu;
174 struct MailboxView *mv = pd->mailbox_view;
175 struct Mailbox *m = mv->mailbox;
176
177 const int index = menu_get_index(menu);
178 const bool bf = (event->op == OP_DELETE);
179
180 /* should deleted draft messages be saved in the trash folder? */
181 struct EmailArray ea = ARRAY_HEAD_INITIALIZER;
182 postpone_add_selection(&ea, menu, m, menu->tag_prefix, event->count);
183 const int num = ARRAY_SIZE(&ea);
184 postpone_apply_set_deleted(m, &ea, bf);
185 ARRAY_FREE(&ea);
186
187 const bool c_resolve = cs_subset_bool(NeoMutt->sub, "resolve");
188 if (!menu->tag_prefix && c_resolve && ((index + num) < menu->max))
189 {
190 const int new_index = index + num;
191 menu_set_index(menu, new_index);
192 if (new_index >= (menu->top + menu->page_len))
193 {
194 menu->top = new_index;
195 }
196 }
198
199 return FR_SUCCESS;
200}
201
205static int op_quit(struct PostponeData *pd, const struct KeyEvent *event)
206{
207 pd->done = true;
208 return FR_SUCCESS;
209}
210
214static int op_generic_select_entry(struct PostponeData *pd, const struct KeyEvent *event)
215{
216 int index = menu_get_index(pd->menu);
217 struct MailboxView *mv = pd->mailbox_view;
218 struct Mailbox *m = mv->mailbox;
219 pd->email = m->emails[index];
220 pd->done = true;
221 return FR_SUCCESS;
222}
223
233static int op_search(struct PostponeData *pd, const struct KeyEvent *event)
234{
235 SearchFlags flags = SEARCH_NONE;
236 switch (event->op)
237 {
238 case OP_SEARCH:
239 flags |= SEARCH_PROMPT;
240 pd->search_state->reverse = false;
241 break;
242 case OP_SEARCH_REVERSE:
243 flags |= SEARCH_PROMPT;
244 pd->search_state->reverse = true;
245 break;
246 case OP_SEARCH_NEXT:
247 break;
248 case OP_SEARCH_OPPOSITE:
249 flags |= SEARCH_OPPOSITE;
250 break;
251 }
252
253 int index = menu_get_index(pd->menu);
254 struct MailboxView *mv = pd->mailbox_view;
255 index = mutt_search_command(mv, pd->menu, index, pd->search_state, flags);
256 if (index != -1)
257 menu_set_index(pd->menu, index);
258
259 return FR_SUCCESS;
260}
261
262// -----------------------------------------------------------------------------
263
267static const struct PostponeFunction PostponeFunctions[] = {
268 // clang-format off
269 { OP_DELETE, op_delete },
270 { OP_EXIT, op_quit },
271 { OP_GENERIC_SELECT_ENTRY, op_generic_select_entry },
272 { OP_QUIT, op_quit },
273 { OP_SEARCH, op_search },
274 { OP_SEARCH_NEXT, op_search },
275 { OP_SEARCH_OPPOSITE, op_search },
276 { OP_SEARCH_REVERSE, op_search },
277 { OP_UNDELETE, op_delete },
278 { 0, NULL },
279 // clang-format on
280};
281
285int postpone_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
286{
287 // The Dispatcher may be called on any Window in the Dialog
288 struct MuttWindow *dlg = dialog_find(win);
289 if (!event || !dlg || !dlg->wdata)
290 {
292 return FR_ERROR;
293 }
294
295 const int op = event->op;
296 struct Menu *menu = dlg->wdata;
297 struct PostponeData *pd = menu->mdata;
298 if (!pd)
299 {
301 return FR_ERROR;
302 }
303
304 int rc = FR_UNKNOWN;
305 for (size_t i = 0; PostponeFunctions[i].op != OP_NULL; i++)
306 {
307 const struct PostponeFunction *fn = &PostponeFunctions[i];
308 if (fn->op == op)
309 {
310 rc = fn->function(pd, event);
311 break;
312 }
313 }
314
315 if (rc == FR_UNKNOWN) // Not our function
316 return rc;
317
318 const char *result = dispatcher_get_retval_name(rc);
319 mutt_debug(LL_DEBUG1, "Handled %s (%d) -> %s\n", opcodes_get_name(op), op, NONULL(result));
320
322 return rc;
323}
324
331{
332 if (!dlg)
333 return NULL;
334
335 struct Menu *menu = dlg->wdata;
336 struct PostponeData *pd = menu->mdata;
337 if (!pd)
338 return NULL;
339
340 return pd->mailbox_view;
341}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
struct MuttWindow * dialog_find(struct MuttWindow *win)
Find the parent Dialog of a Window.
Definition dialog.c:89
const char * dispatcher_get_retval_name(int rv)
Get the name of a return value.
Definition dispatcher.c:55
void dispatcher_flush_on_error(int rv)
Flush pending keys after a dispatch error.
Definition dispatcher.c:65
@ FR_SUCCESS
Valid function - successfully performed.
Definition dispatcher.h:40
@ FR_UNKNOWN
Unknown function.
Definition dispatcher.h:34
@ FR_ERROR
Valid function - error occurred.
Definition dispatcher.h:39
Structs that make up an email.
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
static int op_quit(struct AliasFunctionData *fdata, const struct KeyEvent *event)
Save changes and exit this dialog - Implements alias_function_t -.
Definition functions.c:308
static int op_delete(struct AliasFunctionData *fdata, const struct KeyEvent *event)
delete the current entry - Implements alias_function_t -
Definition functions.c:270
static int op_search(struct AliasFunctionData *fdata, const struct KeyEvent *event)
search for a regular expression - Implements alias_function_t -
Definition functions.c:519
static int op_generic_select_entry(struct AliasFunctionData *fdata, const struct KeyEvent *event)
select the current entry - Implements alias_function_t -
Definition functions.c:388
int postpone_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Postpone function - Implements function_dispatcher_t -.
Definition functions.c:285
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
Convenience wrapper for the gui headers.
void km_menu_add_submenu(struct MenuDefinition *md, struct SubMenu *sm)
Add a SubMenu to a Menu Definition.
Definition init.c:123
struct SubMenu * km_register_submenu(const struct MenuFuncOp functions[])
Register a submenu.
Definition init.c:88
struct MenuDefinition * km_register_menu(int menu, const char *name)
Register a menu.
Definition init.c:105
void km_menu_add_bindings(struct MenuDefinition *md, const struct MenuOpSeq bindings[])
Add Keybindings to a Menu.
Definition init.c:136
Manage keymappings.
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
GUI present the user with a selectable list.
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition menu.c:177
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition menu.c:153
@ 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:167
@ MODULE_ID_POSTPONE
ModulePostpone, Postponed Emails
Definition module_api.h:89
Convenience wrapper for the library headers.
Many unsorted constants and some structs.
@ MUTT_DELETE
Messages to be deleted.
Definition mutt.h:94
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition opcodes.c:48
Match patterns to emails.
int mutt_search_command(struct MailboxView *mv, struct Menu *menu, int cur, struct SearchState *state, SearchFlags flags)
Perform a search.
Definition pattern.c:462
struct MailboxView * postpone_get_mailbox_view(struct MuttWindow *dlg)
Extract the Mailbox from the Postponed Dialog.
Definition functions.c:330
static void postpone_apply_set_deleted(struct Mailbox *m, struct EmailArray *ea, bool deleted)
Apply the deleted flag to a working set of Emails.
Definition functions.c:144
static int postpone_add_selection(struct EmailArray *ea, struct Menu *menu, struct Mailbox *m, bool tagged, int count)
Build a working set of Emails for an action.
Definition functions.c:100
static const struct MenuFuncOp OpPostpone[]
Functions for the Postpone Menu.
Definition functions.c:49
static const struct MenuOpSeq PostponeDefaultBindings[]
Key bindings for the Postpone Menu.
Definition functions.c:58
static const struct PostponeFunction PostponeFunctions[]
All the NeoMutt functions that the Postpone supports.
Definition functions.c:267
void postpone_init_keys(struct NeoMutt *n, struct SubMenu *sm_generic)
Initialise the Postponed Keybindings - Implements ::init_keys_api.
Definition functions.c:69
Postponed Email Functions.
Postpone private Module data.
uint8_t SearchFlags
@ SEARCH_NONE
No flags are set.
@ SEARCH_PROMPT
Ask for search input.
@ SEARCH_OPPOSITE
Search in the opposite direction.
#define ASSERT(COND)
Definition signal2.h:59
#define NONULL(x)
Definition string2.h:44
The envelope/body of an email.
Definition email.h:39
bool deleted
Email is deleted.
Definition email.h:78
int index
The absolute (unsorted) message number.
Definition email.h:110
bool tagged
Email is tagged.
Definition email.h:107
An event such as a keypress.
Definition get.h:75
int count
Optional count prefix, e.g. 3 for 3j
Definition get.h:78
int op
Function opcode, e.g. OP_HELP.
Definition get.h:77
View of a Mailbox.
Definition mview.h:40
struct Mailbox * mailbox
Current Mailbox.
Definition mview.h:51
A mailbox.
Definition mailbox.h:81
int msg_count
Total number of messages.
Definition mailbox.h:90
struct Email ** emails
Array of Emails.
Definition mailbox.h:98
int msg_deleted
Number of deleted messages.
Definition mailbox.h:95
Functions for a Dialog or Window.
Definition menudef.h:44
Mapping between a function and an operation.
Definition menu.h:37
Mapping between an operation and a key sequence.
Definition menu.h:47
Definition lib.h:86
int top
Entry that is the top of the current page.
Definition lib.h:98
void * mdata
Private data.
Definition lib.h:155
bool tag_prefix
User has pressed <tag-prefix>
Definition lib.h:92
int max
Number of entries in the menu.
Definition lib.h:88
int page_len
Number of entries per screen.
Definition lib.h:91
void * wdata
Private data.
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
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 MailboxView * mailbox_view
Postponed Mailbox view.
Definition functions.h:36
struct Menu * menu
Postponed Menu.
Definition functions.h:37
A NeoMutt function.
Definition functions.h:62
postpone_function_t function
Function to call.
Definition functions.h:64
int op
Op code, e.g. OP_DELETE.
Definition functions.h:63
Postpone private Module data.
Definition module_data.h:32
struct MenuDefinition * menu_postpone
Postpone menu definition.
Definition module_data.h:34
short post_count
Number of postponed (draft) emails.
Definition module_data.h:35
bool reverse
search backwards
Collection of related functions.
Definition menudef.h:33
@ MENU_POSTPONE
Select a postponed email.
Definition type.h:49