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 < safe_strlen (box); ++i) {
73 else if (isupper (box[i]))
74 return (safe_strdup (box));
76 last_dot = strrchr (box, '.');
79 new_box = safe_malloc (safe_strlen (last_dot) + 2 * dots + 1);
81 for (i = 1, j = 1; i < safe_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 = safe_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 && safe_strlen (ImapHomeNamespace) > 0) {
119 if (strncmp (box, ImapHomeNamespace, safe_strlen (ImapHomeNamespace)) == 0
120 && safe_strcmp (box, ImapHomeNamespace) != 0) {
121 box += safe_strlen (ImapHomeNamespace) + 1;
125 max -= quick_log10 (size);
127 max -= quick_log10 (new) + 2;
129 max -= quick_log10 (flagged) + 2;
130 if (option (OPTSHORTENHIERARCHY) && safe_strlen (box) > max) {
131 box = shortened_hierarchy (box);
134 i = safe_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;
222 short delim_len = safe_strlen (SidebarDelim);
224 /* initialize first time */
226 prev_show_value = option (OPTMBOXPANE);
227 saveSidebarWidth = SidebarWidth;
228 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 && safe_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))
259 /* draw devider only if necessary (if the sidebar becomes visible e.g.)*/
260 if (draw_devider == 1){
261 /* draw the divider */
262 SETCOLOR (MT_COLOR_SIDEBAR);
264 lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
266 move (lines, SidebarWidth - delim_len);
267 if (option (OPTASCIICHARS))
268 addstr (NONULL (SidebarDelim));
269 else if (!option (OPTASCIICHARS) && !safe_strcmp (SidebarDelim, "|"))
271 else if ((Charset_is_utf8) && !safe_strcmp (SidebarDelim, "|"))
272 addstr ("\342\224\202");
274 addstr (NONULL (SidebarDelim));
277 SETCOLOR (MT_COLOR_NORMAL);
279 if (list_empty(Incoming))
282 lines = option (OPTHELP) ? 1 : 0; /* go back to the top */
284 calc_boundaries (menu);
286 for (i = TopBuffy; i < Incoming->length && lines < LINES - 1 -
287 (menu != MENU_PAGER || option (OPTSTATUSONTOP)); i++) {
288 tmp = (BUFFY*) Incoming->data[i];
290 SETCOLOR (MT_COLOR_INDICATOR);
291 else if (tmp->msg_flagged > 0)
292 SETCOLOR (MT_COLOR_FLAGGED);
293 else if (tmp->msg_unread > 0)
294 SETCOLOR (MT_COLOR_NEW);
296 SETCOLOR (MT_COLOR_NORMAL);
299 if (option (OPTSIDEBARNEWMAILONLY)) {
300 if (tmp->msg_unread > 0) {
301 if (Context && !safe_strcmp (tmp->path, Context->path)) {
302 printw ("%.*s", SidebarWidth - delim_len,
303 make_sidebar_entry (basename (tmp->path),
304 Context->msgcount, Context->unread,
306 tmp->msg_unread = Context->unread;
307 tmp->msgcount = Context->msgcount;
308 tmp->msg_flagged = Context->flagged;
311 printw ("%.*s", SidebarWidth - delim_len,
312 make_sidebar_entry (basename (tmp->path),
313 tmp->msgcount, tmp->msg_unread,
319 if (Context && !safe_strcmp (tmp->path, Context->path)) {
320 printw ("%.*s", SidebarWidth - delim_len,
321 make_sidebar_entry (basename (tmp->path),
322 Context->msgcount, Context->unread,
324 tmp->msg_unread = Context->unread;
325 tmp->msgcount = Context->msgcount;
326 tmp->msg_flagged = Context->flagged;
329 printw ("%.*s", SidebarWidth - delim_len,
330 make_sidebar_entry (basename (tmp->path),
331 tmp->msgcount, tmp->msg_unread,
336 SETCOLOR (MT_COLOR_NORMAL);
337 for (; lines < LINES - 1 - (menu != MENU_PAGER || option (OPTSTATUSONTOP));
342 for (; i < SidebarWidth - delim_len; i++)
348 /* returns index of new item with new mail or -1 */
349 static int exist_next_new () {
351 if (list_empty(Incoming))
354 while (i < Incoming->length)
355 if (((BUFFY*) Incoming->data[i++])->msg_unread)
360 /* returns index of prev item with new mail or -1 */
361 static int exist_prev_new () {
363 if (list_empty(Incoming))
367 if (((BUFFY*) Incoming->data[i--])->msg_unread)
372 void sidebar_scroll (int op, int menu) {
375 if (!SidebarWidth || list_empty(Incoming))
379 case OP_SIDEBAR_NEXT:
380 if (!option (OPTSIDEBARNEWMAILONLY)) {
381 if (CurBuffy + 1 == Incoming->length) {
382 mutt_error (_("You are on the last mailbox."));
387 } /* the fall-through is intentional */
388 case OP_SIDEBAR_NEXT_NEW:
389 if ((i = exist_next_new ()) < 0) {
390 mutt_error (_("No next mailboxes with new mail."));
396 case OP_SIDEBAR_PREV:
397 if (!option (OPTSIDEBARNEWMAILONLY)) {
399 mutt_error (_("You are on the first mailbox."));
404 } /* the fall-through is intentional */
405 case OP_SIDEBAR_PREV_NEW:
406 if ((i = exist_prev_new ()) < 0) {
407 mutt_error (_("No previous mailbox with new mail."));
414 case OP_SIDEBAR_SCROLL_UP:
416 mutt_error (_("You are on the first mailbox."));
419 CurBuffy -= known_lines;
423 case OP_SIDEBAR_SCROLL_DOWN:
424 if (TopBuffy + known_lines >= Incoming->length) {
425 mutt_error (_("You are on the last mailbox."));
428 CurBuffy += known_lines;
429 if (CurBuffy >= Incoming->length)
430 CurBuffy = Incoming->length;
435 calc_boundaries (menu);