2 * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu>
3 * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 #include "mutt_menu.h"
24 #include "mutt_curses.h"
31 /*BUFFY *CurBuffy = 0;*/
32 static BUFFY *TopBuffy = 0;
33 static BUFFY *BottomBuffy = 0;
34 static int known_lines = 0;
35 static short initialized = 0;
36 static int prev_show_value;
37 static short saveSidebarWidth;
38 static char *entry = 0;
40 static int quick_log10 (int n)
44 for (; n > 9; len++, n /= 10);
48 /* CurBuffy should contain a valid buffy
49 * mailbox before calling this function!!! */
50 void calc_boundaries (int menu)
52 BUFFY *tmp = Incoming;
54 int i, count, mailbox_position;
56 /* correct known_lines if it has changed because of a window resize */
57 if (known_lines != LINES) {
60 /* fix all the prev links on all the mailboxes
61 * FIXME move this over to buffy.c where it belongs */
62 for (; tmp->next != 0; tmp = tmp->next)
63 tmp->next->prev = tmp;
65 /* calculate the position of the current mailbox */
68 while (tmp != CurBuffy) {
72 /* calculate the size of the screen we can use */
73 count = LINES - 2 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
74 /* calculate the position of the current mailbox on the screen */
75 mailbox_position = position % count;
76 if (mailbox_position == 0)
77 mailbox_position = count;
78 /* determine topbuffy */
80 for (i = mailbox_position; i > 1; i--)
81 TopBuffy = TopBuffy->prev;
82 /* determine bottombuffy */
83 BottomBuffy = CurBuffy;
84 for (i = mailbox_position; i < count && BottomBuffy->next; i++)
85 BottomBuffy = BottomBuffy->next;
88 static char *shortened_hierarchy (char *box)
95 for (i = 0; i < strlen (box); ++i) {
98 else if (isupper (box[i]))
99 return (safe_strdup (box));
101 last_dot = strrchr (box, '.');
104 new_box = safe_malloc (strlen (last_dot) + 2 * dots + 1);
106 for (i = 1, j = 1; i < strlen (box); ++i) {
110 if (&box[i + 1] != last_dot) {
111 new_box[j++] = box[i + 1];
115 strcat (&new_box[j], last_dot);
122 return safe_strdup (box);
125 char *make_sidebar_entry (char *box, int size, int new, int flagged)
127 int i = 0, dlen, max, shortened = 0;
130 if (SidebarWidth > COLS)
133 dlen = mutt_strlen (SidebarDelim);
134 max = SidebarWidth - dlen - 1;
136 safe_realloc (&entry, SidebarWidth + 1);
137 entry[SidebarWidth] = 0;
138 for (; i < SidebarWidth; entry[i++] = ' ');
140 if (ImapHomeNamespace && strlen (ImapHomeNamespace) > 0) {
141 if (strncmp (box, ImapHomeNamespace, strlen (ImapHomeNamespace)) == 0
142 && strcmp (box, ImapHomeNamespace) != 0) {
143 box += strlen (ImapHomeNamespace) + 1;
147 max -= quick_log10 (size);
149 max -= quick_log10 (new) + 2;
151 max -= quick_log10 (flagged) + 2;
152 if (option (OPTSHORTENHIERARCHY) && mutt_strlen (box) > max) {
153 box = shortened_hierarchy (box);
157 strncpy (entry, box, i < SidebarWidth - dlen ? i : SidebarWidth - dlen);
162 SidebarWidth - 5 - quick_log10 (size) - dlen - quick_log10 (new) -
163 quick_log10 (flagged);
166 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
167 "% d(%d)[%d]", size, new, flagged);
171 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (new);
174 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
175 "% d(%d)", size, new);
181 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (flagged);
184 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
185 "% d[%d]", size, flagged);
188 offset = SidebarWidth - 1 - quick_log10 (size) - dlen;
191 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
196 if (option (OPTSHORTENHIERARCHY) && shortened) {
202 void set_curbuffy (char buf[LONG_STRING])
204 BUFFY *tmp = CurBuffy = Incoming;
210 if (!strcmp (tmp->path, buf)) {
222 void set_buffystats (CONTEXT * Context)
224 BUFFY *tmp = Incoming;
229 if (strcmp (tmp->path, Context->path) == 0) {
230 tmp->new = Context->new;
231 tmp->msg_unread = Context->unread;
232 tmp->msgcount = Context->msgcount;
233 tmp->msg_flagged = Context->flagged;
240 int draw_sidebar (int menu)
243 int lines = option (OPTHELP) ? 1 : 0;
245 short delim_len = mutt_strlen (SidebarDelim);
247 /* initialize first time */
249 prev_show_value = option (OPTMBOXPANE);
250 saveSidebarWidth = SidebarWidth;
251 if (!option (OPTMBOXPANE))
256 /* save or restore the value SidebarWidth */
257 if (prev_show_value != option (OPTMBOXPANE)) {
258 if (prev_show_value && !option (OPTMBOXPANE)) {
259 saveSidebarWidth = SidebarWidth;
262 else if (!prev_show_value && option (OPTMBOXPANE)) {
263 SidebarWidth = saveSidebarWidth;
264 /* after toggle: force recounting of all mail */
265 mutt_buffy_check (2);
267 prev_show_value = option (OPTMBOXPANE);
270 if (SidebarWidth > 0 && option (OPTMBOXPANE)
271 && mutt_strlen (SidebarDelim) >= SidebarWidth) {
272 mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
274 unset_option (OPTMBOXPANE);
278 if (SidebarWidth == 0 || !option (OPTMBOXPANE))
281 /* draw the divider */
282 /* SETCOLOR(MT_COLOR_STATUS); */
283 SETCOLOR (MT_COLOR_SIDEBAR);
285 lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
287 move (lines, SidebarWidth - delim_len);
288 if (option (OPTASCIICHARS))
289 addstr (NONULL (SidebarDelim));
290 else if (!option (OPTASCIICHARS) && !strcmp (SidebarDelim, "|"))
292 else if ((Charset_is_utf8) && !strcmp (SidebarDelim, "|"))
293 addstr ("\342\224\202");
295 addstr (NONULL (SidebarDelim));
297 SETCOLOR (MT_COLOR_NORMAL);
301 lines = option (OPTHELP) ? 1 : 0; /* go back to the top */
306 if (known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0)
308 calc_boundaries (menu);
313 tmp && lines < LINES - 1 - (menu != MENU_PAGER
314 || option (OPTSTATUSONTOP));
317 SETCOLOR (MT_COLOR_INDICATOR);
318 else if (tmp->msg_flagged > 0)
319 SETCOLOR (MT_COLOR_FLAGGED);
320 else if (tmp->msg_unread > 0)
321 SETCOLOR (MT_COLOR_NEW);
323 SETCOLOR (MT_COLOR_NORMAL);
326 if (option (OPTSIDEBARNEWMAILONLY)) {
327 if (tmp->msg_unread > 0) {
328 if (Context && !strcmp (tmp->path, Context->path)) {
329 printw ("%.*s", SidebarWidth - delim_len,
330 make_sidebar_entry (basename (tmp->path),
331 Context->msgcount, Context->unread,
333 tmp->msg_unread = Context->unread;
334 tmp->msgcount = Context->msgcount;
335 tmp->msg_flagged = Context->flagged;
338 printw ("%.*s", SidebarWidth - delim_len,
339 make_sidebar_entry (basename (tmp->path),
340 tmp->msgcount, tmp->msg_unread,
346 if (Context && !strcmp (tmp->path, Context->path)) {
347 printw ("%.*s", SidebarWidth - delim_len,
348 make_sidebar_entry (basename (tmp->path),
349 Context->msgcount, Context->unread,
351 tmp->msg_unread = Context->unread;
352 tmp->msgcount = Context->msgcount;
353 tmp->msg_flagged = Context->flagged;
356 printw ("%.*s", SidebarWidth - delim_len,
357 make_sidebar_entry (basename (tmp->path),
358 tmp->msgcount, tmp->msg_unread,
363 SETCOLOR (MT_COLOR_NORMAL);
364 for (; lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
369 for (; i < SidebarWidth - delim_len; i++)
375 BUFFY *exist_next_new ()
377 BUFFY *tmp = CurBuffy;
381 while (tmp->next != NULL) {
389 BUFFY *exist_prev_new ()
391 BUFFY *tmp = CurBuffy;
395 while (tmp->prev != NULL) {
404 void scroll_sidebar (int op, int menu)
414 case OP_SIDEBAR_NEXT:
415 if (!option (OPTSIDEBARNEWMAILONLY)) {
416 if (CurBuffy->next == NULL) {
417 mutt_error (_("You are on the last mailbox."));
420 CurBuffy = CurBuffy->next;
422 } /* the fall-through is intentional */
423 case OP_SIDEBAR_NEXT_NEW:
424 if ((tmp = exist_next_new ()) == NULL) {
425 mutt_error (_("No next mailboxes with new mail."));
431 case OP_SIDEBAR_PREV:
432 if (!option (OPTSIDEBARNEWMAILONLY)) {
433 if (CurBuffy->prev == NULL) {
434 mutt_error (_("You are on the first mailbox."));
437 CurBuffy = CurBuffy->prev;
439 } /* the fall-through is intentional */
440 case OP_SIDEBAR_PREV_NEW:
441 if ((tmp = exist_prev_new ()) == NULL) {
442 mutt_error (_("No previous mailbox with new mail."));
449 case OP_SIDEBAR_SCROLL_UP:
451 if (CurBuffy != Incoming) {
452 calc_boundaries (menu);
453 CurBuffy = CurBuffy->prev;
456 case OP_SIDEBAR_SCROLL_DOWN:
457 CurBuffy = BottomBuffy;
458 if (CurBuffy->next) {
459 calc_boundaries (menu);
460 CurBuffy = CurBuffy->next;
466 calc_boundaries (menu);