changeset: 6707:b05c170b4c91 user: Kevin McCarthy <ke...@8t8.us> date: Sat Jul 02 12:22:51 2016 -0700 link: http://dev.mutt.org/hg/mutt/rev/b05c170b4c91
Decouple the sidebar from the Buffy list. Change the sidebar to use an array of SBENTRY* instead. Move the "is_hidden" into SBENTRY. Remove the added "prev" pointer from BUFFY. This way, sorting the sidebar doesn't affect the BUFFY list order, and we don't need elements inside BUFFY just for the sidebar presentation. Fix sidebar-next for the case where the mailboxes are unsorted and $sidebar_new_mail_only is set. Change sorting not to clump hidden mailboxes at the bottom, instead simply skip over hidden mailboxes in sidebar-next/prev. changeset: 6708:d404059a7619 user: Kevin McCarthy <ke...@8t8.us> date: Sat Jul 02 12:24:25 2016 -0700 link: http://dev.mutt.org/hg/mutt/rev/d404059a7619 Fix sidebar "unsorted" order to match Buffy list order. Since the previous commit decoupled the sidebar from the Buffy list, we can now restore the order to match the buffy list when sidebar_sort_method is set (back) to "unsorted". changeset: 6709:20089a780e8e user: Kevin McCarthy <ke...@8t8.us> date: Sat Jul 02 12:25:59 2016 -0700 link: http://dev.mutt.org/hg/mutt/rev/20089a780e8e Add R_SIDEBAR to redraw sidebar when its settings change. Add to the sidebar settings that control formatting of the sidebar. changeset: 6710:bf1c73de2b7c user: Kevin McCarthy <ke...@8t8.us> date: Sat Jul 02 12:32:55 2016 -0700 link: http://dev.mutt.org/hg/mutt/rev/bf1c73de2b7c Fix the documented sort methods for sidebar_sort_method. Remove references to unused "date" and "size", and add "flagged". diffs (truncated from 964 to 950 lines): diff -r c62f5cd3c8e4 -r bf1c73de2b7c buffy.h --- a/buffy.h Fri Jul 01 13:39:51 2016 -0700 +++ b/buffy.h Sat Jul 02 12:32:55 2016 -0700 @@ -30,9 +30,6 @@ and the sidebar */ off_t size; struct buffy_t *next; -#ifdef USE_SIDEBAR - struct buffy_t *prev; -#endif short new; /* mailbox has new mail */ /* These next three are only set when OPTMAILCHECKSTATS is set */ @@ -40,9 +37,6 @@ int msg_unread; /* number of unread messages */ int msg_flagged; /* number of flagged messages */ -#ifdef USE_SIDEBAR - short is_hidden; /* is hidden from the sidebar */ -#endif short notified; /* user has been notified */ short magic; /* mailbox type */ short newly_created; /* mbox or mmdf just popped into existence */ diff -r c62f5cd3c8e4 -r bf1c73de2b7c doc/manual.xml.head --- a/doc/manual.xml.head Fri Jul 01 13:39:51 2016 -0700 +++ b/doc/manual.xml.head Sat Jul 02 12:32:55 2016 -0700 @@ -8200,7 +8200,7 @@ <row> <entry><literal>sidebar_sort_method</literal></entry> <entry>enum</entry> - <entry><literal>SORT_ORDER</literal></entry> + <entry><literal>unsorted</literal></entry> </row> <row> <entry><literal>sidebar_visible</literal></entry> diff -r c62f5cd3c8e4 -r bf1c73de2b7c init.c --- a/init.c Fri Jul 01 13:39:51 2016 -0700 +++ b/init.c Sat Jul 02 12:32:55 2016 -0700 @@ -1613,6 +1613,10 @@ set_option (OPTREDRAWTREE); if (p->flags & R_REFLOW) mutt_reflow_windows (); +#ifdef USE_SIDEBAR + if (p->flags & R_SIDEBAR) + SidebarNeedsRedraw = 1; +#endif } static size_t escape_string (char *dst, size_t len, const char* src) @@ -2233,6 +2237,10 @@ set_option (OPTREDRAWTREE); if (MuttVars[idx].flags & R_REFLOW) mutt_reflow_windows (); +#ifdef USE_SIDEBAR + if (MuttVars[idx].flags & R_SIDEBAR) + SidebarNeedsRedraw = 1; +#endif } } return (r); diff -r c62f5cd3c8e4 -r bf1c73de2b7c init.h --- a/init.h Fri Jul 01 13:39:51 2016 -0700 +++ b/init.h Sat Jul 02 12:32:55 2016 -0700 @@ -63,6 +63,7 @@ #define R_RESORT_INIT (1<<4) /* resort from scratch */ #define R_TREE (1<<5) /* redraw the thread tree */ #define R_REFLOW (1<<6) /* reflow window layout */ +#define R_SIDEBAR (1<<7) /* redraw the sidebar */ #define R_BOTH (R_INDEX | R_PAGER) #define R_RESORT_BOTH (R_RESORT | R_RESORT_SUB) @@ -2684,14 +2685,14 @@ ** shell from \fC/etc/passwd\fP is used. */ #ifdef USE_SIDEBAR - { "sidebar_divider_char", DT_STR, R_BOTH, UL &SidebarDividerChar, UL "|" }, + { "sidebar_divider_char", DT_STR, R_SIDEBAR, UL &SidebarDividerChar, UL "|" }, /* ** .pp ** This specifies the characters to be drawn between the sidebar (when ** visible) and the other Mutt panels. ASCII and Unicode line-drawing ** characters are supported. */ - { "sidebar_delim_chars", DT_STR, R_NONE, UL &SidebarDelimChars, UL "/." }, + { "sidebar_delim_chars", DT_STR, R_SIDEBAR, UL &SidebarDelimChars, UL "/." }, /* ** .pp ** This contains the list of characters which you would like to treat @@ -2709,14 +2710,14 @@ ** .pp ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_folder_indent, $$sidebar_indent_string. */ - { "sidebar_folder_indent", DT_BOOL, R_BOTH, OPTSIDEBARFOLDERINDENT, 0 }, + { "sidebar_folder_indent", DT_BOOL, R_SIDEBAR, OPTSIDEBARFOLDERINDENT, 0 }, /* ** .pp ** Set this to indent mailboxes in the sidebar. ** .pp ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_indent_string, $$sidebar_delim_chars. */ - { "sidebar_format", DT_STR, R_NONE, UL &SidebarFormat, UL "%B%* %n" }, + { "sidebar_format", DT_STR, R_SIDEBAR, UL &SidebarFormat, UL "%B%* %n" }, /* ** .pp ** This variable allows you to customize the sidebar display. This string is @@ -2747,7 +2748,7 @@ ** be \fIset\fP. When thus set, a suggested value for this option is ** "%B%?F? [%F]?%* %?N?%N/?%S". */ - { "sidebar_indent_string", DT_STR, R_BOTH, UL &SidebarIndentString, UL " " }, + { "sidebar_indent_string", DT_STR, R_SIDEBAR, UL &SidebarIndentString, UL " " }, /* ** .pp ** This specifies the string that is used to indent mailboxes in the sidebar. @@ -2755,7 +2756,7 @@ ** .pp ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_folder_indent, $$sidebar_delim_chars. */ - { "sidebar_new_mail_only", DT_BOOL, R_BOTH, OPTSIDEBARNEWMAILONLY, 0 }, + { "sidebar_new_mail_only", DT_BOOL, R_SIDEBAR, OPTSIDEBARNEWMAILONLY, 0 }, /* ** .pp ** When set, the sidebar will only display mailboxes containing new, or @@ -2763,7 +2764,7 @@ ** .pp ** \fBSee also:\fP $sidebar_whitelist. */ - { "sidebar_next_new_wrap", DT_BOOL, R_BOTH, UL OPTSIDEBARNEXTNEWWRAP, 0 }, + { "sidebar_next_new_wrap", DT_BOOL, R_NONE, UL OPTSIDEBARNEXTNEWWRAP, 0 }, /* ** .pp ** When set, the \fC<sidebar-next-new>\fP command will not stop and the end of @@ -2771,7 +2772,7 @@ ** \fC<sidebar-prev-new>\fP command is similarly affected, wrapping around to ** the end of the list. */ - { "sidebar_short_path", DT_BOOL, R_BOTH, OPTSIDEBARSHORTPATH, 0 }, + { "sidebar_short_path", DT_BOOL, R_SIDEBAR, OPTSIDEBARSHORTPATH, 0 }, /* ** .pp ** By default the sidebar will show the mailbox's path, relative to the @@ -2787,7 +2788,7 @@ ** .pp ** \fBSee also:\fP $$sidebar_delim_chars, $$sidebar_folder_indent, $$sidebar_indent_string. */ - { "sidebar_sort_method", DT_SORT|DT_SORT_SIDEBAR, R_NONE, UL &SidebarSortMethod, SORT_ORDER }, + { "sidebar_sort_method", DT_SORT|DT_SORT_SIDEBAR, R_SIDEBAR, UL &SidebarSortMethod, SORT_ORDER }, /* ** .pp ** Specifies how to sort entries in the file browser. By default, the @@ -2795,9 +2796,8 @@ ** .il ** .dd alpha (alphabetically) ** .dd count (all message count) - ** .dd date + ** .dd flagged (flagged message count) ** .dd new (new message count) - ** .dd size ** .dd unsorted ** .ie ** .pp diff -r c62f5cd3c8e4 -r bf1c73de2b7c sidebar.c --- a/sidebar.c Fri Jul 01 13:39:51 2016 -0700 +++ b/sidebar.c Sat Jul 02 12:32:55 2016 -0700 @@ -29,86 +29,26 @@ #include "sort.h" /* Previous values for some sidebar config */ -static short PreviousSort; /* sidebar_sort_method */ - -/* Keep track of various BUFFYs */ -static BUFFY *TopBuffy; /* First mailbox visible in sidebar */ -static BUFFY *OpnBuffy; /* Current (open) mailbox */ -static BUFFY *HilBuffy; /* Highlighted mailbox */ -static BUFFY *BotBuffy; /* Last mailbox visible in sidebar */ -static BUFFY *Outgoing; /* Last mailbox in the linked list */ +static short PreviousSort = SORT_ORDER; /* sidebar_sort_method */ /** * struct sidebar_entry - Info about folders in the sidebar - * - * Used in the mutt_FormatString callback */ -struct sidebar_entry +typedef struct sidebar_entry { - char box[STRING]; + char box[STRING]; /* formatted mailbox name */ BUFFY *buffy; -}; + short is_hidden; +} SBENTRY; +static int EntryCount = 0; +static int EntryLen = 0; +static SBENTRY **Entries = NULL; -/** - * find_next_new - Find the next folder that contains new mail - * @wrap: Wrap around to the beginning if the end is reached - * - * Search down the list of mail folders for one containing new mail. - * - * Returns: - * BUFFY*: Success - * NULL: Failure - */ -static BUFFY *find_next_new (int wrap) -{ - BUFFY *b = HilBuffy; - if (!b) - return NULL; - - do - { - b = b->next; - if (!b && wrap) - b = Incoming; - if (!b || (b == HilBuffy)) - break; - if (b->new || b->msg_unread > 0) - return b; - } while (b); - - return NULL; -} - -/** - * find_prev_new - Find the previous folder that contains new mail - * @wrap: Wrap around to the beginning if the end is reached - * - * Search up the list of mail folders for one containing new mail. - * - * Returns: - * BUFFY*: Success - * NULL: Failure - */ -static BUFFY *find_prev_new (int wrap) -{ - BUFFY *b = HilBuffy; - if (!b) - return NULL; - - do - { - b = b->prev; - if (!b && wrap) - b = Outgoing; - if (!b || (b == HilBuffy)) - break; - if (b->new || b->msg_unread > 0) - return b; - } while (b); - - return NULL; -} +static int TopIndex = -1; /* First mailbox visible in sidebar */ +static int OpnIndex = -1; /* Current (open) mailbox */ +static int HilIndex = -1; /* Highlighted mailbox */ +static int BotIndex = -1; /* Last mailbox visible in sidebar */ /** * cb_format_str - Create the string to show in the sidebar @@ -135,7 +75,7 @@ const char *src, const char *prefix, const char *ifstring, const char *elsestring, unsigned long data, format_flag flags) { - struct sidebar_entry *sbe = (struct sidebar_entry *) data; + SBENTRY *sbe = (SBENTRY *) data; unsigned int optional; char fmt[STRING]; @@ -265,17 +205,14 @@ * us using cb_format_str() for the sidebar specific formatting characters. */ static void make_sidebar_entry (char *buf, unsigned int buflen, int width, char *box, - BUFFY *b) + SBENTRY *sbe) { - struct sidebar_entry sbe; - - if (!buf || !box || !b) + if (!buf || !box || !sbe) return; - sbe.buffy = b; - strfcpy (sbe.box, box, sizeof (sbe.box)); + strfcpy (sbe->box, box, sizeof (sbe->box)); - mutt_FormatString (buf, buflen, 0, width, NONULL(SidebarFormat), cb_format_str, (unsigned long) &sbe, 0); + mutt_FormatString (buf, buflen, 0, width, NONULL(SidebarFormat), cb_format_str, (unsigned long) sbe, 0); /* Force string to be exactly the right width */ int w = mutt_strwidth (buf); @@ -296,30 +233,21 @@ } /** - * cb_qsort_buffy - qsort callback to sort BUFFYs - * @a: First BUFFY to compare - * @b: Second BUFFY to compare - * - * Compare the paths of two BUFFYs taking the locale into account. + * cb_qsort_sbe - qsort callback to sort SBENTRYs + * @a: First SBENTRY to compare + * @b: Second SBENTRY to compare * * Returns: * -1: a precedes b * 0: a and b are identical * 1: b precedes a */ -static int cb_qsort_buffy (const void *a, const void *b) +static int cb_qsort_sbe (const void *a, const void *b) { - const BUFFY *b1 = *(const BUFFY **) a; - const BUFFY *b2 = *(const BUFFY **) b; - - /* Special case -- move hidden BUFFYs to the end */ - if (b1->is_hidden != b2->is_hidden) - { - if (b1->is_hidden) - return 1; - else - return -1; - } + const SBENTRY *sbe1 = *(const SBENTRY **) a; + const SBENTRY *sbe2 = *(const SBENTRY **) b; + BUFFY *b1 = sbe1->buffy; + BUFFY *b2 = sbe2->buffy; int result = 0; @@ -346,38 +274,9 @@ } /** - * buffy_going - Prevent our pointers becoming invalid - * @b: BUFFY about to be deleted + * update_entries_visibility - Should a sidebar_entry be displayed in the sidebar * - * If we receive a delete-notification for a BUFFY, we need to change any - * pointers we have to reference a different BUFFY, or set them to NULL. - * - * We don't update the prev/next pointers, they'll be fixed on the next - * call to prepare_sidebar(). - * - * Returns: - * A valid alternative BUFFY, or NULL - */ -static BUFFY *buffy_going (const BUFFY *b) -{ - if (!b) - return NULL; - - if (b->next) - { - b->next->prev = b->prev; - return b->next; - } - - return b->prev; -} - -/** - * update_buffy_visibility - Should a BUFFY be displayed in the sidebar - * @arr: array of BUFFYs - * @arr_len: number of BUFFYs in array - * - * For each BUFFY in the array, check whether we should display it. + * For each SBENTRY in the Entries array, check whether we should display it. * This is determined by several criteria. If the BUFFY: * is the currently open mailbox * is the currently highlighted mailbox @@ -385,80 +284,96 @@ * has flagged messages * is whitelisted */ -static void update_buffy_visibility (BUFFY **arr, int arr_len) +static void update_entries_visibility (void) { - if (!arr) - return; + short new_only = option (OPTSIDEBARNEWMAILONLY); + SBENTRY *sbe; + int i; - short new_only = option (OPTSIDEBARNEWMAILONLY); + for (i = 0; i < EntryCount; i++) + { + sbe = Entries[i]; - BUFFY *b; - int i; - for (i = 0; i < arr_len; i++) - { - b = arr[i]; - - b->is_hidden = 0; + sbe->is_hidden = 0; if (!new_only) continue; - if ((b == OpnBuffy) || (b->msg_unread > 0) || b->new || - (b == HilBuffy) || (b->msg_flagged > 0)) + if ((i == OpnIndex) || (sbe->buffy->msg_unread > 0) || sbe->buffy->new || + (i == HilIndex) || (sbe->buffy->msg_flagged > 0)) continue; - if (Context && (mutt_strcmp (b->realpath, Context->realpath) == 0)) + if (Context && (mutt_strcmp (sbe->buffy->realpath, Context->realpath) == 0)) /* Spool directory */ continue; - if (mutt_find_list (SidebarWhitelist, b->path)) + if (mutt_find_list (SidebarWhitelist, sbe->buffy->path)) /* Explicitly asked to be visible */ continue; - b->is_hidden = 1; + sbe->is_hidden = 1; } } /** - * sort_buffy_array - Sort an array of BUFFY pointers - * @arr: array of BUFFYs - * @arr_len: number of BUFFYs in array + * unsort_entries - Restore Entries array order to match Buffy list order + */ +static void unsort_entries (void) +{ + BUFFY *cur = Incoming; + int i = 0, j; + SBENTRY *tmp; + + while (cur && (i < EntryCount)) + { + j = i; + while ((j < EntryCount) && + (Entries[j]->buffy != cur)) + j++; + if (j < EntryCount) + { + if (j != i) + { + tmp = Entries[i]; + Entries[i] = Entries[j]; + Entries[j] = tmp; + } + i++; + } + cur = cur->next; + } +} + +/** + * sort_entries - Sort Entries array. * - * Sort an array of BUFFY pointers according to the current sort config + * Sort the 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_buffy". + * callback function "cb_qsort_sbe". * * Once sorted, the prev/next links will be reconstructed. */ -static void sort_buffy_array (BUFFY **arr, int arr_len) +static void sort_entries (void) { - if (!arr) - return; + short ssm = (SidebarSortMethod & SORT_MASK); /* These are the only sort methods we understand */ - short ssm = (SidebarSortMethod & SORT_MASK); if ((ssm == SORT_COUNT) || (ssm == SORT_COUNT_NEW) || (ssm == SORT_FLAGGED) || (ssm == SORT_PATH)) - qsort (arr, arr_len, sizeof (*arr), cb_qsort_buffy); - - int i; - for (i = 0; i < (arr_len - 1); i++) - arr[i]->next = arr[i + 1]; - arr[arr_len - 1]->next = NULL; - - for (i = 1; i < arr_len; i++) - arr[i]->prev = arr[i - 1]; - arr[0]->prev = NULL; + qsort (Entries, EntryCount, sizeof (*Entries), cb_qsort_sbe); + else if ((ssm == SORT_ORDER) && + (SidebarSortMethod != PreviousSort)) + unsort_entries (); } /** - * prepare_sidebar - Prepare the list of BUFFYs for the sidebar display + * prepare_sidebar - Prepare the list of SBENTRYs for the sidebar display * @page_size: The number of lines on a page * - * Before painting the sidebar, we count the BUFFYs, determine which are - * visible, sort them and set up our page pointers. + * 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. @@ -469,66 +384,45 @@ */ static int prepare_sidebar (int page_size) { - BUFFY *b = Incoming; - if (!b) + int i; + SBENTRY *opn_entry = NULL, *hil_entry = NULL; + + if (!EntryCount) return 0; - int count = 0; - for (; b; b = b->next) - count++; + if (OpnIndex >= 0) + opn_entry = Entries[OpnIndex]; + if (HilIndex >= 0) + hil_entry = Entries[HilIndex]; - BUFFY **arr = safe_malloc (count * sizeof (*arr)); + update_entries_visibility (); + sort_entries (); - int i = 0; - for (b = Incoming; b; b = b->next, i++) - arr[i] = b; - - update_buffy_visibility (arr, count); - sort_buffy_array (arr, count); - - Incoming = arr[0]; - - int top_index = 0; - int opn_index = -1; - int hil_index = -1; - int bot_index = -1; - - for (i = 0; i < count; i++) + for (i = 0; i < EntryCount; i++) { - if (OpnBuffy == arr[i]) - opn_index = i; - if (HilBuffy == arr[i]) - hil_index = i; + if (opn_entry == Entries[i]) + OpnIndex = i; + if (hil_entry == Entries[i]) + HilIndex = i; } - if (!HilBuffy || (SidebarSortMethod != PreviousSort)) + if ((HilIndex < 0) || (SidebarSortMethod != PreviousSort)) { - if (OpnBuffy) - { - HilBuffy = OpnBuffy; - hil_index = opn_index; - } + if (OpnIndex >= 0) + HilIndex = OpnIndex; else - { - HilBuffy = arr[0]; - hil_index = 0; - } + HilIndex = 0; } - if (TopBuffy) - top_index = (hil_index / page_size) * page_size; + if (TopIndex >= 0) + TopIndex = (HilIndex / page_size) * page_size; else - top_index = hil_index; - TopBuffy = arr[top_index]; + TopIndex = HilIndex; - bot_index = top_index + page_size - 1; - if (bot_index > (count - 1)) - bot_index = count - 1; - BotBuffy = arr[bot_index]; - - Outgoing = arr[count - 1]; + BotIndex = TopIndex + page_size - 1; + if (BotIndex > (EntryCount - 1)) + BotIndex = EntryCount - 1; PreviousSort = SidebarSortMethod; - FREE (&arr); return 1; } @@ -616,25 +510,29 @@ */ static void draw_sidebar (int num_rows, int num_cols, int div_width) { - BUFFY *b = TopBuffy; - if (!b) + int entryidx; + SBENTRY *entry; + BUFFY *b; + if (TopIndex < 0) return; int w = MIN(num_cols, (SidebarWidth - div_width)); int row = 0; - for (b = TopBuffy; b && (row < num_rows); b = b->next) + for (entryidx = TopIndex; (entryidx < EntryCount) && (row < num_rows); entryidx++) { - if (b->is_hidden) + entry = Entries[entryidx]; + if (entry->is_hidden) continue; + b = entry->buffy; - if (b == OpnBuffy) + if (entryidx == OpnIndex) { if ((ColorDefs[MT_COLOR_SB_INDICATOR] != 0)) SETCOLOR(MT_COLOR_SB_INDICATOR); else SETCOLOR(MT_COLOR_INDICATOR); } - else if (b == HilBuffy) + else if (entryidx == HilIndex) SETCOLOR(MT_COLOR_HIGHLIGHT); else if ((ColorDefs[MT_COLOR_SB_SPOOLFILE] != 0) && (mutt_strcmp (b->path, Spoolfile) == 0)) @@ -714,7 +612,7 @@ } } char str[STRING]; - make_sidebar_entry (str, sizeof (str), w, sidebar_folder_name, b); + make_sidebar_entry (str, sizeof (str), w, sidebar_folder_name, entry); printw ("%s", str); if (sidebar_folder_depth > 0) FREE (&sidebar_folder_name); @@ -756,6 +654,126 @@ } /** + * select_next - Selects the next unhidden mailbox + * + * Returns: + * 1: Success + * 0: Failure + */ +static int select_next (void) +{ + int entry = HilIndex; + + if (!EntryCount || HilIndex < 0) + return 0; + + do + { + entry++; + if (entry == EntryCount) + return 0; + } while (Entries[entry]->is_hidden); + + HilIndex = entry; + return 1; +} + +/** + * select_next_new - Selects the next new mailbox + * + * Search down the list of mail folders for one containing new mail. + * + * Returns: + * 1: Success + * 0: Failure + */ +static int select_next_new (void) +{ + int entry = HilIndex; + + if (!EntryCount || HilIndex < 0) + return 0; + + do + { + entry++; + if (entry == EntryCount) + { + if (option (OPTSIDEBARNEXTNEWWRAP)) + entry = 0; + else + return 0; + } + if (entry == HilIndex) + return 0; + } while (!Entries[entry]->buffy->new && + !Entries[entry]->buffy->msg_unread); + + HilIndex = entry; + return 1; +} + +/** + * select_prev - Selects the previous unhidden mailbox + * + * Returns: + * 1: Success + * 0: Failure + */ +static int select_prev (void) +{ + int entry = HilIndex; + + if (!EntryCount || HilIndex < 0) + return 0; + + do + { + entry--; + if (entry < 0) + return 0; + } while (Entries[entry]->is_hidden); + + HilIndex = entry; + return 1; +} + +/** + * select_prev_new - Selects the previous new mailbox + * + * Search up the list of mail folders for one containing new mail. + * + * Returns: + * 1: Success + * 0: Failure + */ +static int select_prev_new (void) +{ + int entry = HilIndex; + + if (!EntryCount || HilIndex < 0) + return 0; + + do + { + entry--; + if (entry < 0) + { + if (option (OPTSIDEBARNEXTNEWWRAP)) + entry = EntryCount - 1; + else + return 0; + } + if (entry == HilIndex) + return 0; + } while (!Entries[entry]->buffy->new && + !Entries[entry]->buffy->msg_unread); + + HilIndex = entry; + return 1; +} + +/** * mutt_sb_change_mailbox - Change the selected mailbox * @op: Operation code * @@ -775,49 +793,34 @@ if (!option (OPTSIDEBAR)) return; - BUFFY *b; - if (!HilBuffy) /* It'll get reset on the next draw */ + if (HilIndex < 0) /* It'll get reset on the next draw */ return; switch (op) { case OP_SIDEBAR_NEXT: - if (!HilBuffy->next) + if (! select_next ()) return; - if (HilBuffy->next->is_hidden) - return; - HilBuffy = HilBuffy->next; break; case OP_SIDEBAR_NEXT_NEW: - b = find_next_new (option (OPTSIDEBARNEXTNEWWRAP)); - if (!b) + if (! select_next_new ()) return; - else - HilBuffy = b; break; case OP_SIDEBAR_PAGE_DOWN: - HilBuffy = BotBuffy; - if (HilBuffy->next) - HilBuffy = HilBuffy->next; + HilIndex = BotIndex; + select_next (); break; case OP_SIDEBAR_PAGE_UP: - HilBuffy = TopBuffy; - if (HilBuffy != Incoming) - HilBuffy = HilBuffy->prev; + HilIndex = TopIndex; + select_prev (); break; case OP_SIDEBAR_PREV: - if (!HilBuffy->prev) + if (! select_prev ()) return; - if (HilBuffy->prev->is_hidden) /* Can't happen, we've sorted the hidden to the end */ - return; - HilBuffy = HilBuffy->prev; break; case OP_SIDEBAR_PREV_NEW: - b = find_prev_new (option (OPTSIDEBARNEXTNEWWRAP)); - if (!b) + if (! select_prev_new ()) return; - else - HilBuffy = b; break; default: return; @@ -865,10 +868,10 @@ if (!option (OPTSIDEBAR)) return NULL; - if (!HilBuffy) + if (!EntryCount || HilIndex < 0) return NULL; - return HilBuffy->path; + return Entries[HilIndex]->buffy->path; } /** @@ -877,28 +880,21 @@ * Search through the list of mailboxes. If a BUFFY has a matching path, set * OpnBuffy to it. */ -BUFFY *mutt_sb_set_open_buffy (void) +void mutt_sb_set_open_buffy (void) { - /* Even if the sidebar is hidden */ + int entry; - BUFFY *b = Incoming; + OpnIndex = -1; - OpnBuffy = NULL; - - if (!Context || !b) - return NULL; - - for (; b; b = b->next) + for (entry = 0; entry < EntryCount; entry++) { - if (!mutt_strcmp (b->realpath, Context->realpath)) + if (!mutt_strcmp (Entries[entry]->buffy->realpath, Context->realpath)) { - OpnBuffy = b; - HilBuffy = b; + OpnIndex = entry; + HilIndex = entry; break; } } - - return OpnBuffy; } /** @@ -912,6 +908,8 @@ */ void mutt_sb_notify_mailbox (BUFFY *b, int created) { + int del_index; + if (!b) return; @@ -920,35 +918,49 @@ if (created) { - if (!TopBuffy) - TopBuffy = b; - if (!HilBuffy) - HilBuffy = b; - if (!BotBuffy) - BotBuffy = b; - if (!Outgoing) - Outgoing = b; - if (!OpnBuffy && Context) + if (EntryCount >= EntryLen) { - /* This might happen if the user "unmailboxes *", then - * "mailboxes" our current mailbox back again */ - if (mutt_strcmp (b->realpath, Context->realpath) == 0) - OpnBuffy = b; + EntryLen += 10; + safe_realloc (&Entries, EntryLen * sizeof (SBENTRY *)); } + Entries[EntryCount] = safe_calloc (1, sizeof(SBENTRY)); + Entries[EntryCount]->buffy = b; + + if (TopIndex < 0) + TopIndex = EntryCount; + if (HilIndex < 0) + HilIndex = EntryCount; + if (BotIndex < 0) + BotIndex = EntryCount; + if ((OpnIndex < 0) && Context && + (mutt_strcmp (b->realpath, Context->realpath) == 0)) + OpnIndex = EntryCount; + + EntryCount++; } else { - BUFFY *replacement = buffy_going (b); - if (TopBuffy == b) - TopBuffy = replacement; - if (OpnBuffy == b) - OpnBuffy = NULL; - if (HilBuffy == b) - HilBuffy = replacement; - if (BotBuffy == b) - BotBuffy = replacement; - if (Outgoing == b) - Outgoing = replacement; + for (del_index = 0; del_index < EntryCount; del_index++) + if (Entries[del_index]->buffy == b) + break; + if (del_index == EntryCount) + return; + FREE (&Entries[del_index]); + EntryCount--; + + if (TopIndex > del_index || TopIndex == EntryCount) + TopIndex--;