1 /* Copyright (C) 2004 Justin Hibbits <jrh29@po.cwru.edu>
2 * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
3 * Copyright (C) 2015-2016 Richard Russon <rich@flatcap.org>
4 * Copyright (C) 2016-2017 Kevin J. McCarthy <kevin@8t8.us>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
28 #include "mutt_curses.h"
29 #include "mutt_menu.h"
32 /* Previous values for some sidebar config */
33 static short PreviousSort = SORT_ORDER; /* sidebar_sort_method */
36 * struct sidebar_entry - Info about folders in the sidebar
38 typedef struct sidebar_entry
40 char box[STRING]; /* formatted mailbox name */
45 static int EntryCount = 0;
46 static int EntryLen = 0;
47 static SBENTRY **Entries = NULL;
49 static int TopIndex = -1; /* First mailbox visible in sidebar */
50 static int OpnIndex = -1; /* Current (open) mailbox */
51 static int HilIndex = -1; /* Highlighted mailbox */
52 static int BotIndex = -1; /* Last mailbox visible in sidebar */
54 static int select_next (void);
58 * cb_format_str - Create the string to show in the sidebar
59 * @dest: Buffer in which to save string
60 * @destlen: Buffer length
61 * @col: Starting column, UNUSED
62 * @op: printf-like operator, e.g. 'B'
63 * @src: printf-like format string
64 * @prefix: Field formatting string, UNUSED
65 * @ifstring: If condition is met, display this string
66 * @elsestring: Otherwise, display this string
67 * @data: Pointer to our sidebar_entry
68 * @flags: Format flags, e.g. MUTT_FORMAT_OPTIONAL
70 * cb_format_str is a callback function for mutt_FormatString. It understands
71 * six operators. '%B' : Mailbox name, '%F' : Number of flagged messages,
72 * '%N' : Number of new messages, '%S' : Size (total number of messages),
73 * '%!' : Icon denoting number of flagged messages.
74 * '%n' : N if folder has new mail, blank otherwise.
76 * Returns: src (unchanged)
78 static const char *cb_format_str(char *dest, size_t destlen, size_t col, int cols, char op,
79 const char *src, const char *prefix, const char *ifstring,
80 const char *elsestring, unsigned long data, format_flag flags)
82 SBENTRY *sbe = (SBENTRY *) data;
83 unsigned int optional;
89 dest[0] = 0; /* Just in case there's nothing to do */
91 BUFFY *b = sbe->buffy;
95 int c = Context && (mutt_strcmp (Context->realpath, b->realpath) == 0);
97 optional = flags & MUTT_FORMAT_OPTIONAL;
102 mutt_format_s (dest, destlen, prefix, sbe->box);
108 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
109 snprintf (dest, destlen, fmt, c ? Context->deleted : 0);
111 else if ((c && Context->deleted == 0) || !c)
118 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
119 snprintf (dest, destlen, fmt, b->msg_flagged);
121 else if (b->msg_flagged == 0)
128 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
129 snprintf (dest, destlen, fmt, c ? Context->vcount : b->msg_count);
131 else if ((c && Context->vcount == b->msg_count) || !c)
138 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
139 snprintf (dest, destlen, fmt, b->msg_unread);
141 else if (b->msg_unread == 0)
148 snprintf (fmt, sizeof (fmt), "%%%sc", prefix);
149 snprintf (dest, destlen, fmt, b->new ? 'N' : ' ');
151 else if (b->new == 0)
158 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
159 snprintf (dest, destlen, fmt, b->msg_count);
161 else if (b->msg_count == 0)
168 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
169 snprintf (dest, destlen, fmt, c ? Context->tagged : 0);
171 else if ((c && Context->tagged == 0) || !c)
176 if (b->msg_flagged == 0)
177 mutt_format_s (dest, destlen, prefix, "");
178 else if (b->msg_flagged == 1)
179 mutt_format_s (dest, destlen, prefix, "!");
180 else if (b->msg_flagged == 2)
181 mutt_format_s (dest, destlen, prefix, "!!");
184 snprintf (fmt, sizeof (fmt), "%d!", b->msg_flagged);
185 mutt_format_s (dest, destlen, prefix, fmt);
191 mutt_FormatString (dest, destlen, col, SidebarWidth, ifstring, cb_format_str, (unsigned long) sbe, flags);
192 else if (flags & MUTT_FORMAT_OPTIONAL)
193 mutt_FormatString (dest, destlen, col, SidebarWidth, elsestring, cb_format_str, (unsigned long) sbe, flags);
195 /* We return the format string, unchanged */
200 * make_sidebar_entry - Turn mailbox data into a sidebar string
201 * @buf: Buffer in which to save string
202 * @buflen: Buffer length
203 * @width: Desired width in screen cells
207 * Take all the relevant mailbox data and the desired screen width and then get
208 * mutt_FormatString to do the actual work. mutt_FormatString will callback to
209 * us using cb_format_str() for the sidebar specific formatting characters.
211 static void make_sidebar_entry (char *buf, unsigned int buflen, int width, const char *box,
214 if (!buf || !box || !sbe)
217 strfcpy (sbe->box, box, sizeof (sbe->box));
219 mutt_FormatString (buf, buflen, 0, width, NONULL(SidebarFormat), cb_format_str, (unsigned long) sbe, 0);
221 /* Force string to be exactly the right width */
222 int w = mutt_strwidth (buf);
223 int s = mutt_strlen (buf);
224 width = MIN(buflen, width);
227 /* Pad with spaces */
228 memset (buf + s, ' ', width - w);
229 buf[s + width - w] = 0;
233 /* Truncate to fit */
234 int len = mutt_wstr_trunc (buf, buflen, width, NULL);
240 * cb_qsort_sbe - qsort callback to sort SBENTRYs
241 * @a: First SBENTRY to compare
242 * @b: Second SBENTRY to compare
246 * 0: a and b are identical
249 static int cb_qsort_sbe (const void *a, const void *b)
251 const SBENTRY *sbe1 = *(const SBENTRY **) a;
252 const SBENTRY *sbe2 = *(const SBENTRY **) b;
253 BUFFY *b1 = sbe1->buffy;
254 BUFFY *b2 = sbe2->buffy;
258 switch ((SidebarSortMethod & SORT_MASK))
261 result = (b2->msg_count - b1->msg_count);
264 result = (b2->msg_unread - b1->msg_unread);
267 result = (b2->msg_flagged - b1->msg_flagged);
270 result = mutt_strcasecmp (mutt_b2s (b1->pathbuf), mutt_b2s (b2->pathbuf));
274 if (SidebarSortMethod & SORT_REVERSE)
281 * update_entries_visibility - Should a sidebar_entry be displayed in the sidebar
283 * For each SBENTRY in the Entries array, check whether we should display it.
284 * This is determined by several criteria. If the BUFFY:
285 * is the currently open mailbox
286 * is the currently highlighted mailbox
287 * has unread messages
288 * has flagged messages
291 static void update_entries_visibility (void)
293 short new_only = option (OPTSIDEBARNEWMAILONLY);
297 for (i = 0; i < EntryCount; i++)
306 if ((i == OpnIndex) || (sbe->buffy->msg_unread > 0) || sbe->buffy->new ||
307 (sbe->buffy->msg_flagged > 0))
310 if (Context && (mutt_strcmp (sbe->buffy->realpath, Context->realpath) == 0))
311 /* Spool directory */
314 if (mutt_find_list (SidebarWhitelist, mutt_b2s (sbe->buffy->pathbuf)))
315 /* Explicitly asked to be visible */
323 * unsort_entries - Restore Entries array order to match Buffy list order
325 static void unsort_entries (void)
327 BUFFY *cur = Incoming;
331 while (cur && (i < EntryCount))
334 while ((j < EntryCount) &&
335 (Entries[j]->buffy != cur))
342 Entries[i] = Entries[j];
352 * sort_entries - Sort Entries array.
354 * Sort the Entries array according to the current sort config
355 * option "sidebar_sort_method". This calls qsort to do the work which calls our
356 * callback function "cb_qsort_sbe".
358 * Once sorted, the prev/next links will be reconstructed.
360 static void sort_entries (void)
362 short ssm = (SidebarSortMethod & SORT_MASK);
364 /* These are the only sort methods we understand */
365 if ((ssm == SORT_COUNT) ||
366 (ssm == SORT_UNREAD) ||
367 (ssm == SORT_FLAGGED) ||
369 qsort (Entries, EntryCount, sizeof (*Entries), cb_qsort_sbe);
370 else if ((ssm == SORT_ORDER) &&
371 (SidebarSortMethod != PreviousSort))
376 * prepare_sidebar - Prepare the list of SBENTRYs for the sidebar display
377 * @page_size: The number of lines on a page
379 * Before painting the sidebar, we determine which are visible, sort
380 * them and set up our page pointers.
382 * This is a lot of work to do each refresh, but there are many things that
383 * can change outside of the sidebar that we don't hear about.
386 * 0: No, don't draw the sidebar
387 * 1: Yes, draw the sidebar
389 static int prepare_sidebar (int page_size)
392 SBENTRY *opn_entry = NULL, *hil_entry = NULL;
395 if (!EntryCount || (page_size <= 0))
399 opn_entry = Entries[OpnIndex];
401 hil_entry = Entries[HilIndex];
403 update_entries_visibility ();
406 for (i = 0; i < EntryCount; i++)
408 if (opn_entry == Entries[i])
410 if (hil_entry == Entries[i])
414 if ((HilIndex < 0) || Entries[HilIndex]->is_hidden ||
415 (SidebarSortMethod != PreviousSort))
422 if (Entries[HilIndex]->is_hidden)
427 /* Set the Top and Bottom to frame the HilIndex in groups of page_size */
429 /* If OPTSIDEBARNEMAILONLY is set, some entries may be hidden so we
430 * need to scan for the framing interval */
431 if (option (OPTSIDEBARNEWMAILONLY))
433 TopIndex = BotIndex = -1;
434 while (BotIndex < HilIndex)
436 TopIndex = BotIndex + 1;
438 while (page_entries < page_size)
441 if (BotIndex >= EntryCount)
443 if (! Entries[BotIndex]->is_hidden)
448 /* Otherwise we can just calculate the interval */
451 TopIndex = (HilIndex / page_size) * page_size;
452 BotIndex = TopIndex + page_size - 1;
455 if (BotIndex > (EntryCount - 1))
456 BotIndex = EntryCount - 1;
458 PreviousSort = SidebarSortMethod;
463 * draw_divider - Draw a line between the sidebar and the rest of mutt
464 * @num_rows: Height of the Sidebar
465 * @num_cols: Width of the Sidebar
467 * Draw a divider using characters from the config option "sidebar_divider_char".
468 * This can be an ASCII or Unicode character. First we calculate this
469 * characters' width in screen columns, then subtract that from the config
470 * option "sidebar_width".
473 * -1: Error: bad character, etc
474 * 0: Error: 0 width character
475 * n: Success: character occupies n screen columns
477 static int draw_divider (int num_rows, int num_cols)
479 /* Calculate the width of the delimiter in screen cells */
480 int delim_len = mutt_strwidth (SidebarDividerChar);
485 if (delim_len > num_cols)
488 SETCOLOR(MT_COLOR_DIVIDER);
491 for (i = 0; i < num_rows; i++)
493 mutt_window_move (MuttSidebarWindow, i, SidebarWidth - delim_len); //RAR 0 for rhs
494 addstr (NONULL(SidebarDividerChar));
501 * fill_empty_space - Wipe the remaining Sidebar space
502 * @first_row: Window line to start (0-based)
503 * @num_rows: Number of rows to fill
504 * @width: Width of the Sidebar (minus the divider)
506 * Write spaces over the area the sidebar isn't using.
508 static void fill_empty_space (int first_row, int num_rows, int width)
510 /* Fill the remaining rows with blank space */
511 SETCOLOR(MT_COLOR_NORMAL);
514 for (r = 0; r < num_rows; r++)
516 mutt_window_move (MuttSidebarWindow, first_row + r, 0); //RAR rhs
518 for (i = 0; i < width; i++)
524 * calculate_depth - Calculate depth of path based on SidebarDelimChars.
526 * If lastpath is not NULL, common_depth is also calculated. These
527 * are used for indentation and short_path calculation.
529 static void calculate_depth (const char *path, const char *lastpath,
530 int *depth, int *common_depth)
532 int i, has_trailing_delim = 0;
534 *depth = *common_depth = 0;
535 if (!SidebarDelimChars || !path)
538 for (i = 0; path[i]; i++)
540 if (strchr (SidebarDelimChars, path[i]))
544 /* /a/b/c and /a/b/c/ both are a depth of 3.
545 * Only count the final '\0' if the last character wasn't a separator.
548 has_trailing_delim = 1;
559 if (strchr (SidebarDelimChars, path[i]) &&
560 (strchr (SidebarDelimChars, lastpath[i]) || !lastpath[i]))
573 else if (!lastpath[i] || path[i] != lastpath[i])
578 if (!has_trailing_delim)
589 (strchr (SidebarDelimChars, lastpath[i]) || !lastpath[i]))
594 #define SIDEBAR_MAX_INDENT 32
597 * draw_sidebar - Write out a list of mailboxes, on the left
598 * @num_rows: Height of the Sidebar
599 * @num_cols: Width of the Sidebar
600 * @div_width: Width in screen characters taken by the divider
602 * Display a list of mailboxes in a panel on the left. What's displayed will
603 * depend on our index markers: TopBuffy, OpnBuffy, HilBuffy, BotBuffy.
604 * On the first run they'll be NULL, so we display the top of Mutt's list
607 * TopBuffy - first visible mailbox
608 * BotBuffy - last visible mailbox
609 * OpnBuffy - mailbox shown in Mutt's Index Panel
610 * HilBuffy - Unselected mailbox (the paging follows this)
612 * The entries are formatted using "sidebar_format" and may be abbreviated:
613 * "sidebar_short_path", indented: "sidebar_folder_indent",
614 * "sidebar_indent_string" and sorted: "sidebar_sort_method". Finally, they're
615 * trimmed to fit the available space.
617 static void draw_sidebar (int num_rows, int num_cols, int div_width)
622 int indent_width = -1;
623 int indent_depths[SIDEBAR_MAX_INDENT];
624 const char *sidebar_folder_name;
625 BUFFER *pretty_folder_name, *last_folder_name, *indent_folder_name;
630 pretty_folder_name = mutt_buffer_pool_get ();
631 last_folder_name = mutt_buffer_pool_get ();
632 indent_folder_name = mutt_buffer_pool_get ();
634 int w = MIN(num_cols, (SidebarWidth - div_width));
636 for (entryidx = TopIndex; (entryidx < EntryCount) && (row < num_rows); entryidx++)
638 entry = Entries[entryidx];
639 if (entry->is_hidden)
643 if (entryidx == OpnIndex)
645 if ((ColorDefs[MT_COLOR_SB_INDICATOR] != 0))
646 SETCOLOR(MT_COLOR_SB_INDICATOR);
648 SETCOLOR(MT_COLOR_INDICATOR);
650 else if (entryidx == HilIndex)
651 SETCOLOR(MT_COLOR_HIGHLIGHT);
652 else if ((b->msg_unread > 0) || (b->new))
653 SETCOLOR(MT_COLOR_NEW);
654 else if (b->msg_flagged > 0)
655 SETCOLOR(MT_COLOR_FLAGGED);
656 else if ((ColorDefs[MT_COLOR_SB_SPOOLFILE] != 0) &&
657 (mutt_strcmp (mutt_b2s (b->pathbuf), Spoolfile) == 0))
658 SETCOLOR(MT_COLOR_SB_SPOOLFILE);
660 SETCOLOR(MT_COLOR_NORMAL);
662 mutt_window_move (MuttSidebarWindow, row, 0);
663 if (Context && Context->realpath &&
664 !mutt_strcmp (b->realpath, Context->realpath))
666 b->msg_unread = Context->unread;
667 b->msg_count = Context->msgcount;
668 b->msg_flagged = Context->flagged;
671 mutt_buffer_strcpy (pretty_folder_name, mutt_b2s (b->pathbuf));
672 mutt_buffer_pretty_mailbox (pretty_folder_name);
673 sidebar_folder_name = mutt_b2s (pretty_folder_name);
675 if (SidebarDelimChars)
677 int parent_depth = 0;
680 if (option (OPTSIDEBARSHORTPATH) || option (OPTSIDEBARFOLDERINDENT))
682 int depth = 0, common_depth = 0;
684 calculate_depth (sidebar_folder_name, mutt_b2s (last_folder_name),
685 &depth, &common_depth);
686 mutt_buffer_strcpy (last_folder_name, sidebar_folder_name);
688 if (indent_width < SIDEBAR_MAX_INDENT)
691 /* indent_depths[] hold the path depths at each level of indentation.
692 * Indent based off the longest path that we share in common.
694 * The 'indent_depths[] >= depth' test below is for a corner case:
696 * path depth common_depth indent_width
701 * Because the common_depth of /a/b/ matches the depth of
702 * /a/b, we need the additional test to continue popping the
703 * indent_depths[] stack.
705 while (indent_width &&
706 ((indent_depths[indent_width - 1] > common_depth) ||
707 (indent_depths[indent_width - 1] >= depth)))
710 if (indent_width < SIDEBAR_MAX_INDENT)
711 indent_depths[indent_width] = depth;
713 parent_depth = indent_depths[indent_width - 1];
716 if (option (OPTSIDEBARSHORTPATH) && parent_depth)
718 for (i = 0; parent_depth && sidebar_folder_name[i]; i++)
719 if (strchr (SidebarDelimChars, sidebar_folder_name[i]))
721 sidebar_folder_name += i;
724 if (option (OPTSIDEBARFOLDERINDENT) && indent_width)
726 mutt_buffer_clear (indent_folder_name);
727 for (i = 0; i < indent_width; i++)
728 mutt_buffer_addstr (indent_folder_name, NONULL(SidebarIndentString));
729 mutt_buffer_addstr (indent_folder_name, sidebar_folder_name);
730 sidebar_folder_name = mutt_b2s (indent_folder_name);
735 make_sidebar_entry (str, sizeof (str), w, sidebar_folder_name, entry);
740 mutt_buffer_pool_release (&pretty_folder_name);
741 mutt_buffer_pool_release (&last_folder_name);
742 mutt_buffer_pool_release (&indent_folder_name);
744 fill_empty_space (row, num_rows - row, w);
749 * mutt_sb_draw - Completely redraw the sidebar
751 * Completely refresh the sidebar region. First draw the divider; then, for
752 * each BUFFY, call make_sidebar_entry; finally blank out any remaining space.
754 void mutt_sb_draw (void)
756 if (!option (OPTSIDEBAR))
759 int num_rows = MuttSidebarWindow->rows;
760 int num_cols = MuttSidebarWindow->cols;
762 int div_width = draw_divider (num_rows, num_cols);
768 fill_empty_space (0, num_rows, SidebarWidth - div_width);
772 if (!prepare_sidebar (num_rows))
775 draw_sidebar (num_rows, num_cols, div_width);
779 * select_next - Selects the next unhidden mailbox
785 static int select_next (void)
787 int entry = HilIndex;
789 if (!EntryCount || HilIndex < 0)
795 if (entry == EntryCount)
797 } while (Entries[entry]->is_hidden);
804 * select_next_new - Selects the next new mailbox
806 * Search down the list of mail folders for one containing new mail.
812 static int select_next_new (void)
814 int entry = HilIndex;
816 if (!EntryCount || HilIndex < 0)
822 if (entry == EntryCount)
824 if (option (OPTSIDEBARNEXTNEWWRAP))
829 if (entry == HilIndex)
831 } while (!Entries[entry]->buffy->new &&
832 !Entries[entry]->buffy->msg_unread);
839 * select_prev - Selects the previous unhidden mailbox
845 static int select_prev (void)
847 int entry = HilIndex;
849 if (!EntryCount || HilIndex < 0)
857 } while (Entries[entry]->is_hidden);
864 * select_prev_new - Selects the previous new mailbox
866 * Search up the list of mail folders for one containing new mail.
872 static int select_prev_new (void)
874 int entry = HilIndex;
876 if (!EntryCount || HilIndex < 0)
884 if (option (OPTSIDEBARNEXTNEWWRAP))
885 entry = EntryCount - 1;
889 if (entry == HilIndex)
891 } while (!Entries[entry]->buffy->new &&
892 !Entries[entry]->buffy->msg_unread);
899 * select_page_down - Selects the first entry in the next page of mailboxes
905 static int select_page_down (void)
907 int orig_hil_index = HilIndex;
909 if (!EntryCount || BotIndex < 0)
914 /* If the rest of the entries are hidden, go up to the last unhidden one */
915 if (Entries[HilIndex]->is_hidden)
918 return (orig_hil_index != HilIndex);
922 * select_page_up - Selects the last entry in the previous page of mailboxes
928 static int select_page_up (void)
930 int orig_hil_index = HilIndex;
932 if (!EntryCount || TopIndex < 0)
937 /* If the rest of the entries are hidden, go down to the last unhidden one */
938 if (Entries[HilIndex]->is_hidden)
941 return (orig_hil_index != HilIndex);
945 * mutt_sb_change_mailbox - Change the selected mailbox
946 * @op: Operation code
948 * Change the selected mailbox, e.g. "Next mailbox", "Previous Mailbox
949 * with new mail". The operations are listed OPS.SIDEBAR which is built
950 * into an enum in keymap_defs.h.
952 * If the operation is successful, HilBuffy will be set to the new mailbox.
953 * This function only *selects* the mailbox, doesn't *open* it.
955 * Allowed values are: OP_SIDEBAR_NEXT, OP_SIDEBAR_NEXT_NEW,
956 * OP_SIDEBAR_PAGE_DOWN, OP_SIDEBAR_PAGE_UP, OP_SIDEBAR_PREV,
957 * OP_SIDEBAR_PREV_NEW.
959 void mutt_sb_change_mailbox (int op)
961 if (!option (OPTSIDEBAR))
964 if (HilIndex < 0) /* It'll get reset on the next draw */
969 case OP_SIDEBAR_NEXT:
970 if (! select_next ())
973 case OP_SIDEBAR_NEXT_NEW:
974 if (! select_next_new ())
977 case OP_SIDEBAR_PAGE_DOWN:
978 if (! select_page_down ())
981 case OP_SIDEBAR_PAGE_UP:
982 if (! select_page_up ())
985 case OP_SIDEBAR_PREV:
986 if (! select_prev ())
989 case OP_SIDEBAR_PREV_NEW:
990 if (! select_prev_new ())
996 mutt_set_current_menu_redraw (REDRAW_SIDEBAR);
1000 * mutt_sb_set_buffystats - Update the BUFFY's message counts from the CONTEXT
1001 * @ctx: A mailbox CONTEXT
1003 * Given a mailbox CONTEXT, find a matching mailbox BUFFY and copy the message
1006 void mutt_sb_set_buffystats (const CONTEXT *ctx)
1008 /* Even if the sidebar's hidden,
1009 * we should take note of the new data. */
1010 BUFFY *b = Incoming;
1014 for (; b; b = b->next)
1016 if (!mutt_strcmp (b->realpath, ctx->realpath))
1018 b->msg_unread = ctx->unread;
1019 b->msg_count = ctx->msgcount;
1020 b->msg_flagged = ctx->flagged;
1027 * mutt_sb_get_highlight - Get the BUFFY that's highlighted in the sidebar
1029 * Get the path of the mailbox that's highlighted in the sidebar.
1034 const char *mutt_sb_get_highlight (void)
1036 if (!option (OPTSIDEBAR))
1039 if (!EntryCount || HilIndex < 0)
1042 return mutt_b2s (Entries[HilIndex]->buffy->pathbuf);
1046 * mutt_sb_set_open_buffy - Set the OpnBuffy based on the global Context
1048 * Search through the list of mailboxes. If a BUFFY has a matching path, set
1051 void mutt_sb_set_open_buffy (void)
1060 for (entry = 0; entry < EntryCount; entry++)
1062 if (!mutt_strcmp (Entries[entry]->buffy->realpath, Context->realpath))
1072 * mutt_sb_notify_mailbox - The state of a BUFFY is about to change
1074 * We receive a notification:
1075 * After a new BUFFY has been created
1076 * Before a BUFFY is deleted
1078 * Before a deletion, check that our pointers won't be invalidated.
1080 void mutt_sb_notify_mailbox (BUFFY *b, int created)
1087 /* Any new/deleted mailboxes will cause a refresh. As long as
1088 * they're valid, our pointers will be updated in prepare_sidebar() */
1092 if (EntryCount >= EntryLen)
1095 safe_realloc (&Entries, EntryLen * sizeof (SBENTRY *));
1097 Entries[EntryCount] = safe_calloc (1, sizeof(SBENTRY));
1098 Entries[EntryCount]->buffy = b;
1101 TopIndex = EntryCount;
1103 BotIndex = EntryCount;
1104 if ((OpnIndex < 0) && Context &&
1105 (mutt_strcmp (b->realpath, Context->realpath) == 0))
1106 OpnIndex = EntryCount;
1112 for (del_index = 0; del_index < EntryCount; del_index++)
1113 if (Entries[del_index]->buffy == b)
1115 if (del_index == EntryCount)
1117 FREE (&Entries[del_index]);
1120 if (TopIndex > del_index || TopIndex == EntryCount)
1122 if (OpnIndex == del_index)
1124 else if (OpnIndex > del_index)
1126 if (HilIndex > del_index || HilIndex == EntryCount)
1128 if (BotIndex > del_index || BotIndex == EntryCount)
1131 for (; del_index < EntryCount; del_index++)
1132 Entries[del_index] = Entries[del_index + 1];
1135 mutt_set_current_menu_redraw (REDRAW_SIDEBAR);