NeoMutt  2022-04-29-178-g3b62e6
Teaching an old dog new tricks
DOXYGEN
functions.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <stddef.h>
31#include <stdbool.h>
32#include "private.h"
33#include "mutt/lib.h"
34#include "config/lib.h"
35#include "core/lib.h"
36#include "gui/lib.h"
37#include "functions.h"
38#include "lib.h"
39#include "index/lib.h"
40#include "opcodes.h"
41
47bool sb_next(struct SidebarWindowData *wdata)
48{
49 struct SbEntry **sbep = NULL;
50 ARRAY_FOREACH_FROM(sbep, &wdata->entries, wdata->hil_index + 1)
51 {
52 if (!(*sbep)->is_hidden)
53 {
54 wdata->hil_index = ARRAY_FOREACH_IDX;
55 return true;
56 }
57 }
58
59 return false;
60}
61
70static struct SbEntry **sb_next_new(struct SidebarWindowData *wdata, size_t begin, size_t end)
71{
72 struct SbEntry **sbep = NULL;
73 ARRAY_FOREACH_FROM_TO(sbep, &wdata->entries, begin, end)
74 {
75 if ((*sbep)->mailbox->has_new || ((*sbep)->mailbox->msg_unread != 0))
76 return sbep;
77 }
78 return NULL;
79}
80
86bool sb_prev(struct SidebarWindowData *wdata)
87{
88 struct SbEntry **sbep = NULL, **prev = NULL;
89 ARRAY_FOREACH_TO(sbep, &wdata->entries, wdata->hil_index)
90 {
91 if (!(*sbep)->is_hidden)
92 prev = sbep;
93 }
94
95 if (prev)
96 {
97 wdata->hil_index = ARRAY_IDX(&wdata->entries, prev);
98 return true;
99 }
100
101 return false;
102}
103
112static struct SbEntry **sb_prev_new(struct SidebarWindowData *wdata, size_t begin, size_t end)
113{
114 struct SbEntry **sbep = NULL, **prev = NULL;
115 ARRAY_FOREACH_FROM_TO(sbep, &wdata->entries, begin, end)
116 {
117 if ((*sbep)->mailbox->has_new || ((*sbep)->mailbox->msg_unread != 0))
118 prev = sbep;
119 }
120
121 return prev;
122}
123
124// -----------------------------------------------------------------------------
125
129static int op_sidebar_first(struct SidebarWindowData *wdata, int op)
130{
131 if (!mutt_window_is_visible(wdata->win))
132 return FR_NO_ACTION;
133
134 if (ARRAY_EMPTY(&wdata->entries) || (wdata->hil_index < 0))
135 return FR_NO_ACTION;
136
137 int orig_hil_index = wdata->hil_index;
138
139 wdata->hil_index = 0;
140 if ((*ARRAY_GET(&wdata->entries, wdata->hil_index))->is_hidden)
141 if (!sb_next(wdata))
142 wdata->hil_index = orig_hil_index;
143
144 if (orig_hil_index == wdata->hil_index)
145 return FR_NO_ACTION;
146
147 wdata->win->actions |= WA_RECALC;
148 return FR_SUCCESS;
149}
150
154static int op_sidebar_last(struct SidebarWindowData *wdata, int op)
155{
156 if (!mutt_window_is_visible(wdata->win))
157 return FR_NO_ACTION;
158
159 if (ARRAY_EMPTY(&wdata->entries) || (wdata->hil_index < 0))
160 return FR_NO_ACTION;
161
162 int orig_hil_index = wdata->hil_index;
163
164 wdata->hil_index = ARRAY_SIZE(&wdata->entries);
165 if (!sb_prev(wdata))
166 wdata->hil_index = orig_hil_index;
167
168 if (orig_hil_index == wdata->hil_index)
169 return FR_NO_ACTION;
170
171 wdata->win->actions |= WA_RECALC;
172 return FR_SUCCESS;
173}
174
178static int op_sidebar_next(struct SidebarWindowData *wdata, int op)
179{
180 if (!mutt_window_is_visible(wdata->win))
181 return FR_NO_ACTION;
182
183 if (ARRAY_EMPTY(&wdata->entries) || (wdata->hil_index < 0))
184 return FR_NO_ACTION;
185
186 if (!sb_next(wdata))
187 return FR_NO_ACTION;
188
189 wdata->win->actions |= WA_RECALC;
190 return FR_SUCCESS;
191}
192
198static int op_sidebar_next_new(struct SidebarWindowData *wdata, int op)
199{
200 if (!mutt_window_is_visible(wdata->win))
201 return FR_NO_ACTION;
202
203 const size_t max_entries = ARRAY_SIZE(&wdata->entries);
204 if ((max_entries == 0) || (wdata->hil_index < 0))
205 return FR_NO_ACTION;
206
207 const bool c_sidebar_next_new_wrap = cs_subset_bool(NeoMutt->sub, "sidebar_next_new_wrap");
208 struct SbEntry **sbep = NULL;
209 if ((sbep = sb_next_new(wdata, wdata->hil_index + 1, max_entries)) ||
210 (c_sidebar_next_new_wrap && (sbep = sb_next_new(wdata, 0, wdata->hil_index))))
211 {
212 wdata->hil_index = ARRAY_IDX(&wdata->entries, sbep);
213 wdata->win->actions |= WA_RECALC;
214 return FR_SUCCESS;
215 }
216
217 return FR_NO_ACTION;
218}
219
223static int op_sidebar_open(struct SidebarWindowData *wdata, int op)
224{
225 struct MuttWindow *win_sidebar = wdata->win;
226 if (!mutt_window_is_visible(win_sidebar))
227 return FR_NO_ACTION;
228
229 struct MuttWindow *dlg = dialog_find(win_sidebar);
230 dlg_change_folder(dlg, sb_get_highlight(win_sidebar));
231 return FR_SUCCESS;
232}
233
238{
239 if (!mutt_window_is_visible(wdata->win))
240 return FR_NO_ACTION;
241
242 if (ARRAY_EMPTY(&wdata->entries) || (wdata->bot_index < 0))
243 return FR_NO_ACTION;
244
245 int orig_hil_index = wdata->hil_index;
246
247 wdata->hil_index = wdata->bot_index;
248 sb_next(wdata);
249 /* If the rest of the entries are hidden, go up to the last unhidden one */
250 if ((*ARRAY_GET(&wdata->entries, wdata->hil_index))->is_hidden)
251 sb_prev(wdata);
252
253 if (orig_hil_index == wdata->hil_index)
254 return FR_NO_ACTION;
255
256 wdata->win->actions |= WA_RECALC;
257 return FR_SUCCESS;
258}
259
263static int op_sidebar_page_up(struct SidebarWindowData *wdata, int op)
264{
265 if (!mutt_window_is_visible(wdata->win))
266 return FR_NO_ACTION;
267
268 if (ARRAY_EMPTY(&wdata->entries) || (wdata->top_index < 0))
269 return FR_NO_ACTION;
270
271 int orig_hil_index = wdata->hil_index;
272
273 wdata->hil_index = wdata->top_index;
274 sb_prev(wdata);
275 /* If the rest of the entries are hidden, go down to the last unhidden one */
276 if ((*ARRAY_GET(&wdata->entries, wdata->hil_index))->is_hidden)
277 sb_next(wdata);
278
279 if (orig_hil_index == wdata->hil_index)
280 return FR_NO_ACTION;
281
282 wdata->win->actions |= WA_RECALC;
283 return FR_SUCCESS;
284}
285
289static int op_sidebar_prev(struct SidebarWindowData *wdata, int op)
290{
291 if (!mutt_window_is_visible(wdata->win))
292 return FR_NO_ACTION;
293
294 if (ARRAY_EMPTY(&wdata->entries) || (wdata->hil_index < 0))
295 return FR_NO_ACTION;
296
297 if (!sb_prev(wdata))
298 return FR_NO_ACTION;
299
300 wdata->win->actions |= WA_RECALC;
301 return FR_SUCCESS;
302}
303
309static int op_sidebar_prev_new(struct SidebarWindowData *wdata, int op)
310{
311 if (!mutt_window_is_visible(wdata->win))
312 return FR_NO_ACTION;
313
314 const size_t max_entries = ARRAY_SIZE(&wdata->entries);
315 if ((max_entries == 0) || (wdata->hil_index < 0))
316 return FR_NO_ACTION;
317
318 const bool c_sidebar_next_new_wrap = cs_subset_bool(NeoMutt->sub, "sidebar_next_new_wrap");
319 struct SbEntry **sbep = NULL;
320 if ((sbep = sb_prev_new(wdata, 0, wdata->hil_index)) ||
321 (c_sidebar_next_new_wrap &&
322 (sbep = sb_prev_new(wdata, wdata->hil_index + 1, max_entries))))
323 {
324 wdata->hil_index = ARRAY_IDX(&wdata->entries, sbep);
325 wdata->win->actions |= WA_RECALC;
326 return FR_SUCCESS;
327 }
328
329 return FR_NO_ACTION;
330}
331
335static int op_sidebar_toggle_visible(struct SidebarWindowData *wdata, int op)
336{
337 bool_str_toggle(NeoMutt->sub, "sidebar_visible", NULL);
338 mutt_window_reflow(NULL);
339 return FR_SUCCESS;
340}
341
345static int op_sidebar_toggle_virtual(struct SidebarWindowData *wdata, int op)
346{
347 return FR_SUCCESS;
348}
349
350// -----------------------------------------------------------------------------
351
356 // clang-format off
357 { OP_SIDEBAR_FIRST, op_sidebar_first },
358 { OP_SIDEBAR_LAST, op_sidebar_last },
359 { OP_SIDEBAR_NEXT, op_sidebar_next },
360 { OP_SIDEBAR_NEXT_NEW, op_sidebar_next_new },
361 { OP_SIDEBAR_OPEN, op_sidebar_open },
362 { OP_SIDEBAR_PAGE_DOWN, op_sidebar_page_down },
363 { OP_SIDEBAR_PAGE_UP, op_sidebar_page_up },
364 { OP_SIDEBAR_PREV, op_sidebar_prev },
365 { OP_SIDEBAR_PREV_NEW, op_sidebar_prev_new },
366 { OP_SIDEBAR_TOGGLE_VIRTUAL, op_sidebar_toggle_virtual },
367 { OP_SIDEBAR_TOGGLE_VISIBLE, op_sidebar_toggle_visible },
368 { 0, NULL },
369 // clang-format on
370};
371
376{
377 if (!win || !win->wdata)
378 return FR_UNKNOWN;
379
380 struct SidebarWindowData *wdata = win->wdata;
381 int rc = FR_UNKNOWN;
382 for (size_t i = 0; SidebarFunctions[i].op != OP_NULL; i++)
383 {
384 const struct SidebarFunction *fn = &SidebarFunctions[i];
385 if (fn->op == op)
386 {
387 rc = fn->function(wdata, op);
388 break;
389 }
390 }
391
392 if (rc == FR_UNKNOWN) // Not our function
393 return rc;
394
395 const char *result = dispacher_get_retval_name(rc);
396 mutt_debug(LL_DEBUG1, "Handled %s (%d) -> %s\n", opcodes_get_name(op), op, NONULL(result));
397
398 return FR_SUCCESS; // Whatever the outcome, we handled it
399}
#define ARRAY_IDX(head, elem)
Return the index of an element of the array.
Definition: array.h:258
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:73
#define ARRAY_FOREACH_TO(elem, head, to)
Iterate from the beginning to an index.
Definition: array.h:233
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:86
#define ARRAY_FOREACH_FROM(elem, head, from)
Iterate from an index to the end.
Definition: array.h:222
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:108
#define ARRAY_FOREACH_FROM_TO(elem, head, from, to)
Iterate between two indexes.
Definition: array.h:246
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:214
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
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:83
const char * dispacher_get_retval_name(int rv)
Get the name of a return value.
Definition: dispatcher.c:54
@ FR_SUCCESS
Valid function - successfully performed.
Definition: dispatcher.h:39
@ FR_UNKNOWN
Unknown function.
Definition: dispatcher.h:33
@ FR_NO_ACTION
Valid function - no action performed.
Definition: dispatcher.h:37
void dlg_change_folder(struct MuttWindow *dlg, struct Mailbox *m)
Change the current folder, cautiously.
Definition: dlg_index.c:1427
int sb_function_dispatcher(struct MuttWindow *win, int op)
Perform a Sidebar function - Implements function_dispatcher_t -.
Definition: functions.c:375
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
static int op_sidebar_page_up(struct SidebarWindowData *wdata, int op)
Selects the last entry in the previous page of mailboxes - Implements sidebar_function_t -.
Definition: functions.c:263
static int op_sidebar_page_down(struct SidebarWindowData *wdata, int op)
Selects the first entry in the next page of mailboxes - Implements sidebar_function_t -.
Definition: functions.c:237
static int op_sidebar_toggle_virtual(struct SidebarWindowData *wdata, int op)
Deprecated - Implements sidebar_function_t -.
Definition: functions.c:345
static int op_sidebar_next_new(struct SidebarWindowData *wdata, int op)
Selects the next new mailbox - Implements sidebar_function_t -.
Definition: functions.c:198
static int op_sidebar_next(struct SidebarWindowData *wdata, int op)
Selects the next unhidden mailbox - Implements sidebar_function_t -.
Definition: functions.c:178
static int op_sidebar_toggle_visible(struct SidebarWindowData *wdata, int op)
Make the sidebar (in)visible - Implements sidebar_function_t -.
Definition: functions.c:335
static int op_sidebar_prev(struct SidebarWindowData *wdata, int op)
Selects the previous unhidden mailbox - Implements sidebar_function_t -.
Definition: functions.c:289
static int op_sidebar_prev_new(struct SidebarWindowData *wdata, int op)
Selects the previous new mailbox - Implements sidebar_function_t -.
Definition: functions.c:309
static int op_sidebar_first(struct SidebarWindowData *wdata, int op)
Selects the first unhidden mailbox - Implements sidebar_function_t -.
Definition: functions.c:129
static int op_sidebar_open(struct SidebarWindowData *wdata, int op)
Open highlighted mailbox - Implements sidebar_function_t -.
Definition: functions.c:223
static int op_sidebar_last(struct SidebarWindowData *wdata, int op)
Selects the last unhidden mailbox - Implements sidebar_function_t -.
Definition: functions.c:154
Convenience wrapper for the gui headers.
GUI manage the main index (list of emails)
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
Convenience wrapper for the library headers.
bool mutt_window_is_visible(struct MuttWindow *win)
Is the Window visible?
Definition: mutt_window.c:501
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:340
#define WA_RECALC
Recalculate the contents of the Window.
Definition: mutt_window.h:110
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:46
All user-callable functions.
struct SidebarFunction SidebarFunctions[]
All the NeoMutt functions that the Sidebar supports.
Definition: functions.c:355
bool sb_prev(struct SidebarWindowData *wdata)
Find the previous unhidden Mailbox.
Definition: functions.c:86
static struct SbEntry ** sb_prev_new(struct SidebarWindowData *wdata, size_t begin, size_t end)
Return the previous mailbox with new messages.
Definition: functions.c:112
bool sb_next(struct SidebarWindowData *wdata)
Find the next unhidden Mailbox.
Definition: functions.c:47
static struct SbEntry ** sb_next_new(struct SidebarWindowData *wdata, size_t begin, size_t end)
Return the next mailbox with new messages.
Definition: functions.c:70
Sidebar functions.
GUI display the mailboxes in a side panel.
struct Mailbox * sb_get_highlight(struct MuttWindow *win)
Get the Mailbox that's highlighted in the sidebar.
Definition: sidebar.c:58
Key value store.
#define NONULL(x)
Definition: string2.h:37
void * wdata
Private data.
Definition: mutt_window.h:145
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
Definition: mutt_window.h:132
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Info about folders in the sidebar.
Definition: private.h:41
A NeoMutt function.
Definition: functions.h:44
int op
Op code, e.g. OP_SIDEBAR_NEXT.
Definition: functions.h:45
sidebar_function_t function
Function to call.
Definition: functions.h:46
Sidebar private Window data -.
Definition: private.h:65
int hil_index
Highlighted mailbox.
Definition: private.h:72
struct MuttWindow * win
Sidebar Window.
Definition: private.h:66
struct SbEntryArray entries
Items to display in the sidebar.
Definition: private.h:68