NeoMutt  2021-02-05-89-gabe350
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 "core/lib.h"
35 #include "gui/lib.h"
36 #include "lib.h"
37 #include "opcodes.h"
38 
45 {
46  if (ARRAY_EMPTY(&wdata->entries) || (wdata->hil_index < 0))
47  return false;
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 
70 static struct SbEntry **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 
89 static bool select_next_new(struct SidebarWindowData *wdata, bool next_new_wrap)
90 {
91  const size_t max_entries = ARRAY_SIZE(&wdata->entries);
92 
93  if ((max_entries == 0) || (wdata->hil_index < 0))
94  return false;
95 
96  struct SbEntry **sbep = NULL;
97  if ((sbep = next_new(wdata, wdata->hil_index + 1, max_entries)) ||
98  (next_new_wrap && (sbep = next_new(wdata, 0, wdata->hil_index))))
99  {
100  wdata->hil_index = ARRAY_IDX(&wdata->entries, sbep);
101  return true;
102  }
103 
104  return false;
105 }
106 
112 bool select_prev(struct SidebarWindowData *wdata)
113 {
114  if (ARRAY_EMPTY(&wdata->entries) || (wdata->hil_index < 0))
115  return false;
116 
117  struct SbEntry **sbep = NULL, **prev = NULL;
118  ARRAY_FOREACH_TO(sbep, &wdata->entries, wdata->hil_index)
119  {
120  if (!(*sbep)->is_hidden)
121  prev = sbep;
122  }
123 
124  if (prev)
125  {
126  wdata->hil_index = ARRAY_IDX(&wdata->entries, prev);
127  return true;
128  }
129 
130  return false;
131 }
132 
141 static struct SbEntry **prev_new(struct SidebarWindowData *wdata, size_t begin, size_t end)
142 {
143  struct SbEntry **sbep = NULL, **prev = NULL;
144  ARRAY_FOREACH_FROM_TO(sbep, &wdata->entries, begin, end)
145  {
146  if ((*sbep)->mailbox->has_new || (*sbep)->mailbox->msg_unread != 0)
147  prev = sbep;
148  }
149 
150  return prev;
151 }
152 
161 static bool select_prev_new(struct SidebarWindowData *wdata, bool next_new_wrap)
162 {
163  const size_t max_entries = ARRAY_SIZE(&wdata->entries);
164 
165  if ((max_entries == 0) || (wdata->hil_index < 0))
166  return false;
167 
168  struct SbEntry **sbep = NULL;
169  if ((sbep = prev_new(wdata, 0, wdata->hil_index)) ||
170  (next_new_wrap && (sbep = prev_new(wdata, wdata->hil_index + 1, max_entries))))
171  {
172  wdata->hil_index = ARRAY_IDX(&wdata->entries, sbep);
173  return true;
174  }
175 
176  return false;
177 }
178 
184 static bool select_page_down(struct SidebarWindowData *wdata)
185 {
186  if (ARRAY_EMPTY(&wdata->entries) || (wdata->bot_index < 0))
187  return false;
188 
189  int orig_hil_index = wdata->hil_index;
190 
191  wdata->hil_index = wdata->bot_index;
192  select_next(wdata);
193  /* If the rest of the entries are hidden, go up to the last unhidden one */
194  if ((*ARRAY_GET(&wdata->entries, wdata->hil_index))->is_hidden)
195  select_prev(wdata);
196 
197  return (orig_hil_index != wdata->hil_index);
198 }
199 
205 static bool select_page_up(struct SidebarWindowData *wdata)
206 {
207  if (ARRAY_EMPTY(&wdata->entries) || (wdata->top_index < 0))
208  return false;
209 
210  int orig_hil_index = wdata->hil_index;
211 
212  wdata->hil_index = wdata->top_index;
213  select_prev(wdata);
214  /* If the rest of the entries are hidden, go down to the last unhidden one */
215  if ((*ARRAY_GET(&wdata->entries, wdata->hil_index))->is_hidden)
216  select_next(wdata);
217 
218  return (orig_hil_index != wdata->hil_index);
219 }
220 
226 static bool select_first(struct SidebarWindowData *wdata)
227 {
228  if (ARRAY_EMPTY(&wdata->entries) || (wdata->hil_index < 0))
229  return false;
230 
231  int orig_hil_index = wdata->hil_index;
232 
233  wdata->hil_index = 0;
234  if ((*ARRAY_GET(&wdata->entries, wdata->hil_index))->is_hidden)
235  if (!select_next(wdata))
236  wdata->hil_index = orig_hil_index;
237 
238  return (orig_hil_index != wdata->hil_index);
239 }
240 
246 static bool select_last(struct SidebarWindowData *wdata)
247 {
248  if (ARRAY_EMPTY(&wdata->entries) || (wdata->hil_index < 0))
249  return false;
250 
251  int orig_hil_index = wdata->hil_index;
252 
253  wdata->hil_index = ARRAY_SIZE(&wdata->entries);
254  if (!select_prev(wdata))
255  wdata->hil_index = orig_hil_index;
256 
257  return (orig_hil_index != wdata->hil_index);
258 }
259 
265 void sb_change_mailbox(struct MuttWindow *win, int op)
266 {
267  if (!mutt_window_is_visible(win))
268  return;
269 
270  struct SidebarWindowData *wdata = sb_wdata_get(win);
271  if (!wdata)
272  return;
273 
274  if (wdata->hil_index < 0) /* It'll get reset on the next draw */
275  return;
276 
277  bool changed = false;
278  const bool c_sidebar_next_new_wrap =
279  cs_subset_bool(NeoMutt->sub, "sidebar_next_new_wrap");
280  switch (op)
281  {
282  case OP_SIDEBAR_FIRST:
283  changed = select_first(wdata);
284  break;
285  case OP_SIDEBAR_LAST:
286  changed = select_last(wdata);
287  break;
288  case OP_SIDEBAR_NEXT:
289  changed = select_next(wdata);
290  break;
291  case OP_SIDEBAR_NEXT_NEW:
292  changed = select_next_new(wdata, c_sidebar_next_new_wrap);
293  break;
294  case OP_SIDEBAR_PAGE_DOWN:
295  changed = select_page_down(wdata);
296  break;
297  case OP_SIDEBAR_PAGE_UP:
298  changed = select_page_up(wdata);
299  break;
300  case OP_SIDEBAR_PREV:
301  changed = select_prev(wdata);
302  break;
303  case OP_SIDEBAR_PREV_NEW:
304  changed = select_prev_new(wdata, c_sidebar_next_new_wrap);
305  break;
306  default:
307  return;
308  }
309  if (changed)
310  win->actions |= WA_RECALC;
311 }
prev_new
static struct SbEntry ** prev_new(struct SidebarWindowData *wdata, size_t begin, size_t end)
Return the previous mailbox with new messages.
Definition: functions.c:141
ARRAY_FOREACH_FROM
#define ARRAY_FOREACH_FROM(elem, head, from)
Iterate from an index to the end.
Definition: array.h:217
WA_RECALC
#define WA_RECALC
Recalculate the contents of the Window.
Definition: mutt_window.h:107
MuttWindow
A division of the screen.
Definition: mutt_window.h:115
cs_subset_bool
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:69
sb_wdata_get
struct SidebarWindowData * sb_wdata_get(struct MuttWindow *win)
Get the Sidebar data for this window.
Definition: wdata.c:70
select_first
static bool select_first(struct SidebarWindowData *wdata)
Selects the first unhidden mailbox.
Definition: functions.c:226
private.h
select_next
bool select_next(struct SidebarWindowData *wdata)
Selects the next unhidden mailbox.
Definition: functions.c:44
SidebarWindowData
Sidebar private Window data -.
Definition: private.h:61
ARRAY_IDX
#define ARRAY_IDX(head, elem)
Return the index of an element of the array.
Definition: array.h:253
ARRAY_SIZE
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
select_next_new
static bool select_next_new(struct SidebarWindowData *wdata, bool next_new_wrap)
Selects the next new mailbox.
Definition: functions.c:89
ARRAY_GET
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:105
select_prev
bool select_prev(struct SidebarWindowData *wdata)
Selects the previous unhidden mailbox.
Definition: functions.c:112
SidebarWindowData::top_index
int top_index
First mailbox visible in sidebar.
Definition: private.h:65
sb_change_mailbox
void sb_change_mailbox(struct MuttWindow *win, int op)
Perform a Sidebar function.
Definition: functions.c:265
mutt_window_is_visible
bool mutt_window_is_visible(struct MuttWindow *win)
Is the Window visible?
Definition: mutt_window.c:657
lib.h
lib.h
MuttWindow::actions
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
Definition: mutt_window.h:125
select_last
static bool select_last(struct SidebarWindowData *wdata)
Selects the last unhidden mailbox.
Definition: functions.c:246
select_prev_new
static bool select_prev_new(struct SidebarWindowData *wdata, bool next_new_wrap)
Selects the previous new mailbox.
Definition: functions.c:161
ARRAY_FOREACH_TO
#define ARRAY_FOREACH_TO(elem, head, to)
Iterate from the beginning to an index.
Definition: array.h:228
next_new
static struct SbEntry ** next_new(struct SidebarWindowData *wdata, size_t begin, size_t end)
Return the next mailbox with new messages.
Definition: functions.c:70
select_page_down
static bool select_page_down(struct SidebarWindowData *wdata)
Selects the first entry in the next page of mailboxes.
Definition: functions.c:184
ARRAY_EMPTY
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
select_page_up
static bool select_page_up(struct SidebarWindowData *wdata)
Selects the last entry in the previous page of mailboxes.
Definition: functions.c:205
SidebarWindowData::hil_index
int hil_index
Highlighted mailbox.
Definition: private.h:67
ARRAY_FOREACH_FROM_TO
#define ARRAY_FOREACH_FROM_TO(elem, head, from, to)
Iterate between two indexes.
Definition: array.h:241
SbEntry
Info about folders in the sidebar.
Definition: private.h:38
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
opcodes.h
SidebarWindowData::bot_index
int bot_index
Last mailbox visible in sidebar.
Definition: private.h:68
lib.h
MuttWindow::wdata
void * wdata
Private data.
Definition: mutt_window.h:138