NeoMutt  2020-06-26-89-g172cd3
Teaching an old dog new tricks
DOXYGEN
sidebar.c File Reference

GUI display the mailboxes in a side panel. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "lib.h"
#include "context.h"
#include "format_flags.h"
#include "mutt_globals.h"
#include "mutt_menu.h"
#include "muttlib.h"
+ Include dependency graph for sidebar.c:

Go to the source code of this file.

Functions

static size_t add_indent (char *buf, size_t buflen, const struct SbEntry *sbe)
 Generate the needed indentation. More...
 
static const char * sidebar_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the sidebar - Implements format_t. More...
 
static void make_sidebar_entry (char *buf, size_t buflen, int width, struct SbEntry *sbe)
 Turn mailbox data into a sidebar string. More...
 
static int cb_qsort_sbe (const void *a, const void *b)
 qsort callback to sort SbEntry's More...
 
static void update_entries_visibility (struct SidebarWindowData *wdata)
 Should a SbEntry be displayed in the sidebar? More...
 
static void unsort_entries (struct SidebarWindowData *wdata)
 Restore wdata->entries array order to match Mailbox list order. More...
 
static void sort_entries (struct SidebarWindowData *wdata)
 Sort wdata->entries array. More...
 
static bool prepare_sidebar (struct SidebarWindowData *wdata, int page_size)
 Prepare the list of SbEntry's for the sidebar display. More...
 
static int draw_divider (struct SidebarWindowData *wdata, struct MuttWindow *win, int num_rows, int num_cols)
 Draw a line between the sidebar and the rest of neomutt. More...
 
static void fill_empty_space (struct MuttWindow *win, int first_row, int num_rows, int div_width, int num_cols)
 Wipe the remaining Sidebar space. More...
 
static int imap_is_prefix (const char *folder, const char *mbox)
 Check if folder matches the beginning of mbox. More...
 
static const char * abbrev_folder (const char *mbox, const char *folder, enum MailboxType type)
 Abbreviate a Mailbox path using a folder. More...
 
static const char * abbrev_url (const char *mbox, enum MailboxType type)
 Abbreviate a url-style Mailbox path. More...
 
static int calc_path_depth (const char *mbox, const char *delims, const char **last_part)
 Calculate the depth of a Mailbox path. More...
 
static void draw_sidebar (struct SidebarWindowData *wdata, struct MuttWindow *win, int num_rows, int num_cols, int div_width)
 Write out a list of mailboxes, in a panel. More...
 
struct Mailboxsb_get_highlight (struct MuttWindow *win)
 Get the Mailbox that's highlighted in the sidebar. More...
 
void sb_set_open_mailbox (struct MuttWindow *win, struct Mailbox *m)
 Set the 'open' Mailbox. More...
 
void sb_notify_mailbox (struct MuttWindow *win, struct Mailbox *m, enum SidebarNotification sbn)
 The state of a Mailbox is about to change. More...
 
void sb_draw (struct MuttWindow *win)
 Completely redraw the sidebar. More...
 
void sb_win_init (struct MuttWindow *dlg)
 Initialise and insert the Sidebar Window. More...
 
void sb_win_shutdown (struct MuttWindow *dlg)
 Clean up the Sidebar's observers. More...
 
void sb_init (void)
 Set up the Sidebar. More...
 
void sb_shutdown (void)
 Clean up the Sidebar. More...
 

Variables

struct ListHead SidebarWhitelist = STAILQ_HEAD_INITIALIZER(SidebarWhitelist)
 List of mailboxes to always display in the sidebar. More...
 

Detailed Description

GUI display the mailboxes in a side panel.

Authors
  • Justin Hibbits
  • Thomer M. Gil
  • Richard Russon
  • Kevin J. McCarthy

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file sidebar.c.

Function Documentation

◆ add_indent()

static size_t add_indent ( char *  buf,
size_t  buflen,
const struct SbEntry sbe 
)
static

Generate the needed indentation.

Parameters
bufOutput bufer
buflenSize of output buffer
sbeSidebar entry
Return values
Numberof bytes written

Definition at line 60 of file sidebar.c.

61 {
62  size_t res = 0;
63  for (int i = 0; i < sbe->depth; i++)
64  {
65  res += mutt_str_copy(buf + res, C_SidebarIndentString, buflen - res);
66  }
67  return res;
68 }
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
int depth
Indentation depth.
Definition: private.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sidebar_format_str()

static const char* sidebar_format_str ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
char  op,
const char *  src,
const char *  prec,
const char *  if_str,
const char *  else_str,
intptr_t  data,
MuttFormatFlags  flags 
)
static

Format a string for the sidebar - Implements format_t.

Expando Description
%! 'n!' Flagged messages
%B Name of the mailbox
%D Description of the mailbox
%d Number of deleted messages
%F Number of Flagged messages in the mailbox
%L Number of messages after limiting
%n 'N' if mailbox has new mail, ' ' (space) otherwise
%N Number of unread messages in the mailbox
%o Number of old unread messages in the mailbox
%r Number of read messages in the mailbox
%S Size of mailbox (total number of messages)
%t Number of tagged messages
%Z Number of new unseen messages in the mailbox

Definition at line 89 of file sidebar.c.

93 {
94  struct SbEntry *sbe = (struct SbEntry *) data;
95  char fmt[256];
96 
97  if (!sbe || !buf)
98  return src;
99 
100  buf[0] = '\0'; /* Just in case there's nothing to do */
101 
102  struct Mailbox *m = sbe->mailbox;
103  if (!m)
104  return src;
105 
106  bool c = Context && Context->mailbox &&
108 
109  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
110 
111  switch (op)
112  {
113  case 'B':
114  case 'D':
115  {
116  char indented[256];
117  size_t offset = add_indent(indented, sizeof(indented), sbe);
118  snprintf(indented + offset, sizeof(indented) - offset, "%s",
119  ((op == 'D') && sbe->mailbox->name) ? sbe->mailbox->name : sbe->box);
120 
121  mutt_format_s(buf, buflen, prec, indented);
122  break;
123  }
124 
125  case 'd':
126  if (!optional)
127  {
128  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
129  snprintf(buf, buflen, fmt, c ? Context->mailbox->msg_deleted : 0);
130  }
131  else if ((c && (Context->mailbox->msg_deleted == 0)) || !c)
132  optional = false;
133  break;
134 
135  case 'F':
136  if (!optional)
137  {
138  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
139  snprintf(buf, buflen, fmt, m->msg_flagged);
140  }
141  else if (m->msg_flagged == 0)
142  optional = false;
143  break;
144 
145  case 'L':
146  if (!optional)
147  {
148  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
149  snprintf(buf, buflen, fmt, c ? Context->mailbox->vcount : m->msg_count);
150  }
151  else if ((c && (Context->mailbox->vcount == m->msg_count)) || !c)
152  optional = false;
153  break;
154 
155  case 'N':
156  if (!optional)
157  {
158  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
159  snprintf(buf, buflen, fmt, m->msg_unread);
160  }
161  else if (m->msg_unread == 0)
162  optional = false;
163  break;
164 
165  case 'n':
166  if (!optional)
167  {
168  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
169  snprintf(buf, buflen, fmt, m->has_new ? 'N' : ' ');
170  }
171  else if (m->has_new == false)
172  optional = false;
173  break;
174 
175  case 'o':
176  if (!optional)
177  {
178  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
179  snprintf(buf, buflen, fmt, m->msg_unread - m->msg_new);
180  }
181  else if ((c && (Context->mailbox->msg_unread - Context->mailbox->msg_new) == 0) || !c)
182  optional = false;
183  break;
184 
185  case 'r':
186  if (!optional)
187  {
188  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
189  snprintf(buf, buflen, fmt, m->msg_count - m->msg_unread);
190  }
191  else if ((c && (Context->mailbox->msg_count - Context->mailbox->msg_unread) == 0) || !c)
192  optional = false;
193  break;
194 
195  case 'S':
196  if (!optional)
197  {
198  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
199  snprintf(buf, buflen, fmt, m->msg_count);
200  }
201  else if (m->msg_count == 0)
202  optional = false;
203  break;
204 
205  case 't':
206  if (!optional)
207  {
208  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
209  snprintf(buf, buflen, fmt, c ? Context->mailbox->msg_tagged : 0);
210  }
211  else if ((c && (Context->mailbox->msg_tagged == 0)) || !c)
212  optional = false;
213  break;
214 
215  case 'Z':
216  if (!optional)
217  {
218  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
219  snprintf(buf, buflen, fmt, m->msg_new);
220  }
221  else if ((c && (Context->mailbox->msg_new) == 0) || !c)
222  optional = false;
223  break;
224 
225  case '!':
226  if (m->msg_flagged == 0)
227  mutt_format_s(buf, buflen, prec, "");
228  else if (m->msg_flagged == 1)
229  mutt_format_s(buf, buflen, prec, "!");
230  else if (m->msg_flagged == 2)
231  mutt_format_s(buf, buflen, prec, "!!");
232  else
233  {
234  snprintf(fmt, sizeof(fmt), "%d!", m->msg_flagged);
235  mutt_format_s(buf, buflen, prec, fmt);
236  }
237  break;
238  }
239 
240  if (optional)
241  {
242  mutt_expando_format(buf, buflen, col, C_SidebarWidth, if_str,
243  sidebar_format_str, IP sbe, flags);
244  }
245  else if (flags & MUTT_FORMAT_OPTIONAL)
246  {
247  mutt_expando_format(buf, buflen, col, C_SidebarWidth, else_str,
248  sidebar_format_str, IP sbe, flags);
249  }
250 
251  /* We return the format string, unchanged */
252  return src;
253 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
The "current" mailbox.
Definition: context.h:37
int msg_count
Total number of messages.
Definition: mailbox.h:91
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
static int const char * fmt
Definition: acutest.h:488
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Info about folders in the sidebar.
Definition: private.h:36
int vcount
The number of virtual messages.
Definition: mailbox.h:102
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:40
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:772
struct Mailbox * mailbox
Definition: context.h:50
int flags
e.g. MB_NORMAL
Definition: mailbox.h:134
char box[256]
Mailbox path (possibly abbreviated)
Definition: private.h:38
A mailbox.
Definition: mailbox.h:81
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:97
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1241
int msg_new
Number of new messages.
Definition: mailbox.h:95
#define IP
Definition: set.h:54
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_sidebar_entry()

static void make_sidebar_entry ( char *  buf,
size_t  buflen,
int  width,
struct SbEntry sbe 
)
static

Turn mailbox data into a sidebar string.

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]widthDesired width in screen cells
[in]sbeMailbox object

Take all the relevant mailbox data and the desired screen width and then get mutt_expando_format to do the actual work. mutt_expando_format will callback to us using sidebar_format_str() for the sidebar specific formatting characters.

Definition at line 266 of file sidebar.c.

267 {
268  mutt_expando_format(buf, buflen, 0, width, NONULL(C_SidebarFormat),
270 
271  /* Force string to be exactly the right width */
272  int w = mutt_strwidth(buf);
273  int s = mutt_str_len(buf);
274  width = MIN(buflen, width);
275  if (w < width)
276  {
277  /* Pad with spaces */
278  memset(buf + s, ' ', width - w);
279  buf[s + width - w] = '\0';
280  }
281  else if (w > width)
282  {
283  /* Truncate to fit */
284  size_t len = mutt_wstr_trunc(buf, buflen, width, NULL);
285  buf[len] = '\0';
286  }
287 }
#define NONULL(x)
Definition: string2.h:37
#define MIN(a, b)
Definition: memory.h:31
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:772
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1356
size_t mutt_wstr_trunc(const char *src, size_t maxlen, size_t maxwid, size_t *width)
Work out how to truncate a widechar string.
Definition: curs_lib.c:1306
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
#define IP
Definition: set.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cb_qsort_sbe()

static int cb_qsort_sbe ( const void *  a,
const void *  b 
)
static

qsort callback to sort SbEntry's

Parameters
aFirst SbEntry to compare
bSecond SbEntry to compare
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 297 of file sidebar.c.

298 {
299  const struct SbEntry *sbe1 = *(struct SbEntry const *const *) a;
300  const struct SbEntry *sbe2 = *(struct SbEntry const *const *) b;
301  const struct Mailbox *m1 = sbe1->mailbox;
302  const struct Mailbox *m2 = sbe2->mailbox;
303 
304  int rc = 0;
305 
306  switch ((C_SidebarSortMethod & SORT_MASK))
307  {
308  case SORT_COUNT:
309  if (m2->msg_count == m1->msg_count)
310  rc = mutt_str_coll(mailbox_path(m1), mailbox_path(m2));
311  else
312  rc = (m2->msg_count - m1->msg_count);
313  break;
314  case SORT_UNREAD:
315  if (m2->msg_unread == m1->msg_unread)
316  rc = mutt_str_coll(mailbox_path(m1), mailbox_path(m2));
317  else
318  rc = (m2->msg_unread - m1->msg_unread);
319  break;
320  case SORT_DESC:
321  rc = mutt_str_cmp(m1->name, m2->name);
322  break;
323  case SORT_FLAGGED:
324  if (m2->msg_flagged == m1->msg_flagged)
325  rc = mutt_str_coll(mailbox_path(m1), mailbox_path(m2));
326  else
327  rc = (m2->msg_flagged - m1->msg_flagged);
328  break;
329  case SORT_PATH:
330  {
332  if (rc == 0)
333  rc = mutt_str_coll(mailbox_path(m1), mailbox_path(m2));
334  break;
335  }
336  }
337 
339  rc = -rc;
340 
341  return rc;
342 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:196
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:572
int msg_count
Total number of messages.
Definition: mailbox.h:91
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
Sort by the number of flagged emails.
Definition: sort2.h:67
Sort by the folder&#39;s path.
Definition: sort2.h:68
Info about folders in the sidebar.
Definition: private.h:36
int mutt_str_coll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:649
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:40
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
A mailbox.
Definition: mailbox.h:81
int mutt_inbox_cmp(const char *a, const char *b)
do two folders share the same path and one is an inbox
Definition: muttlib.c:1593
Sort by the number of unread emails.
Definition: sort2.h:66
Sort by the folder&#39;s description.
Definition: sort2.h:70
Sort by number of emails in a folder.
Definition: sort2.h:65
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_entries_visibility()

static void update_entries_visibility ( struct SidebarWindowData wdata)
static

Should a SbEntry be displayed in the sidebar?

For each SbEntry in the entries array, check whether we should display it. This is determined by several criteria. If the Mailbox:

  • is the currently open mailbox
  • is the currently highlighted mailbox
  • has unread messages
  • has flagged messages
  • is whitelisted

Definition at line 355 of file sidebar.c.

356 {
357  /* Aliases for readability */
358  const bool new_only = C_SidebarNewMailOnly;
359  const bool non_empty_only = C_SidebarNonEmptyMailboxOnly;
360  struct SbEntry *sbe = NULL;
361 
362  /* Take the fast path if there is no need to test visibilities */
363  if (!new_only && !non_empty_only)
364  {
365  for (int i = 0; i < wdata->entry_count; i++)
366  {
367  wdata->entries[i]->is_hidden = false;
368  }
369  return;
370  }
371 
372  for (int i = 0; i < wdata->entry_count; i++)
373  {
374  sbe = wdata->entries[i];
375 
376  sbe->is_hidden = false;
377 
379  {
380  /* Spool directories are always visible */
381  continue;
382  }
383 
386  {
387  /* Explicitly asked to be visible */
388  continue;
389  }
390 
391  if (non_empty_only && (i != wdata->opn_index) && (sbe->mailbox->msg_count == 0))
392  {
393  sbe->is_hidden = true;
394  }
395 
396  if (new_only && (i != wdata->opn_index) && (sbe->mailbox->msg_unread == 0) &&
397  (sbe->mailbox->msg_flagged == 0) && !sbe->mailbox->has_new)
398  {
399  sbe->is_hidden = true;
400  }
401  }
402 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:196
int msg_count
Total number of messages.
Definition: mailbox.h:91
int opn_index
Current (open) mailbox.
Definition: private.h:65
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Info about folders in the sidebar.
Definition: private.h:36
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: private.h:41
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:40
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
struct Mailbox * mailbox
Definition: context.h:50
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:102
int entry_count
Number of items in entries.
Definition: private.h:61
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ unsort_entries()

static void unsort_entries ( struct SidebarWindowData wdata)
static

Restore wdata->entries array order to match Mailbox list order.

Definition at line 407 of file sidebar.c.

408 {
409  int i = 0;
410 
411  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
413  struct MailboxNode *np = NULL;
414  STAILQ_FOREACH(np, &ml, entries)
415  {
416  if (i >= wdata->entry_count)
417  break;
418 
419  int j = i;
420  while ((j < wdata->entry_count) && (wdata->entries[j]->mailbox != np->mailbox))
421  j++;
422  if (j < wdata->entry_count)
423  {
424  if (j != i)
425  {
426  struct SbEntry *tmp = wdata->entries[i];
427  wdata->entries[i] = wdata->entries[j];
428  wdata->entries[j] = tmp;
429  }
430  i++;
431  }
432  }
434 }
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:160
Info about folders in the sidebar.
Definition: private.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:40
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
int entry_count
Number of items in entries.
Definition: private.h:61
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
List of Mailboxes.
Definition: mailbox.h:145
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sort_entries()

static void sort_entries ( struct SidebarWindowData wdata)
static

Sort wdata->entries array.

Sort the wdata->entries array according to the current sort config option "sidebar_sort_method". This calls qsort to do the work which calls our callback function "cb_qsort_sbe".

Once sorted, the prev/next links will be reconstructed.

Definition at line 445 of file sidebar.c.

446 {
447  enum SortType ssm = (C_SidebarSortMethod & SORT_MASK);
448 
449  /* These are the only sort methods we understand */
450  if ((ssm == SORT_COUNT) || (ssm == SORT_UNREAD) || (ssm == SORT_FLAGGED) || (ssm == SORT_PATH))
451  qsort(wdata->entries, wdata->entry_count, sizeof(*wdata->entries), cb_qsort_sbe);
452  else if ((ssm == SORT_ORDER) && (C_SidebarSortMethod != wdata->previous_sort))
453  unsort_entries(wdata);
454 }
SortType
Methods for sorting.
Definition: sort2.h:48
Sort by the number of flagged emails.
Definition: sort2.h:67
Sort by the folder&#39;s path.
Definition: sort2.h:68
short previous_sort
sidebar_sort_method
Definition: private.h:69
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
int entry_count
Number of items in entries.
Definition: private.h:61
Sort by the number of unread emails.
Definition: sort2.h:66
Sort by number of emails in a folder.
Definition: sort2.h:65
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ prepare_sidebar()

static bool prepare_sidebar ( struct SidebarWindowData wdata,
int  page_size 
)
static

Prepare the list of SbEntry's for the sidebar display.

Parameters
wdataSidebar data
page_sizeNumber of lines on a page
Return values
falseNo, don't draw the sidebar
trueYes, draw the sidebar

Before painting the sidebar, we determine which are visible, sort them and set up our page pointers.

This is a lot of work to do each refresh, but there are many things that can change outside of the sidebar that we don't hear about.

Definition at line 469 of file sidebar.c.

470 {
471  if ((wdata->entry_count == 0) || (page_size <= 0))
472  return false;
473 
474  const struct SbEntry *opn_entry =
475  (wdata->opn_index >= 0) ? wdata->entries[wdata->opn_index] : NULL;
476  const struct SbEntry *hil_entry =
477  (wdata->hil_index >= 0) ? wdata->entries[wdata->hil_index] : NULL;
478 
480  sort_entries(wdata);
481 
482  for (int i = 0; i < wdata->entry_count; i++)
483  {
484  if (opn_entry == wdata->entries[i])
485  wdata->opn_index = i;
486  if (hil_entry == wdata->entries[i])
487  wdata->hil_index = i;
488  }
489 
490  if ((wdata->hil_index < 0) || wdata->entries[wdata->hil_index]->is_hidden ||
492  {
493  if (wdata->opn_index >= 0)
494  wdata->hil_index = wdata->opn_index;
495  else
496  {
497  wdata->hil_index = 0;
498  if (wdata->entries[wdata->hil_index]->is_hidden)
499  select_next(wdata);
500  }
501  }
502 
503  /* Set the Top and Bottom to frame the wdata->hil_index in groups of page_size */
504 
505  /* If C_SidebarNewMailOnly or C_SidebarNonEmptyMailboxOnly is set, some entries
506  * may be hidden so we need to scan for the framing interval */
508  {
509  wdata->top_index = -1;
510  wdata->bot_index = -1;
511  while (wdata->bot_index < wdata->hil_index)
512  {
513  wdata->top_index = wdata->bot_index + 1;
514  int page_entries = 0;
515  while (page_entries < page_size)
516  {
517  wdata->bot_index++;
518  if (wdata->bot_index >= wdata->entry_count)
519  break;
520  if (!wdata->entries[wdata->bot_index]->is_hidden)
521  page_entries++;
522  }
523  }
524  }
525  /* Otherwise we can just calculate the interval */
526  else
527  {
528  wdata->top_index = (wdata->hil_index / page_size) * page_size;
529  wdata->bot_index = wdata->top_index + page_size - 1;
530  }
531 
532  if (wdata->bot_index > (wdata->entry_count - 1))
533  wdata->bot_index = wdata->entry_count - 1;
534 
536  return true;
537 }
int opn_index
Current (open) mailbox.
Definition: private.h:65
int top_index
First mailbox visible in sidebar.
Definition: private.h:64
Info about folders in the sidebar.
Definition: private.h:36
int hil_index
Highlighted mailbox.
Definition: private.h:66
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: private.h:41
short previous_sort
sidebar_sort_method
Definition: private.h:69
int entry_count
Number of items in entries.
Definition: private.h:61
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
int bot_index
Last mailbox visible in sidebar.
Definition: private.h:67
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_divider()

static int draw_divider ( struct SidebarWindowData wdata,
struct MuttWindow win,
int  num_rows,
int  num_cols 
)
static

Draw a line between the sidebar and the rest of neomutt.

Parameters
wdataSidebar data
winWindow to draw on
num_rowsHeight of the Sidebar
num_colsWidth of the Sidebar
Return values
0Empty string
numCharacter occupies n screen columns

Draw a divider using characters from the config option "sidebar_divider_char". This can be an ASCII or Unicode character. We calculate these characters' width in screen columns.

If the user hasn't set $sidebar_divider_char we pick a character for them, respecting the value of $ascii_chars.

Definition at line 555 of file sidebar.c.

557 {
558  if ((num_rows < 1) || (num_cols < 1))
559  return 0;
560 
561  enum DivType altchar = SB_DIV_UTF8;
562 
563  /* Calculate the width of the delimiter in screen cells */
565  if (wdata->divider_width < 0)
566  {
567  wdata->divider_width = 1; /* Bad character */
568  }
569  else if (wdata->divider_width == 0)
570  {
572  return 0; /* User has set empty string */
573 
574  wdata->divider_width = 1; /* Unset variable */
575  }
576  else
577  {
578  altchar = SB_DIV_USER; /* User config */
579  }
580 
581  if (C_AsciiChars && (altchar != SB_DIV_ASCII))
582  {
583  /* $ascii_chars overrides Unicode divider chars */
584  if (altchar == SB_DIV_UTF8)
585  {
586  altchar = SB_DIV_ASCII;
587  }
588  else if (C_SidebarDividerChar)
589  {
590  for (int i = 0; i < wdata->divider_width; i++)
591  {
592  if (C_SidebarDividerChar[i] & ~0x7F) /* high-bit is set */
593  {
594  altchar = SB_DIV_ASCII;
595  wdata->divider_width = 1;
596  break;
597  }
598  }
599  }
600  }
601 
602  if (wdata->divider_width > num_cols)
603  return 0;
604 
606 
607  int col = C_SidebarOnRight ? 0 : (C_SidebarWidth - wdata->divider_width);
608 
609  for (int i = 0; i < num_rows; i++)
610  {
611  mutt_window_move(win, col, i);
612 
613  switch (altchar)
614  {
615  case SB_DIV_USER:
617  break;
618  case SB_DIV_ASCII:
619  mutt_window_addch('|');
620  break;
621  case SB_DIV_UTF8:
622  mutt_window_addch(ACS_VLINE);
623  break;
624  }
625  }
626 
627  return wdata->divider_width;
628 }
#define NONULL(x)
Definition: string2.h:37
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
Line dividing sidebar from the index/pager.
Definition: color.h:84
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:362
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1356
WHERE bool C_AsciiChars
Config: Use plain ASCII characters, when drawing email threads.
Definition: mutt_globals.h:137
short divider_width
Width of the divider in screen columns.
Definition: private.h:71
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:488
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:518
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fill_empty_space()

static void fill_empty_space ( struct MuttWindow win,
int  first_row,
int  num_rows,
int  div_width,
int  num_cols 
)
static

Wipe the remaining Sidebar space.

Parameters
winWindow to draw on
first_rowWindow line to start (0-based)
num_rowsNumber of rows to fill
div_widthWidth in screen characters taken by the divider
num_colsNumber of columns to fill

Write spaces over the area the sidebar isn't using.

Definition at line 640 of file sidebar.c.

642 {
643  /* Fill the remaining rows with blank space */
645 
646  if (!C_SidebarOnRight)
647  div_width = 0;
648  for (int r = 0; r < num_rows; r++)
649  {
650  mutt_window_move(win, div_width, first_row + r);
651 
652  for (int i = 0; i < num_cols; i++)
653  mutt_window_addch(' ');
654  }
655 }
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:362
Plain text.
Definition: color.h:77
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:488
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_is_prefix()

static int imap_is_prefix ( const char *  folder,
const char *  mbox 
)
static

Check if folder matches the beginning of mbox.

Parameters
folderFolder
mboxMailbox path
Return values
numLength of the prefix

Definition at line 663 of file sidebar.c.

664 {
665  int plen = 0;
666 
667  struct Url *url_m = url_parse(mbox);
668  struct Url *url_f = url_parse(folder);
669  if (!url_m || !url_f)
670  goto done;
671 
672  if (!mutt_istr_equal(url_m->host, url_f->host))
673  goto done;
674 
675  if (url_m->user && url_f->user && !mutt_istr_equal(url_m->user, url_f->user))
676  goto done;
677 
678  size_t mlen = mutt_str_len(url_m->path);
679  size_t flen = mutt_str_len(url_f->path);
680  if (flen > mlen)
681  goto done;
682 
683  if (!mutt_strn_equal(url_m->path, url_f->path, flen))
684  goto done;
685 
686  plen = strlen(mbox) - mlen + flen;
687 
688 done:
689  url_free(&url_m);
690  url_free(&url_f);
691 
692  return plen;
693 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
char * user
Username.
Definition: url.h:69
char * host
Host.
Definition: url.h:71
char * path
Path.
Definition: url.h:73
bool mutt_strn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:598
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ abbrev_folder()

static const char* abbrev_folder ( const char *  mbox,
const char *  folder,
enum MailboxType  type 
)
static

Abbreviate a Mailbox path using a folder.

Parameters
mboxMailbox path to shorten
folderFolder path to use
typeMailbox type
Return values
ptrPointer into the mbox param

Definition at line 702 of file sidebar.c.

703 {
704  if (!mbox || !folder)
705  return NULL;
706 
707  if (type == MUTT_IMAP)
708  {
709  int prefix = imap_is_prefix(folder, mbox);
710  if (prefix == 0)
711  return NULL;
712  return mbox + prefix;
713  }
714 
715  if (!C_SidebarDelimChars)
716  return NULL;
717 
718  size_t flen = mutt_str_len(folder);
719  if (flen == 0)
720  return NULL;
721  if (strchr(C_SidebarDelimChars, folder[flen - 1])) // folder ends with a delimiter
722  flen--;
723 
724  size_t mlen = mutt_str_len(mbox);
725  if (mlen <= flen)
726  return NULL;
727 
728  if (!mutt_strn_equal(folder, mbox, flen))
729  return NULL;
730 
731  // After the match, check that mbox has a delimiter
732  if (!strchr(C_SidebarDelimChars, mbox[flen]))
733  return NULL;
734 
735  return mbox + flen + 1;
736 }
bool mutt_strn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:598
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ abbrev_url()

static const char* abbrev_url ( const char *  mbox,
enum MailboxType  type 
)
static

Abbreviate a url-style Mailbox path.

Parameters
mboxMailbox path to shorten
typeMailbox type

Use heuristics to shorten a non-local Mailbox path. Strip the host part (or database part for Notmuch).

e.g.

  • imap://user@host.com/apple/banana becomes apple/banana
  • notmuch:///home/user/db?query=hello becomes query=hello

Definition at line 750 of file sidebar.c.

751 {
752  /* This is large enough to skip `notmuch://`,
753  * but not so large that it will go past the host part. */
754  const int scheme_len = 10;
755 
756  size_t len = mutt_str_len(mbox);
757  if ((len < scheme_len) || ((type != MUTT_NNTP) && (type != MUTT_IMAP) &&
758  (type != MUTT_NOTMUCH) && (type != MUTT_POP)))
759  {
760  return mbox;
761  }
762 
763  const char split = (type == MUTT_NOTMUCH) ? '?' : '/';
764 
765  // Skip over the scheme, e.g. `imaps://`, `notmuch://`
766  const char *last = strchr(mbox + scheme_len, split);
767  if (last)
768  mbox = last + 1;
769  return mbox;
770 }
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_path_depth()

static int calc_path_depth ( const char *  mbox,
const char *  delims,
const char **  last_part 
)
static

Calculate the depth of a Mailbox path.

Parameters
[in]mboxMailbox path to examine
[in]delimsDelimiter characters
[out]last_partLast path component

Definition at line 778 of file sidebar.c.

779 {
780  if (!mbox || !delims || !last_part)
781  return 0;
782 
783  int depth = 0;
784  const char *match = NULL;
785  while ((match = strpbrk(mbox, delims)))
786  {
787  depth++;
788  mbox = match + 1;
789  }
790 
791  *last_part = mbox;
792  return depth;
793 }
+ Here is the caller graph for this function:

◆ draw_sidebar()

static void draw_sidebar ( struct SidebarWindowData wdata,
struct MuttWindow win,
int  num_rows,
int  num_cols,
int  div_width 
)
static

Write out a list of mailboxes, in a panel.

Parameters
wdataSidebar data
winWindow to draw on
num_rowsHeight of the Sidebar
num_colsWidth of the Sidebar
div_widthWidth in screen characters taken by the divider

Display a list of mailboxes in a panel on the left. What's displayed will depend on our index markers: TopMailbox, OpnMailbox, HilMailbox, BotMailbox. On the first run they'll be NULL, so we display the top of NeoMutt's list.

  • TopMailbox - first visible mailbox
  • BotMailbox - last visible mailbox
  • OpnMailbox - mailbox shown in NeoMutt's Index Panel
  • HilMailbox - Unselected mailbox (the paging follows this)

The entries are formatted using "sidebar_format" and may be abbreviated: "sidebar_short_path", indented: "sidebar_folder_indent", "sidebar_indent_string" and sorted: "sidebar_sort_method". Finally, they're trimmed to fit the available space.

Definition at line 817 of file sidebar.c.

819 {
820  struct SbEntry *entry = NULL;
821  struct Mailbox *m = NULL;
822  if (wdata->top_index < 0)
823  return;
824 
825  int w = MIN(num_cols, (C_SidebarWidth - div_width));
826  int row = 0;
827  for (int entryidx = wdata->top_index;
828  (entryidx < wdata->entry_count) && (row < num_rows); entryidx++)
829  {
830  entry = wdata->entries[entryidx];
831  if (entry->is_hidden)
832  continue;
833  m = entry->mailbox;
834 
835  if (entryidx == wdata->opn_index)
836  {
839  else
841  }
842  else if (entryidx == wdata->hil_index)
844  else if (m->has_new)
846  else if (m->msg_unread > 0)
848  else if (m->msg_flagged > 0)
850  else if ((Colors->defs[MT_COLOR_SIDEBAR_SPOOLFILE] != 0) &&
852  {
854  }
855  else
856  {
859  else
861  }
862 
863  int col = 0;
864  if (C_SidebarOnRight)
865  col = div_width;
866 
867  mutt_window_move(win, col, row);
868  if (Context && Context->mailbox && (Context->mailbox->realpath[0] != '\0') &&
870  {
874  }
875 
876  const char *path = mailbox_path(m);
877 
878  // Try to abbreviate the full path
879  const char *abbr = abbrev_folder(path, C_Folder, m->type);
880  if (!abbr)
881  abbr = abbrev_url(path, m->type);
882  const char *short_path = abbr ? abbr : path;
883 
884  /* Compute the depth */
885  const char *last_part = abbr;
886  entry->depth = calc_path_depth(abbr, C_SidebarDelimChars, &last_part);
887 
888  const bool short_path_is_abbr = (short_path == abbr);
889  if (C_SidebarShortPath)
890  {
891  short_path = last_part;
892  }
893 
894  // Don't indent if we were unable to create an abbreviation.
895  // Otherwise, the full path will be indent, and it looks unusual.
896  if (C_SidebarFolderIndent && short_path_is_abbr)
897  {
898  if (C_SidebarComponentDepth > 0)
899  entry->depth -= C_SidebarComponentDepth;
900  }
901  else if (!C_SidebarFolderIndent)
902  entry->depth = 0;
903 
904  mutt_str_copy(entry->box, short_path, sizeof(entry->box));
905  char str[256];
906  make_sidebar_entry(str, sizeof(str), w, entry);
907  mutt_window_printf("%s", str);
908  row++;
909  }
910 
911  fill_empty_space(win, row, num_rows - row, div_width, w);
912 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:196
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
int msg_count
Total number of messages.
Definition: mailbox.h:91
int opn_index
Current (open) mailbox.
Definition: private.h:65
#define MIN(a, b)
Definition: memory.h:31
int top_index
First mailbox visible in sidebar.
Definition: private.h:64
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
Mailbox with no new or flagged messages.
Definition: color.h:89
int * defs
Array of all fixed colours, see enum ColorId.
Definition: color.h:131
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Select cursor.
Definition: color.h:86
Info about folders in the sidebar.
Definition: private.h:36
int hil_index
Highlighted mailbox.
Definition: private.h:66
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: private.h:41
Mailbox with new mail.
Definition: color.h:88
Current open mailbox.
Definition: color.h:87
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:362
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:40
struct Mailbox * mailbox
Definition: context.h:50
Plain text.
Definition: color.h:77
char box[256]
Mailbox path (possibly abbreviated)
Definition: private.h:38
A mailbox.
Definition: mailbox.h:81
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: mutt_globals.h:99
Selected item in list.
Definition: color.h:73
Definition: color.h:129
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:546
WHERE char * C_Spoolfile
Config: Inbox.
Definition: mutt_globals.h:111
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
int depth
Indentation depth.
Definition: private.h:39
Mailbox with unread mail.
Definition: color.h:91
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
Mailbox with flagged messages.
Definition: color.h:85
$spoolfile (Spool mailbox)
Definition: color.h:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_get_highlight()

struct Mailbox* sb_get_highlight ( struct MuttWindow win)

Get the Mailbox that's highlighted in the sidebar.

Return values
ptrMailbox

Definition at line 918 of file sidebar.c.

919 {
920  if (!C_SidebarVisible)
921  return NULL;
922 
923  struct SidebarWindowData *wdata = sb_wdata_get(win);
924  if ((wdata->entry_count == 0) || (wdata->hil_index < 0))
925  return NULL;
926 
927  return wdata->entries[wdata->hil_index]->mailbox;
928 }
Sidebar private Window data -.
Definition: private.h:58
int hil_index
Highlighted mailbox.
Definition: private.h:66
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:40
int entry_count
Number of items in entries.
Definition: private.h:61
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
void * wdata
Private data.
Definition: mutt_window.h:133
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_set_open_mailbox()

void sb_set_open_mailbox ( struct MuttWindow win,
struct Mailbox m 
)

Set the 'open' Mailbox.

Parameters
winSidebar Window
mMailbox

Search through the list of mailboxes. If a Mailbox has a matching path, set OpnMailbox to it.

Definition at line 938 of file sidebar.c.

939 {
940  struct SidebarWindowData *wdata = sb_wdata_get(win);
941 
942  wdata->opn_index = -1;
943 
944  if (!m)
945  return;
946 
947  for (int entry = 0; entry < wdata->entry_count; entry++)
948  {
949  if (mutt_str_equal(wdata->entries[entry]->mailbox->realpath, m->realpath))
950  {
951  wdata->opn_index = entry;
952  wdata->hil_index = entry;
953  break;
954  }
955  }
956 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
int opn_index
Current (open) mailbox.
Definition: private.h:65
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Sidebar private Window data -.
Definition: private.h:58
int hil_index
Highlighted mailbox.
Definition: private.h:66
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:40
int entry_count
Number of items in entries.
Definition: private.h:61
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
void * wdata
Private data.
Definition: mutt_window.h:133
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_notify_mailbox()

void sb_notify_mailbox ( struct MuttWindow win,
struct Mailbox m,
enum SidebarNotification  sbn 
)

The state of a Mailbox is about to change.

Parameters
winSidebar Window
mFolder
sbnWhat happened to the mailbox

We receive a notification:

Before a deletion, check that our pointers won't be invalidated.

Definition at line 971 of file sidebar.c.

972 {
973  if (!m)
974  return;
975 
976  struct SidebarWindowData *wdata = sb_wdata_get(win);
977  /* Any new/deleted mailboxes will cause a refresh. As long as
978  * they're valid, our pointers will be updated in prepare_sidebar() */
979 
980  if (sbn == SBN_CREATED)
981  {
982  if (wdata->entry_count >= wdata->entry_max)
983  {
984  wdata->entry_max += 10;
985  mutt_mem_realloc(&wdata->entries, wdata->entry_max * sizeof(struct SbEntry *));
986  }
987  wdata->entries[wdata->entry_count] = mutt_mem_calloc(1, sizeof(struct SbEntry));
988  wdata->entries[wdata->entry_count]->mailbox = m;
989 
990  if (wdata->top_index < 0)
991  wdata->top_index = wdata->entry_count;
992  if (wdata->bot_index < 0)
993  wdata->bot_index = wdata->entry_count;
994  if ((wdata->opn_index < 0) && Context &&
996  {
997  wdata->opn_index = wdata->entry_count;
998  }
999 
1000  wdata->entry_count++;
1001  }
1002  else if (sbn == SBN_DELETED)
1003  {
1004  int del_index;
1005  for (del_index = 0; del_index < wdata->entry_count; del_index++)
1006  if (wdata->entries[del_index]->mailbox == m)
1007  break;
1008  if (del_index == wdata->entry_count)
1009  return;
1010  FREE(&wdata->entries[del_index]);
1011  wdata->entry_count--;
1012 
1013  if ((wdata->top_index > del_index) || (wdata->top_index == wdata->entry_count))
1014  wdata->top_index--;
1015  if (wdata->opn_index == del_index)
1016  wdata->opn_index = -1;
1017  else if (wdata->opn_index > del_index)
1018  wdata->opn_index--;
1019  if ((wdata->hil_index > del_index) || (wdata->hil_index == wdata->entry_count))
1020  wdata->hil_index--;
1021  if ((wdata->bot_index > del_index) || (wdata->bot_index == wdata->entry_count))
1022  wdata->bot_index--;
1023 
1024  for (; del_index < wdata->entry_count; del_index++)
1025  wdata->entries[del_index] = wdata->entries[del_index + 1];
1026  }
1027 
1028  // otherwise, we just need to redraw
1029 
1031 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
The "current" mailbox.
Definition: context.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
int opn_index
Current (open) mailbox.
Definition: private.h:65
int top_index
First mailbox visible in sidebar.
Definition: private.h:64
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Sidebar private Window data -.
Definition: private.h:58
Info about folders in the sidebar.
Definition: private.h:36
int hil_index
Highlighted mailbox.
Definition: private.h:66
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:49
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:40
struct Mailbox * mailbox
Definition: context.h:50
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
int entry_max
Size of the entries array.
Definition: private.h:62
int entry_count
Number of items in entries.
Definition: private.h:61
#define FREE(x)
Definition: memory.h:40
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
int bot_index
Last mailbox visible in sidebar.
Definition: private.h:67
void * wdata
Private data.
Definition: mutt_window.h:133
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_draw()

void sb_draw ( struct MuttWindow win)

Completely redraw the sidebar.

Parameters
winWindow to draw on

Completely refresh the sidebar region. First draw the divider; then, for each Mailbox, call make_sidebar_entry; finally blank out any remaining space.

Definition at line 1040 of file sidebar.c.

1041 {
1042  if (!C_SidebarVisible || !win)
1043  return;
1044 
1045  if (!mutt_window_is_visible(win))
1046  return;
1047 
1048  struct SidebarWindowData *wdata = sb_wdata_get(win);
1049 
1050  int col = 0, row = 0;
1051  mutt_window_get_coords(win, &col, &row);
1052 
1053  int num_rows = win->state.rows;
1054  int num_cols = win->state.cols;
1055 
1056  draw_divider(wdata, win, num_rows, num_cols);
1057 
1058  if (!wdata->entries)
1059  {
1060  struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
1062  struct MailboxNode *np = NULL;
1063  STAILQ_FOREACH(np, &ml, entries)
1064  {
1065  if (!(np->mailbox->flags & MB_HIDDEN))
1067  }
1069  }
1070 
1071  if (!prepare_sidebar(wdata, num_rows))
1072  {
1073  fill_empty_space(win, 0, num_rows, wdata->divider_width, num_cols - wdata->divider_width);
1074  return;
1075  }
1076 
1077  draw_sidebar(wdata, win, num_rows, num_cols, wdata->divider_width);
1078  mutt_window_move(win, col, row);
1079 }
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:137
Match any Mailbox type.
Definition: mailbox.h:45
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:160
Sidebar private Window data -.
Definition: private.h:58
Container for Accounts, Notifications.
Definition: neomutt.h:36
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:362
int flags
e.g. MB_NORMAL
Definition: mailbox.h:134
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
void mutt_window_get_coords(struct MuttWindow *win, int *col, int *row)
Get the cursor position in the Window.
Definition: mutt_window.c:302
#define MB_HIDDEN
Definition: mailbox.h:38
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:119
bool mutt_window_is_visible(struct MuttWindow *win)
Is the Window visible?
Definition: mutt_window.c:653
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
short divider_width
Width of the divider in screen columns.
Definition: private.h:71
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
List of Mailboxes.
Definition: mailbox.h:145
struct SbEntry ** entries
Items to display in the sidebar.
Definition: private.h:60
void * wdata
Private data.
Definition: mutt_window.h:133
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_win_init()

void sb_win_init ( struct MuttWindow dlg)

Initialise and insert the Sidebar Window.

Parameters
dlgIndex Dialog

Definition at line 1085 of file sidebar.c.

1086 {
1088 
1089  struct MuttWindow *index_panel = TAILQ_FIRST(&dlg->children);
1090  mutt_window_remove_child(dlg, index_panel);
1091 
1092  struct MuttWindow *pager_panel = TAILQ_FIRST(&dlg->children);
1093  mutt_window_remove_child(dlg, pager_panel);
1094 
1095  struct MuttWindow *cont_right =
1098 
1099  mutt_window_add_child(cont_right, index_panel);
1100  mutt_window_add_child(cont_right, pager_panel);
1101 
1102  struct MuttWindow *win_sidebar =
1105  win_sidebar->state.visible = C_SidebarVisible && (C_SidebarWidth > 0);
1106  win_sidebar->wdata = sb_wdata_new();
1107  win_sidebar->wdata_free = sb_wdata_free;
1108 
1109  if (C_SidebarOnRight)
1110  {
1111  mutt_window_add_child(dlg, cont_right);
1112  mutt_window_add_child(dlg, win_sidebar);
1113  }
1114  else
1115  {
1116  mutt_window_add_child(dlg, win_sidebar);
1117  mutt_window_add_child(dlg, cont_right);
1118  }
1119 
1121 }
struct MuttWindow * mutt_window_remove_child(struct MuttWindow *parent, struct MuttWindow *child)
Remove a child from a Window.
Definition: mutt_window.c:580
enum MuttWindowOrientation orient
Which direction the Window will expand.
Definition: mutt_window.h:122
#define TAILQ_FIRST(head)
Definition: queue.h:716
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Callback function to free private data.
Definition: mutt_window.h:134
Window uses all available vertical space.
Definition: mutt_window.h:35
Invisible shaping container Window.
Definition: mutt_window.h:70
A division of the screen.
Definition: mutt_window.h:114
Container for Accounts, Notifications.
Definition: neomutt.h:36
Window has a fixed size.
Definition: mutt_window.h:44
Side panel containing Accounts or groups of data.
Definition: mutt_window.h:98
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:119
bool visible
Window is visible.
Definition: mutt_window.h:56
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:49
int sb_observer(struct NotifyCallback *nc)
Listen for config changes affecting the sidebar - Implements observer_t.
Definition: observer.c:43
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
bool notify_observer_add(struct Notify *notify, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:153
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:561
Window uses all available horizontal space.
Definition: mutt_window.h:36
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:128
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:131
Window wants as much space as possible.
Definition: mutt_window.h:45
void * wdata
Private data.
Definition: mutt_window.h:133
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_win_shutdown()

void sb_win_shutdown ( struct MuttWindow dlg)

Clean up the Sidebar's observers.

Parameters
dlgDialog Window

Definition at line 1127 of file sidebar.c.

1128 {
1129  struct MuttWindow *win = mutt_window_find(dlg, WT_SIDEBAR);
1130  if (!win)
1131  return;
1132 
1134 }
struct MuttWindow * mutt_window_find(struct MuttWindow *root, enum WindowType type)
Find a Window of a given type.
Definition: mutt_window.c:692
A division of the screen.
Definition: mutt_window.h:114
Container for Accounts, Notifications.
Definition: neomutt.h:36
Side panel containing Accounts or groups of data.
Definition: mutt_window.h:98
int sb_observer(struct NotifyCallback *nc)
Listen for config changes affecting the sidebar - Implements observer_t.
Definition: observer.c:43
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:185
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_init()

void sb_init ( void  )

Set up the Sidebar.

Definition at line 1139 of file sidebar.c.

1140 {
1141  // Soon this will initialise the Sidebar's:
1142  // - Colours
1143  // - Commands
1144  // - Config
1145  // - Functions
1146 
1147  // Listen for dialog creation events
1149 }
Container for Accounts, Notifications.
Definition: neomutt.h:36
int sb_insertion_observer(struct NotifyCallback *nc)
Listen for new Dialogs - Implements observer_t.
Definition: observer.c:94
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
bool notify_observer_add(struct Notify *notify, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:153
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_shutdown()

void sb_shutdown ( void  )

Clean up the Sidebar.

Definition at line 1154 of file sidebar.c.

1155 {
1156  if (NeoMutt)
1159 }
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
int sb_insertion_observer(struct NotifyCallback *nc)
Listen for new Dialogs - Implements observer_t.
Definition: observer.c:94
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:185
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ SidebarWhitelist

struct ListHead SidebarWhitelist = STAILQ_HEAD_INITIALIZER(SidebarWhitelist)

List of mailboxes to always display in the sidebar.

Definition at line 51 of file sidebar.c.