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 static char *shortened_hierarchy (char *box)
70 for (i = 0; i < mutt_strlen (box); ++i) {
73 else if (isupper (box[i]))
74 return (safe_strdup (box));
76 last_dot = strrchr (box, '.');
79 new_box = safe_malloc (mutt_strlen (last_dot) + 2 * dots + 1);
81 for (i = 1, j = 1; i < mutt_strlen (box); ++i) {
85 if (&box[i + 1] != last_dot) {
86 new_box[j++] = box[i + 1];
90 strcat (&new_box[j], last_dot);
97 return safe_strdup (box);
101 * FIXME this is completely fucked up right now
103 char *make_sidebar_entry (char *box, int size, int new, int flagged)
105 int i = 0, dlen, max, shortened = 0;
108 if (SidebarWidth > COLS)
111 dlen = mutt_strlen (SidebarDelim);
112 max = SidebarWidth - dlen - 1;
114 safe_realloc (&entry, SidebarWidth + 1);
115 entry[SidebarWidth] = 0;
116 for (; i < SidebarWidth; entry[i++] = ' ');
118 if (ImapHomeNamespace && mutt_strlen (ImapHomeNamespace) > 0) {
119 if (strncmp (box, ImapHomeNamespace, mutt_strlen (ImapHomeNamespace)) == 0
120 && mutt_strcmp (box, ImapHomeNamespace) != 0) {
121 box += mutt_strlen (ImapHomeNamespace) + 1;
125 max -= quick_log10 (size);
127 max -= quick_log10 (new) + 2;
129 max -= quick_log10 (flagged) + 2;
130 if (option (OPTSHORTENHIERARCHY) && mutt_strlen (box) > max) {
131 box = shortened_hierarchy (box);
134 i = mutt_strlen (box);
135 strncpy (entry, box, i < SidebarWidth - dlen ? i : SidebarWidth - dlen);
140 SidebarWidth - 5 - quick_log10 (size) - dlen - quick_log10 (new) -
141 quick_log10 (flagged);
144 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
145 "% d(%d)[%d]", size, new, flagged);
149 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (new);
152 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
153 "% d(%d)", size, new);
159 SidebarWidth - 3 - quick_log10 (size) - dlen - quick_log10 (flagged);
162 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
163 "% d[%d]", size, flagged);
166 offset = SidebarWidth - 1 - quick_log10 (size) - dlen;
169 snprintf (entry + offset, SidebarWidth - dlen - offset + 1,
174 if (option (OPTSHORTENHIERARCHY) && shortened) {
180 /* returns folder name of currently
181 * selected folder for <sidebar-open>
183 const char* sidebar_get_current (void) {
184 if (list_empty(Incoming))
186 return ((char*) ((BUFFY*) Incoming->data[CurBuffy])->path);
189 /* internally sets item to buf */
190 void sidebar_set_current (const char* buf) {
191 int i = buffy_lookup (buf);
196 /* fix counters for a context
197 * FIXME since ctx must not be of our business, move it elsewhere
199 void sidebar_set_buffystats (CONTEXT* Context) {
202 if (!Context || list_empty(Incoming) || (i = buffy_lookup (Context->path)) < 0)
204 tmp = (BUFFY*) Incoming->data[i];
205 tmp->new = Context->new;
206 tmp->msg_unread = Context->unread;
207 tmp->msgcount = Context->msgcount;
208 tmp->msg_flagged = Context->flagged;
211 /* actually draws something
212 * FIXME this needs some clue when to do it
213 * FIXME this is completely fucked up right now
215 int sidebar_draw (int menu)
218 int lines = option (OPTHELP) ? 1 : 0;
221 short delim_len = mutt_strlen (SidebarDelim);
223 /* initialize first time */
225 prev_show_value = option (OPTMBOXPANE);
226 saveSidebarWidth = SidebarWidth;
227 if (!option (OPTMBOXPANE))
232 /* save or restore the value SidebarWidth */
233 if (prev_show_value != option (OPTMBOXPANE)) {
234 if (prev_show_value && !option (OPTMBOXPANE)) {
235 saveSidebarWidth = SidebarWidth;
238 else if (!prev_show_value && option (OPTMBOXPANE)) {
239 SidebarWidth = saveSidebarWidth;
240 /* after toggle: force recounting of all mail */
241 mutt_buffy_check (2);
243 prev_show_value = option (OPTMBOXPANE);
246 if (SidebarWidth > 0 && option (OPTMBOXPANE)
247 && mutt_strlen (SidebarDelim) >= SidebarWidth) {
248 mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
250 unset_option (OPTMBOXPANE);
254 if (SidebarWidth == 0 || !option (OPTMBOXPANE))
257 /* draw the divider */
258 SETCOLOR (MT_COLOR_SIDEBAR);
260 lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
262 move (lines, SidebarWidth - delim_len);
263 if (option (OPTASCIICHARS))
264 addstr (NONULL (SidebarDelim));
265 else if (!option (OPTASCIICHARS) && !mutt_strcmp (SidebarDelim, "|"))
267 else if ((Charset_is_utf8) && !mutt_strcmp (SidebarDelim, "|"))
268 addstr ("\342\224\202");
270 addstr (NONULL (SidebarDelim));
272 SETCOLOR (MT_COLOR_NORMAL);
274 if (list_empty(Incoming))
277 lines = option (OPTHELP) ? 1 : 0; /* go back to the top */
279 calc_boundaries (menu);
281 for (i = TopBuffy; i < Incoming->length && lines < LINES - 1 -
282 (menu != MENU_PAGER || option (OPTSTATUSONTOP)); i++) {
283 tmp = (BUFFY*) Incoming->data[i];
285 SETCOLOR (MT_COLOR_INDICATOR);
286 else if (tmp->msg_flagged > 0)
287 SETCOLOR (MT_COLOR_FLAGGED);
288 else if (tmp->msg_unread > 0)
289 SETCOLOR (MT_COLOR_NEW);
291 SETCOLOR (MT_COLOR_NORMAL);
294 if (option (OPTSIDEBARNEWMAILONLY)) {
295 if (tmp->msg_unread > 0) {
296 if (Context && !mutt_strcmp (tmp->path, Context->path)) {
297 printw ("%.*s", SidebarWidth - delim_len,
298 make_sidebar_entry (basename (tmp->path),
299 Context->msgcount, Context->unread,
301 tmp->msg_unread = Context->unread;
302 tmp->msgcount = Context->msgcount;
303 tmp->msg_flagged = Context->flagged;
306 printw ("%.*s", SidebarWidth - delim_len,
307 make_sidebar_entry (basename (tmp->path),
308 tmp->msgcount, tmp->msg_unread,
314 if (Context && !mutt_strcmp (tmp->path, Context->path)) {
315 printw ("%.*s", SidebarWidth - delim_len,
316 make_sidebar_entry (basename (tmp->path),
317 Context->msgcount, Context->unread,
319 tmp->msg_unread = Context->unread;
320 tmp->msgcount = Context->msgcount;
321 tmp->msg_flagged = Context->flagged;
324 printw ("%.*s", SidebarWidth - delim_len,
325 make_sidebar_entry (basename (tmp->path),
326 tmp->msgcount, tmp->msg_unread,
331 SETCOLOR (MT_COLOR_NORMAL);
332 for (; lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
337 for (; i < SidebarWidth - delim_len; i++)
343 /* returns index of new item with new mail or -1 */
344 static int exist_next_new () {
346 if (list_empty(Incoming))
349 while (i < Incoming->length)
350 if (((BUFFY*) Incoming->data[i++])->msg_unread)
355 /* returns index of prev item with new mail or -1 */
356 static int exist_prev_new () {
358 if (list_empty(Incoming))
362 if (((BUFFY*) Incoming->data[i--])->msg_unread)
367 void sidebar_scroll (int op, int menu) {
370 if (!SidebarWidth || list_empty(Incoming))
374 case OP_SIDEBAR_NEXT:
375 if (!option (OPTSIDEBARNEWMAILONLY)) {
376 if (CurBuffy + 1 == Incoming->length) {
377 mutt_error (_("You are on the last mailbox."));
382 } /* the fall-through is intentional */
383 case OP_SIDEBAR_NEXT_NEW:
384 if ((i = exist_next_new ()) < 0) {
385 mutt_error (_("No next mailboxes with new mail."));
391 case OP_SIDEBAR_PREV:
392 if (!option (OPTSIDEBARNEWMAILONLY)) {
394 mutt_error (_("You are on the first mailbox."));
399 } /* the fall-through is intentional */
400 case OP_SIDEBAR_PREV_NEW:
401 if ((i = exist_prev_new ()) < 0) {
402 mutt_error (_("No previous mailbox with new mail."));
409 case OP_SIDEBAR_SCROLL_UP:
411 mutt_error (_("You are on the first mailbox."));
414 CurBuffy -= known_lines;
418 case OP_SIDEBAR_SCROLL_DOWN:
419 if (TopBuffy + known_lines >= Incoming->length) {
420 mutt_error (_("You are on the last mailbox."));
423 CurBuffy += known_lines;
424 if (CurBuffy >= Incoming->length)
425 CurBuffy = Incoming->length;
430 calc_boundaries (menu);