2 * Copyright notice from original mutt:
3 * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu>
4 * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
6 * Parts were written/modified by:
7 * Rocco Rutte <pdmef@cs.tu-berlin.de>
8 * Nico Golde <nico@ngolde.de>
10 * This file is part of mutt-ng, see http://www.muttng.org/.
11 * It's licensed under the GNU General Public License,
12 * please see the file GPL in the top level source directory.
16 #include "mutt_menu.h"
17 #include "mutt_curses.h"
29 /*BUFFY *CurBuffy = 0;*/
30 static BUFFY *TopBuffy = 0;
31 static BUFFY *BottomBuffy = 0;
32 static int known_lines = 0;
33 static short initialized = 0;
34 static int prev_show_value;
35 static short saveSidebarWidth;
36 static char *entry = 0;
38 static int quick_log10 (int n)
42 for (; n > 9; len++, n /= 10);
46 /* CurBuffy should contain a valid buffy
47 * mailbox before calling this function!!! */
48 void calc_boundaries (int menu)
50 BUFFY *tmp = Incoming;
52 int i, count, mailbox_position;
54 /* correct known_lines if it has changed because of a window resize */
55 if (known_lines != LINES) {
58 /* fix all the prev links on all the mailboxes
59 * FIXME move this over to buffy.c where it belongs */
60 for (; tmp->next != 0; tmp = tmp->next)
61 tmp->next->prev = tmp;
63 /* calculate the position of the current mailbox */
66 while (tmp != CurBuffy) {
70 /* calculate the size of the screen we can use */
71 count = LINES - 2 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
72 /* calculate the position of the current mailbox on the screen */
73 mailbox_position = position % count;
74 if (mailbox_position == 0)
75 mailbox_position = count;
76 /* determine topbuffy */
78 for (i = mailbox_position; i > 1; i--)
79 TopBuffy = TopBuffy->prev;
80 /* determine bottombuffy */
81 BottomBuffy = CurBuffy;
82 for (i = mailbox_position; i < count && BottomBuffy->next; i++)
83 BottomBuffy = BottomBuffy->next;
86 static char *shortened_hierarchy (char *box)
93 for (i = 0; i < mutt_strlen (box); ++i) {
96 else if (isupper (box[i]))
97 return (safe_strdup (box));
99 last_dot = strrchr (box, '.');
102 new_box = safe_malloc (mutt_strlen (last_dot) + 2 * dots + 1);
104 for (i = 1, j = 1; i < mutt_strlen (box); ++i) {
108 if (&box[i + 1] != last_dot) {
109 new_box[j++] = box[i + 1];
113 strcat (&new_box[j], last_dot);
120 return safe_strdup (box);
123 char *make_sidebar_entry (char *box, int size, int new, int flagged)
125 int i = 0, dlen, max, shortened = 0;
128 if (SidebarWidth > COLS)
131 dlen = mutt_strlen (SidebarDelim);
132 max = SidebarWidth - dlen - 1;
134 safe_realloc (&entry, SidebarWidth + 1);
135 entry[SidebarWidth] = 0;
136 for (; i < SidebarWidth; entry[i++] = ' ');
138 if (ImapHomeNamespace && mutt_strlen (ImapHomeNamespace) > 0) {
139 if (strncmp (box, ImapHomeNamespace, mutt_strlen (ImapHomeNamespace)) == 0
140 && strcmp (box, ImapHomeNamespace) != 0) {
141 box += mutt_strlen (ImapHomeNamespace) + 1;
145 max -= quick_log10 (size);
147 max -= quick_log10 (new) + 2;
149 max -= quick_log10 (flagged) + 2;
150 if (option (OPTSHORTENHIERARCHY) && mutt_strlen (box) > max) {
151 box = shortened_hierarchy (box);
154 i = mutt_strlen (box);
155 strncpy (entry, box, i < SidebarWidth - dlen ? i : SidebarWidth - dlen);
160 SidebarWidth - 5 - quick_log10 (size) - dlen - quick_log10 (new) -
161 quick_log10 (flagged);
164 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
165 "% d(%d)[%d]", size, new, flagged);
169 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (new);
172 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
173 "% d(%d)", size, new);
179 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (flagged);
182 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
183 "% d[%d]", size, flagged);
186 offset = SidebarWidth - 1 - quick_log10 (size) - dlen;
189 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
194 if (option (OPTSHORTENHIERARCHY) && shortened) {
200 void set_curbuffy (char buf[LONG_STRING])
202 BUFFY *tmp = CurBuffy = Incoming;
208 if (!mutt_strcmp (tmp->path, buf)) {
220 void set_buffystats (CONTEXT * Context)
222 BUFFY *tmp = Incoming;
227 if (mutt_strcmp (tmp->path, Context->path) == 0) {
228 tmp->new = Context->new;
229 tmp->msg_unread = Context->unread;
230 tmp->msgcount = Context->msgcount;
231 tmp->msg_flagged = Context->flagged;
238 int draw_sidebar (int menu)
241 int lines = option (OPTHELP) ? 1 : 0;
243 short delim_len = mutt_strlen (SidebarDelim);
245 /* initialize first time */
247 prev_show_value = option (OPTMBOXPANE);
248 saveSidebarWidth = SidebarWidth;
249 if (!option (OPTMBOXPANE))
254 /* save or restore the value SidebarWidth */
255 if (prev_show_value != option (OPTMBOXPANE)) {
256 if (prev_show_value && !option (OPTMBOXPANE)) {
257 saveSidebarWidth = SidebarWidth;
260 else if (!prev_show_value && option (OPTMBOXPANE)) {
261 SidebarWidth = saveSidebarWidth;
262 /* after toggle: force recounting of all mail */
263 mutt_buffy_check (2);
265 prev_show_value = option (OPTMBOXPANE);
268 if (SidebarWidth > 0 && option (OPTMBOXPANE)
269 && mutt_strlen (SidebarDelim) >= SidebarWidth) {
270 mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
272 unset_option (OPTMBOXPANE);
276 if (SidebarWidth == 0 || !option (OPTMBOXPANE))
279 /* draw the divider */
280 /* SETCOLOR(MT_COLOR_STATUS); */
281 SETCOLOR (MT_COLOR_SIDEBAR);
283 lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
285 move (lines, SidebarWidth - delim_len);
286 if (option (OPTASCIICHARS))
287 addstr (NONULL (SidebarDelim));
288 else if (!option (OPTASCIICHARS) && !mutt_strcmp (SidebarDelim, "|"))
290 else if ((Charset_is_utf8) && !mutt_strcmp (SidebarDelim, "|"))
291 addstr ("\342\224\202");
293 addstr (NONULL (SidebarDelim));
295 SETCOLOR (MT_COLOR_NORMAL);
299 lines = option (OPTHELP) ? 1 : 0; /* go back to the top */
304 if (known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0)
306 calc_boundaries (menu);
311 tmp && lines < LINES - 1 - (menu != MENU_PAGER
312 || option (OPTSTATUSONTOP));
315 SETCOLOR (MT_COLOR_INDICATOR);
316 else if (tmp->msg_flagged > 0)
317 SETCOLOR (MT_COLOR_FLAGGED);
318 else if (tmp->msg_unread > 0)
319 SETCOLOR (MT_COLOR_NEW);
321 SETCOLOR (MT_COLOR_NORMAL);
324 if (option (OPTSIDEBARNEWMAILONLY)) {
325 if (tmp->msg_unread > 0) {
326 if (Context && !mutt_strcmp (tmp->path, Context->path)) {
327 printw ("%.*s", SidebarWidth - delim_len,
328 make_sidebar_entry (basename (tmp->path),
329 Context->msgcount, Context->unread,
331 tmp->msg_unread = Context->unread;
332 tmp->msgcount = Context->msgcount;
333 tmp->msg_flagged = Context->flagged;
336 printw ("%.*s", SidebarWidth - delim_len,
337 make_sidebar_entry (basename (tmp->path),
338 tmp->msgcount, tmp->msg_unread,
344 if (Context && !strcmp (tmp->path, Context->path)) {
345 printw ("%.*s", SidebarWidth - delim_len,
346 make_sidebar_entry (basename (tmp->path),
347 Context->msgcount, Context->unread,
349 tmp->msg_unread = Context->unread;
350 tmp->msgcount = Context->msgcount;
351 tmp->msg_flagged = Context->flagged;
354 printw ("%.*s", SidebarWidth - delim_len,
355 make_sidebar_entry (basename (tmp->path),
356 tmp->msgcount, tmp->msg_unread,
361 SETCOLOR (MT_COLOR_NORMAL);
362 for (; lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
367 for (; i < SidebarWidth - delim_len; i++)
373 BUFFY *exist_next_new ()
375 BUFFY *tmp = CurBuffy;
379 while (tmp->next != NULL) {
387 BUFFY *exist_prev_new ()
389 BUFFY *tmp = CurBuffy;
393 while (tmp->prev != NULL) {
402 void scroll_sidebar (int op, int menu)
412 case OP_SIDEBAR_NEXT:
413 if (!option (OPTSIDEBARNEWMAILONLY)) {
414 if (CurBuffy->next == NULL) {
415 mutt_error (_("You are on the last mailbox."));
418 CurBuffy = CurBuffy->next;
420 } /* the fall-through is intentional */
421 case OP_SIDEBAR_NEXT_NEW:
422 if ((tmp = exist_next_new ()) == NULL) {
423 mutt_error (_("No next mailboxes with new mail."));
429 case OP_SIDEBAR_PREV:
430 if (!option (OPTSIDEBARNEWMAILONLY)) {
431 if (CurBuffy->prev == NULL) {
432 mutt_error (_("You are on the first mailbox."));
435 CurBuffy = CurBuffy->prev;
437 } /* the fall-through is intentional */
438 case OP_SIDEBAR_PREV_NEW:
439 if ((tmp = exist_prev_new ()) == NULL) {
440 mutt_error (_("No previous mailbox with new mail."));
447 case OP_SIDEBAR_SCROLL_UP:
449 if (CurBuffy != Incoming) {
450 calc_boundaries (menu);
451 CurBuffy = CurBuffy->prev;
454 case OP_SIDEBAR_SCROLL_DOWN:
455 CurBuffy = BottomBuffy;
456 if (CurBuffy->next) {
457 calc_boundaries (menu);
458 CurBuffy = CurBuffy->next;
464 calc_boundaries (menu);