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 * This file is part of mutt-ng, see http://www.muttng.org/.
7 * It's licensed under the GNU General Public License,
8 * please see the file GPL in the top level source directory.
12 #include "mutt_menu.h"
13 #include "mutt_curses.h"
20 /*BUFFY *CurBuffy = 0;*/
21 static BUFFY *TopBuffy = 0;
22 static BUFFY *BottomBuffy = 0;
23 static int known_lines = 0;
24 static short initialized = 0;
25 static int prev_show_value;
26 static short saveSidebarWidth;
27 static char *entry = 0;
29 static int quick_log10 (int n)
33 for (; n > 9; len++, n /= 10);
37 /* CurBuffy should contain a valid buffy
38 * mailbox before calling this function!!! */
39 void calc_boundaries (int menu)
41 BUFFY *tmp = Incoming;
43 int i, count, mailbox_position;
45 /* correct known_lines if it has changed because of a window resize */
46 if (known_lines != LINES) {
49 /* fix all the prev links on all the mailboxes
50 * FIXME move this over to buffy.c where it belongs */
51 for (; tmp->next != 0; tmp = tmp->next)
52 tmp->next->prev = tmp;
54 /* calculate the position of the current mailbox */
57 while (tmp != CurBuffy) {
61 /* calculate the size of the screen we can use */
62 count = LINES - 2 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
63 /* calculate the position of the current mailbox on the screen */
64 mailbox_position = position % count;
65 if (mailbox_position == 0)
66 mailbox_position = count;
67 /* determine topbuffy */
69 for (i = mailbox_position; i > 1; i--)
70 TopBuffy = TopBuffy->prev;
71 /* determine bottombuffy */
72 BottomBuffy = CurBuffy;
73 for (i = mailbox_position; i < count && BottomBuffy->next; i++)
74 BottomBuffy = BottomBuffy->next;
77 static char *shortened_hierarchy (char *box)
84 for (i = 0; i < strlen (box); ++i) {
87 else if (isupper (box[i]))
88 return (safe_strdup (box));
90 last_dot = strrchr (box, '.');
93 new_box = safe_malloc (strlen (last_dot) + 2 * dots + 1);
95 for (i = 1, j = 1; i < strlen (box); ++i) {
99 if (&box[i + 1] != last_dot) {
100 new_box[j++] = box[i + 1];
104 strcat (&new_box[j], last_dot);
111 return safe_strdup (box);
114 char *make_sidebar_entry (char *box, int size, int new, int flagged)
116 int i = 0, dlen, max, shortened = 0;
119 if (SidebarWidth > COLS)
122 dlen = mutt_strlen (SidebarDelim);
123 max = SidebarWidth - dlen - 1;
125 safe_realloc (&entry, SidebarWidth + 1);
126 entry[SidebarWidth] = 0;
127 for (; i < SidebarWidth; entry[i++] = ' ');
129 if (ImapHomeNamespace && strlen (ImapHomeNamespace) > 0) {
130 if (strncmp (box, ImapHomeNamespace, strlen (ImapHomeNamespace)) == 0
131 && strcmp (box, ImapHomeNamespace) != 0) {
132 box += strlen (ImapHomeNamespace) + 1;
136 max -= quick_log10 (size);
138 max -= quick_log10 (new) + 2;
140 max -= quick_log10 (flagged) + 2;
141 if (option (OPTSHORTENHIERARCHY) && mutt_strlen (box) > max) {
142 box = shortened_hierarchy (box);
146 strncpy (entry, box, i < SidebarWidth - dlen ? i : SidebarWidth - dlen);
151 SidebarWidth - 5 - quick_log10 (size) - dlen - quick_log10 (new) -
152 quick_log10 (flagged);
155 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
156 "% d(%d)[%d]", size, new, flagged);
160 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (new);
163 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
164 "% d(%d)", size, new);
170 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (flagged);
173 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
174 "% d[%d]", size, flagged);
177 offset = SidebarWidth - 1 - quick_log10 (size) - dlen;
180 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
185 if (option (OPTSHORTENHIERARCHY) && shortened) {
191 void set_curbuffy (char buf[LONG_STRING])
193 BUFFY *tmp = CurBuffy = Incoming;
199 if (!strcmp (tmp->path, buf)) {
211 void set_buffystats (CONTEXT * Context)
213 BUFFY *tmp = Incoming;
218 if (strcmp (tmp->path, Context->path) == 0) {
219 tmp->new = Context->new;
220 tmp->msg_unread = Context->unread;
221 tmp->msgcount = Context->msgcount;
222 tmp->msg_flagged = Context->flagged;
229 int draw_sidebar (int menu)
232 int lines = option (OPTHELP) ? 1 : 0;
234 short delim_len = mutt_strlen (SidebarDelim);
236 /* initialize first time */
238 prev_show_value = option (OPTMBOXPANE);
239 saveSidebarWidth = SidebarWidth;
240 if (!option (OPTMBOXPANE))
245 /* save or restore the value SidebarWidth */
246 if (prev_show_value != option (OPTMBOXPANE)) {
247 if (prev_show_value && !option (OPTMBOXPANE)) {
248 saveSidebarWidth = SidebarWidth;
251 else if (!prev_show_value && option (OPTMBOXPANE)) {
252 SidebarWidth = saveSidebarWidth;
253 /* after toggle: force recounting of all mail */
254 mutt_buffy_check (2);
256 prev_show_value = option (OPTMBOXPANE);
259 if (SidebarWidth > 0 && option (OPTMBOXPANE)
260 && mutt_strlen (SidebarDelim) >= SidebarWidth) {
261 mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
263 unset_option (OPTMBOXPANE);
267 if (SidebarWidth == 0 || !option (OPTMBOXPANE))
270 /* draw the divider */
271 /* SETCOLOR(MT_COLOR_STATUS); */
272 SETCOLOR (MT_COLOR_SIDEBAR);
274 lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
276 move (lines, SidebarWidth - delim_len);
277 if (option (OPTASCIICHARS))
278 addstr (NONULL (SidebarDelim));
279 else if (!option (OPTASCIICHARS) && !strcmp (SidebarDelim, "|"))
281 else if ((Charset_is_utf8) && !strcmp (SidebarDelim, "|"))
282 addstr ("\342\224\202");
284 addstr (NONULL (SidebarDelim));
286 SETCOLOR (MT_COLOR_NORMAL);
290 lines = option (OPTHELP) ? 1 : 0; /* go back to the top */
295 if (known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0)
297 calc_boundaries (menu);
302 tmp && lines < LINES - 1 - (menu != MENU_PAGER
303 || option (OPTSTATUSONTOP));
306 SETCOLOR (MT_COLOR_INDICATOR);
307 else if (tmp->msg_flagged > 0)
308 SETCOLOR (MT_COLOR_FLAGGED);
309 else if (tmp->msg_unread > 0)
310 SETCOLOR (MT_COLOR_NEW);
312 SETCOLOR (MT_COLOR_NORMAL);
315 if (option (OPTSIDEBARNEWMAILONLY)) {
316 if (tmp->msg_unread > 0) {
317 if (Context && !strcmp (tmp->path, Context->path)) {
318 printw ("%.*s", SidebarWidth - delim_len,
319 make_sidebar_entry (basename (tmp->path),
320 Context->msgcount, Context->unread,
322 tmp->msg_unread = Context->unread;
323 tmp->msgcount = Context->msgcount;
324 tmp->msg_flagged = Context->flagged;
327 printw ("%.*s", SidebarWidth - delim_len,
328 make_sidebar_entry (basename (tmp->path),
329 tmp->msgcount, tmp->msg_unread,
335 if (Context && !strcmp (tmp->path, Context->path)) {
336 printw ("%.*s", SidebarWidth - delim_len,
337 make_sidebar_entry (basename (tmp->path),
338 Context->msgcount, Context->unread,
340 tmp->msg_unread = Context->unread;
341 tmp->msgcount = Context->msgcount;
342 tmp->msg_flagged = Context->flagged;
345 printw ("%.*s", SidebarWidth - delim_len,
346 make_sidebar_entry (basename (tmp->path),
347 tmp->msgcount, tmp->msg_unread,
352 SETCOLOR (MT_COLOR_NORMAL);
353 for (; lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
358 for (; i < SidebarWidth - delim_len; i++)
364 BUFFY *exist_next_new ()
366 BUFFY *tmp = CurBuffy;
370 while (tmp->next != NULL) {
378 BUFFY *exist_prev_new ()
380 BUFFY *tmp = CurBuffy;
384 while (tmp->prev != NULL) {
393 void scroll_sidebar (int op, int menu)
403 case OP_SIDEBAR_NEXT:
404 if (!option (OPTSIDEBARNEWMAILONLY)) {
405 if (CurBuffy->next == NULL) {
406 mutt_error (_("You are on the last mailbox."));
409 CurBuffy = CurBuffy->next;
411 } /* the fall-through is intentional */
412 case OP_SIDEBAR_NEXT_NEW:
413 if ((tmp = exist_next_new ()) == NULL) {
414 mutt_error (_("No next mailboxes with new mail."));
420 case OP_SIDEBAR_PREV:
421 if (!option (OPTSIDEBARNEWMAILONLY)) {
422 if (CurBuffy->prev == NULL) {
423 mutt_error (_("You are on the first mailbox."));
426 CurBuffy = CurBuffy->prev;
428 } /* the fall-through is intentional */
429 case OP_SIDEBAR_PREV_NEW:
430 if ((tmp = exist_prev_new ()) == NULL) {
431 mutt_error (_("No previous mailbox with new mail."));
438 case OP_SIDEBAR_SCROLL_UP:
440 if (CurBuffy != Incoming) {
441 calc_boundaries (menu);
442 CurBuffy = CurBuffy->prev;
445 case OP_SIDEBAR_SCROLL_DOWN:
446 CurBuffy = BottomBuffy;
447 if (CurBuffy->next) {
448 calc_boundaries (menu);
449 CurBuffy = CurBuffy->next;
455 calc_boundaries (menu);