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>
9 * This file is part of mutt-ng, see http://www.muttng.org/.
10 * It's licensed under the GNU General Public License,
11 * please see the file GPL in the top level source directory.
15 #include "mutt_menu.h"
16 #include "mutt_curses.h"
23 /*BUFFY *CurBuffy = 0;*/
24 static BUFFY *TopBuffy = 0;
25 static BUFFY *BottomBuffy = 0;
26 static int known_lines = 0;
27 static short initialized = 0;
28 static int prev_show_value;
29 static short saveSidebarWidth;
30 static char *entry = 0;
32 static int quick_log10 (int n)
36 for (; n > 9; len++, n /= 10);
40 /* CurBuffy should contain a valid buffy
41 * mailbox before calling this function!!! */
42 void calc_boundaries (int menu)
44 BUFFY *tmp = Incoming;
46 int i, count, mailbox_position;
48 /* correct known_lines if it has changed because of a window resize */
49 if (known_lines != LINES) {
52 /* fix all the prev links on all the mailboxes
53 * FIXME move this over to buffy.c where it belongs */
54 for (; tmp->next != 0; tmp = tmp->next)
55 tmp->next->prev = tmp;
57 /* calculate the position of the current mailbox */
60 while (tmp != CurBuffy) {
64 /* calculate the size of the screen we can use */
65 count = LINES - 2 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
66 /* calculate the position of the current mailbox on the screen */
67 mailbox_position = position % count;
68 if (mailbox_position == 0)
69 mailbox_position = count;
70 /* determine topbuffy */
72 for (i = mailbox_position; i > 1; i--)
73 TopBuffy = TopBuffy->prev;
74 /* determine bottombuffy */
75 BottomBuffy = CurBuffy;
76 for (i = mailbox_position; i < count && BottomBuffy->next; i++)
77 BottomBuffy = BottomBuffy->next;
80 static char *shortened_hierarchy (char *box)
87 for (i = 0; i < strlen (box); ++i) {
90 else if (isupper (box[i]))
91 return (safe_strdup (box));
93 last_dot = strrchr (box, '.');
96 new_box = safe_malloc (strlen (last_dot) + 2 * dots + 1);
98 for (i = 1, j = 1; i < strlen (box); ++i) {
102 if (&box[i + 1] != last_dot) {
103 new_box[j++] = box[i + 1];
107 strcat (&new_box[j], last_dot);
114 return safe_strdup (box);
117 char *make_sidebar_entry (char *box, int size, int new, int flagged)
119 int i = 0, dlen, max, shortened = 0;
122 if (SidebarWidth > COLS)
125 dlen = mutt_strlen (SidebarDelim);
126 max = SidebarWidth - dlen - 1;
128 safe_realloc (&entry, SidebarWidth + 1);
129 entry[SidebarWidth] = 0;
130 for (; i < SidebarWidth; entry[i++] = ' ');
132 if (ImapHomeNamespace && strlen (ImapHomeNamespace) > 0) {
133 if (strncmp (box, ImapHomeNamespace, strlen (ImapHomeNamespace)) == 0
134 && strcmp (box, ImapHomeNamespace) != 0) {
135 box += strlen (ImapHomeNamespace) + 1;
139 max -= quick_log10 (size);
141 max -= quick_log10 (new) + 2;
143 max -= quick_log10 (flagged) + 2;
144 if (option (OPTSHORTENHIERARCHY) && mutt_strlen (box) > max) {
145 box = shortened_hierarchy (box);
149 strncpy (entry, box, i < SidebarWidth - dlen ? i : SidebarWidth - dlen);
154 SidebarWidth - 5 - quick_log10 (size) - dlen - quick_log10 (new) -
155 quick_log10 (flagged);
158 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
159 "% d(%d)[%d]", size, new, flagged);
163 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (new);
166 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
167 "% d(%d)", size, new);
173 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (flagged);
176 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
177 "% d[%d]", size, flagged);
180 offset = SidebarWidth - 1 - quick_log10 (size) - dlen;
183 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
188 if (option (OPTSHORTENHIERARCHY) && shortened) {
194 void set_curbuffy (char buf[LONG_STRING])
196 BUFFY *tmp = CurBuffy = Incoming;
202 if (!strcmp (tmp->path, buf)) {
214 void set_buffystats (CONTEXT * Context)
216 BUFFY *tmp = Incoming;
221 if (strcmp (tmp->path, Context->path) == 0) {
222 tmp->new = Context->new;
223 tmp->msg_unread = Context->unread;
224 tmp->msgcount = Context->msgcount;
225 tmp->msg_flagged = Context->flagged;
232 int draw_sidebar (int menu)
235 int lines = option (OPTHELP) ? 1 : 0;
237 short delim_len = mutt_strlen (SidebarDelim);
239 /* initialize first time */
241 prev_show_value = option (OPTMBOXPANE);
242 saveSidebarWidth = SidebarWidth;
243 if (!option (OPTMBOXPANE))
248 /* save or restore the value SidebarWidth */
249 if (prev_show_value != option (OPTMBOXPANE)) {
250 if (prev_show_value && !option (OPTMBOXPANE)) {
251 saveSidebarWidth = SidebarWidth;
254 else if (!prev_show_value && option (OPTMBOXPANE)) {
255 SidebarWidth = saveSidebarWidth;
256 /* after toggle: force recounting of all mail */
257 mutt_buffy_check (2);
259 prev_show_value = option (OPTMBOXPANE);
262 if (SidebarWidth > 0 && option (OPTMBOXPANE)
263 && mutt_strlen (SidebarDelim) >= SidebarWidth) {
264 mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
266 unset_option (OPTMBOXPANE);
270 if (SidebarWidth == 0 || !option (OPTMBOXPANE))
273 /* draw the divider */
274 /* SETCOLOR(MT_COLOR_STATUS); */
275 SETCOLOR (MT_COLOR_SIDEBAR);
277 lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
279 move (lines, SidebarWidth - delim_len);
280 if (option (OPTASCIICHARS))
281 addstr (NONULL (SidebarDelim));
282 else if (!option (OPTASCIICHARS) && !strcmp (SidebarDelim, "|"))
284 else if ((Charset_is_utf8) && !strcmp (SidebarDelim, "|"))
285 addstr ("\342\224\202");
287 addstr (NONULL (SidebarDelim));
289 SETCOLOR (MT_COLOR_NORMAL);
293 lines = option (OPTHELP) ? 1 : 0; /* go back to the top */
298 if (known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0)
300 calc_boundaries (menu);
305 tmp && lines < LINES - 1 - (menu != MENU_PAGER
306 || option (OPTSTATUSONTOP));
309 SETCOLOR (MT_COLOR_INDICATOR);
310 else if (tmp->msg_flagged > 0)
311 SETCOLOR (MT_COLOR_FLAGGED);
312 else if (tmp->msg_unread > 0)
313 SETCOLOR (MT_COLOR_NEW);
315 SETCOLOR (MT_COLOR_NORMAL);
318 if (option (OPTSIDEBARNEWMAILONLY)) {
319 if (tmp->msg_unread > 0) {
320 if (Context && !strcmp (tmp->path, Context->path)) {
321 printw ("%.*s", SidebarWidth - delim_len,
322 make_sidebar_entry (basename (tmp->path),
323 Context->msgcount, Context->unread,
325 tmp->msg_unread = Context->unread;
326 tmp->msgcount = Context->msgcount;
327 tmp->msg_flagged = Context->flagged;
330 printw ("%.*s", SidebarWidth - delim_len,
331 make_sidebar_entry (basename (tmp->path),
332 tmp->msgcount, tmp->msg_unread,
338 if (Context && !strcmp (tmp->path, Context->path)) {
339 printw ("%.*s", SidebarWidth - delim_len,
340 make_sidebar_entry (basename (tmp->path),
341 Context->msgcount, Context->unread,
343 tmp->msg_unread = Context->unread;
344 tmp->msgcount = Context->msgcount;
345 tmp->msg_flagged = Context->flagged;
348 printw ("%.*s", SidebarWidth - delim_len,
349 make_sidebar_entry (basename (tmp->path),
350 tmp->msgcount, tmp->msg_unread,
355 SETCOLOR (MT_COLOR_NORMAL);
356 for (; lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
361 for (; i < SidebarWidth - delim_len; i++)
367 BUFFY *exist_next_new ()
369 BUFFY *tmp = CurBuffy;
373 while (tmp->next != NULL) {
381 BUFFY *exist_prev_new ()
383 BUFFY *tmp = CurBuffy;
387 while (tmp->prev != NULL) {
396 void scroll_sidebar (int op, int menu)
406 case OP_SIDEBAR_NEXT:
407 if (!option (OPTSIDEBARNEWMAILONLY)) {
408 if (CurBuffy->next == NULL) {
409 mutt_error (_("You are on the last mailbox."));
412 CurBuffy = CurBuffy->next;
414 } /* the fall-through is intentional */
415 case OP_SIDEBAR_NEXT_NEW:
416 if ((tmp = exist_next_new ()) == NULL) {
417 mutt_error (_("No next mailboxes with new mail."));
423 case OP_SIDEBAR_PREV:
424 if (!option (OPTSIDEBARNEWMAILONLY)) {
425 if (CurBuffy->prev == NULL) {
426 mutt_error (_("You are on the first mailbox."));
429 CurBuffy = CurBuffy->prev;
431 } /* the fall-through is intentional */
432 case OP_SIDEBAR_PREV_NEW:
433 if ((tmp = exist_prev_new ()) == NULL) {
434 mutt_error (_("No previous mailbox with new mail."));
441 case OP_SIDEBAR_SCROLL_UP:
443 if (CurBuffy != Incoming) {
444 calc_boundaries (menu);
445 CurBuffy = CurBuffy->prev;
448 case OP_SIDEBAR_SCROLL_DOWN:
449 CurBuffy = BottomBuffy;
450 if (CurBuffy->next) {
451 calc_boundaries (menu);
452 CurBuffy = CurBuffy->next;
458 calc_boundaries (menu);