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 static int TopBuffy = 0;
30 static int CurBuffy = 0;
31 static int known_lines = 0;
32 static short initialized = 0;
33 static int prev_show_value;
34 static short saveSidebarWidth;
35 static char *entry = 0;
37 /* computes how many digets a number has;
38 * FIXME move out to library?
40 static int quick_log10 (int n) {
43 for (; n > 9; len++, n /= 10);
47 /* computes first entry to be shown */
48 void calc_boundaries (int menu)
52 if (list_empty(Incoming))
54 /* correct known_lines if it has changed because of a window resize */
55 if (known_lines != LINES)
57 lines = LINES - 2 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
58 TopBuffy = CurBuffy - (CurBuffy % lines);
63 /* compresses hierarchy in folder names;
64 * FIXME move out to library?
66 static char *shortened_hierarchy (char *box)
73 for (i = 0; i < mutt_strlen (box); ++i) {
76 else if (isupper (box[i]))
77 return (safe_strdup (box));
79 last_dot = strrchr (box, '.');
82 new_box = safe_malloc (mutt_strlen (last_dot) + 2 * dots + 1);
84 for (i = 1, j = 1; i < mutt_strlen (box); ++i) {
88 if (&box[i + 1] != last_dot) {
89 new_box[j++] = box[i + 1];
93 strcat (&new_box[j], last_dot);
100 return safe_strdup (box);
104 * FIXME this is completely fucked up right now
106 char *make_sidebar_entry (char *box, int size, int new, int flagged)
108 int i = 0, dlen, max, shortened = 0;
111 if (SidebarWidth > COLS)
114 dlen = mutt_strlen (SidebarDelim);
115 max = SidebarWidth - dlen - 1;
117 safe_realloc (&entry, SidebarWidth + 1);
118 entry[SidebarWidth] = 0;
119 for (; i < SidebarWidth; entry[i++] = ' ');
121 if (ImapHomeNamespace && mutt_strlen (ImapHomeNamespace) > 0) {
122 if (strncmp (box, ImapHomeNamespace, mutt_strlen (ImapHomeNamespace)) == 0
123 && strcmp (box, ImapHomeNamespace) != 0) {
124 box += mutt_strlen (ImapHomeNamespace) + 1;
128 max -= quick_log10 (size);
130 max -= quick_log10 (new) + 2;
132 max -= quick_log10 (flagged) + 2;
133 if (option (OPTSHORTENHIERARCHY) && mutt_strlen (box) > max) {
134 box = shortened_hierarchy (box);
137 i = mutt_strlen (box);
138 strncpy (entry, box, i < SidebarWidth - dlen ? i : SidebarWidth - dlen);
143 SidebarWidth - 5 - quick_log10 (size) - dlen - quick_log10 (new) -
144 quick_log10 (flagged);
147 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
148 "% d(%d)[%d]", size, new, flagged);
152 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (new);
155 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
156 "% d(%d)", size, new);
162 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (flagged);
165 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
166 "% d[%d]", size, flagged);
169 offset = SidebarWidth - 1 - quick_log10 (size) - dlen;
172 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
177 if (option (OPTSHORTENHIERARCHY) && shortened) {
183 /* returns folder name of currently
184 * selected folder for <sidebar-open>
186 const char* sidebar_get_current (void) {
187 if (list_empty(Incoming))
189 return ((char*) ((BUFFY*) Incoming->data[CurBuffy])->path);
192 /* internally sets item to buf */
193 void sidebar_set_current (const char* buf) {
194 int i = buffy_lookup (buf);
199 /* fix counters for a context
200 * FIXME since ctx must not be of our business, move it elsewhere
202 void sidebar_set_buffystats (CONTEXT* Context) {
205 if (!Context || list_empty(Incoming) || (i = buffy_lookup (Context->path)) < 0)
207 tmp = (BUFFY*) Incoming->data[i];
208 tmp->new = Context->new;
209 tmp->msg_unread = Context->unread;
210 tmp->msgcount = Context->msgcount;
211 tmp->msg_flagged = Context->flagged;
214 /* actually draws something
215 * FIXME this needs some clue when to do it
216 * FIXME this is completely fucked up right now
218 int sidebar_draw (int menu)
221 int lines = option (OPTHELP) ? 1 : 0;
224 short delim_len = mutt_strlen (SidebarDelim);
226 /* initialize first time */
228 prev_show_value = option (OPTMBOXPANE);
229 saveSidebarWidth = SidebarWidth;
230 if (!option (OPTMBOXPANE))
235 /* save or restore the value SidebarWidth */
236 if (prev_show_value != option (OPTMBOXPANE)) {
237 if (prev_show_value && !option (OPTMBOXPANE)) {
238 saveSidebarWidth = SidebarWidth;
241 else if (!prev_show_value && option (OPTMBOXPANE)) {
242 SidebarWidth = saveSidebarWidth;
243 /* after toggle: force recounting of all mail */
244 mutt_buffy_check (2);
246 prev_show_value = option (OPTMBOXPANE);
249 if (SidebarWidth > 0 && option (OPTMBOXPANE)
250 && mutt_strlen (SidebarDelim) >= SidebarWidth) {
251 mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
253 unset_option (OPTMBOXPANE);
257 if (SidebarWidth == 0 || !option (OPTMBOXPANE))
260 /* draw the divider */
261 SETCOLOR (MT_COLOR_SIDEBAR);
263 lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
265 move (lines, SidebarWidth - delim_len);
266 if (option (OPTASCIICHARS))
267 addstr (NONULL (SidebarDelim));
268 else if (!option (OPTASCIICHARS) && !mutt_strcmp (SidebarDelim, "|"))
270 else if ((Charset_is_utf8) && !mutt_strcmp (SidebarDelim, "|"))
271 addstr ("\342\224\202");
273 addstr (NONULL (SidebarDelim));
275 SETCOLOR (MT_COLOR_NORMAL);
277 if (list_empty(Incoming))
280 lines = option (OPTHELP) ? 1 : 0; /* go back to the top */
282 calc_boundaries (menu);
284 for (i = TopBuffy; i < Incoming->length && lines < LINES - 1 -
285 (menu != MENU_PAGER || option (OPTSTATUSONTOP)); i++) {
286 tmp = (BUFFY*) Incoming->data[i];
288 SETCOLOR (MT_COLOR_INDICATOR);
289 else if (tmp->msg_flagged > 0)
290 SETCOLOR (MT_COLOR_FLAGGED);
291 else if (tmp->msg_unread > 0)
292 SETCOLOR (MT_COLOR_NEW);
294 SETCOLOR (MT_COLOR_NORMAL);
297 if (option (OPTSIDEBARNEWMAILONLY)) {
298 if (tmp->msg_unread > 0) {
299 if (Context && !mutt_strcmp (tmp->path, Context->path)) {
300 printw ("%.*s", SidebarWidth - delim_len,
301 make_sidebar_entry (basename (tmp->path),
302 Context->msgcount, Context->unread,
304 tmp->msg_unread = Context->unread;
305 tmp->msgcount = Context->msgcount;
306 tmp->msg_flagged = Context->flagged;
309 printw ("%.*s", SidebarWidth - delim_len,
310 make_sidebar_entry (basename (tmp->path),
311 tmp->msgcount, tmp->msg_unread,
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,
334 SETCOLOR (MT_COLOR_NORMAL);
335 for (; lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
340 for (; i < SidebarWidth - delim_len; i++)
346 /* returns index of new item with new mail or -1 */
347 static int exist_next_new () {
349 if (list_empty(Incoming))
352 while (i < Incoming->length)
353 if (((BUFFY*) Incoming->data[i++])->msg_unread)
358 /* returns index of prev item with new mail or -1 */
359 static int exist_prev_new () {
361 if (list_empty(Incoming))
365 if (((BUFFY*) Incoming->data[i--])->msg_unread)
370 void sidebar_scroll (int op, int menu) {
373 if (!SidebarWidth || list_empty(Incoming))
377 case OP_SIDEBAR_NEXT:
378 if (!option (OPTSIDEBARNEWMAILONLY)) {
379 if (CurBuffy + 1 == Incoming->length) {
380 mutt_error (_("You are on the last mailbox."));
385 } /* the fall-through is intentional */
386 case OP_SIDEBAR_NEXT_NEW:
387 if ((i = exist_next_new ()) < 0) {
388 mutt_error (_("No next mailboxes with new mail."));
394 case OP_SIDEBAR_PREV:
395 if (!option (OPTSIDEBARNEWMAILONLY)) {
397 mutt_error (_("You are on the first mailbox."));
402 } /* the fall-through is intentional */
403 case OP_SIDEBAR_PREV_NEW:
404 if ((i = exist_prev_new ()) < 0) {
405 mutt_error (_("No previous mailbox with new mail."));
412 case OP_SIDEBAR_SCROLL_UP:
414 mutt_error (_("You are on the first mailbox."));
417 CurBuffy -= known_lines;
421 case OP_SIDEBAR_SCROLL_DOWN:
422 if (TopBuffy + known_lines >= Incoming->length) {
423 mutt_error (_("You are on the last mailbox."));
426 CurBuffy += known_lines;
427 if (CurBuffy >= Incoming->length)
428 CurBuffy = Incoming->length;
433 calc_boundaries (menu);