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.
15 #include <lib-ui/lib-ui.h>
18 #include <lib-ui/menu.h>
19 #include <lib-ui/sidebar.h>
26 static int CurBuffy = 0;
28 /* computes first entry to be shown */
29 static int calc_boundaries(void)
33 if (CurBuffy < 0 || CurBuffy >= Incoming.len)
36 if (option(OPTSIDEBARNEWMAILONLY)) {
39 for (int i = 0; i < CurBuffy; i++) {
40 n += Incoming.arr[i]->new > 0;
47 for (int i = CurBuffy - 1; i >= 0; i--) {
48 if (Incoming.arr[i]->new > 0 && --n <= 0) {
53 TopBuffy = CurBuffy - (CurBuffy % (LINES - 3));
56 return TopBuffy < 0 ? 0 : TopBuffy;
59 static char *shortened_hierarchy (char *hbox, int maxlen)
62 char *last_dot = NULL;
63 int i, j, len = m_strlen(hbox);
66 if (!SidebarBoundary || !*SidebarBoundary)
67 return (m_strdup(hbox));
69 for (i = 0; i < len; ++i) {
70 if (strchr (SidebarBoundary, hbox[i])) {
78 new_box = p_new(char, maxlen + 1);
80 for (i = 1, j = 1; j < maxlen && i < len; ++i) {
81 if (strchr (SidebarBoundary, hbox[i])) {
82 new_box[j++] = hbox[i];
84 if (&hbox[i + 1] != last_dot || j + m_strlen(last_dot) > maxlen) {
85 new_box[j++] = hbox[i + 1];
88 m_strcat(&new_box[j], maxlen + 1, last_dot);
95 return m_strdup(hbox);
99 sidebar_number_format(char* dest, ssize_t destlen,
100 char op, const char* src, const char* fmt,
101 const char* ifstr, const char* elstr,
102 anytype data, format_flag flags)
105 BUFFY* b = Incoming.arr[data.i];
106 int opt = flags & M_FORMAT_OPTIONAL;
107 int c = Context && !m_strcmp(Context->path, b->path);
113 snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
114 snprintf (dest, destlen, tmp, c ? Context->deleted : 0);
115 } else if ((c && Context->deleted == 0) || !c)
120 case 'f': /* for compatibility */
122 snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
123 snprintf (dest, destlen, tmp, c ? Context->flagged : b->msg_flagged);
124 } else if ((c && Context->flagged == 0) || (!c && b->msg_flagged == 0))
128 case 'c': /* for compatibility */
131 snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
132 snprintf (dest, destlen, tmp, c ? Context->msgcount : b->msgcount);
133 } else if ((c && Context->msgcount == 0) || (!c && b->msgcount == 0))
136 /* total shown, i.e. not hidden by limit */
139 snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
140 snprintf (dest, destlen, tmp, c ? Context->vcount : 0);
141 } else if ((c && Context->vcount == 0) || !c)
147 snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
148 snprintf (dest, destlen, tmp, c ? Context->new : b->new);
149 } else if ((c && Context->new == 0) || (!c && b->new == 0))
155 snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
156 snprintf (dest, destlen, tmp, c ? Context->unread : b->msg_unread);
157 } else if ((c && Context->unread == 0) || (!c && b->msg_unread == 0))
163 snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
164 snprintf (dest, destlen, tmp, c ? Context->tagged : 0);
165 } else if ((c && Context->tagged == 0) || !c)
170 if (flags & M_FORMAT_OPTIONAL)
171 m_strformat(dest, destlen, 0, opt ? ifstr : elstr,
172 sidebar_number_format, data, flags);
176 int sidebar_need_count(void)
178 return ui_layout_sidebar_w() && !m_strisempty(SidebarNumberFormat);
183 * 0 item was not printed ('cause of $sidebar_newmail_only)
186 static int make_sidebar_entry(WINDOW *sw, char *sbox, int idx, ssize_t len)
188 int shortened = 0, lencnt = 0;
189 char no[STRING], entry[STRING];
190 int l_m = m_strlen(Maildir);
192 if (option(OPTSIDEBARNEWMAILONLY) && sbox && Context && Context->path
193 && m_strcmp(Context->path, sbox) && Incoming.arr[idx]->new == 0
197 m_strformat(no, sizeof(no), len, SidebarNumberFormat,
198 sidebar_number_format, idx, 0);
199 lencnt = m_strlen(no);
201 if (l_m > 0 && m_strncmp(sbox, Maildir, l_m) == 0 && m_strlen(sbox) > l_m)
204 if (Maildir[strlen(Maildir) - 1] != '/') {
208 sbox = basename(sbox);
211 if (option(OPTSHORTENHIERARCHY) && m_strlen(sbox) > len - lencnt - 1) {
212 sbox = shortened_hierarchy(sbox, len - lencnt - 1);
216 snprintf(entry, sizeof(entry), "%*s", (int)len, no);
217 memcpy(entry, sbox, MIN(len, m_strlen(sbox)));
218 waddnstr(sw, entry, len);
226 /* returns folder name of currently
227 * selected folder for <sidebar-open>
229 const char *sidebar_get_current(void)
231 if (0 <= CurBuffy && CurBuffy < Incoming.len)
232 return Incoming.arr[CurBuffy]->path;
236 /* internally sets item to buf */
237 void sidebar_set_current(const char* buf)
239 int i = buffy_lookup(buf);
245 /* fix counters for a context
246 * FIXME since ctx must not be of our business, move it elsewhere
248 void sidebar_set_buffystats(CONTEXT *curContext)
253 if (!curContext || (i = buffy_lookup(curContext->path)) < 0)
255 tmp = Incoming.arr[i];
256 tmp->new = curContext->new;
257 tmp->msg_unread = curContext->unread;
258 tmp->msgcount = curContext->msgcount;
259 tmp->msg_flagged = curContext->flagged;
262 int sidebar_draw(void)
264 static short initialized = false, prev_show_value = 0;
269 /* initialize first time */
271 prev_show_value = option(OPTMBOXPANE);
275 /* save or restore the value SidebarWidth */
276 if (prev_show_value != option(OPTMBOXPANE)) {
277 if (!prev_show_value && option(OPTMBOXPANE)) {
278 /* after toggle: force recounting of all mail */
281 prev_show_value = option(OPTMBOXPANE);
284 sw = ui_layout_sidebar_w();
289 memset(&blank, ' ', sizeof(blank));
292 WSETCOLOR(sw, MT_COLOR_STATUS);
293 waddnstr(sw, blank, x);
296 for (i = calc_boundaries(); i < Incoming.len && line < y - 1; i++) {
297 BUFFY *tmp = Incoming.arr[i];
300 WSETCOLOR(sw, MT_COLOR_INDICATOR);
301 else if (tmp->new > 0)
302 WSETCOLOR(sw, MT_COLOR_NEW);
303 else if (tmp->msg_flagged > 0)
304 WSETCOLOR(sw, MT_COLOR_FLAGGED);
306 WSETCOLOR(sw, MT_COLOR_NORMAL);
308 if (make_sidebar_entry(sw, tmp->path, i, x - 1)) {
309 WSETCOLOR(sw, MT_COLOR_SIDEBAR);
310 waddch(sw, ACS_VLINE);
315 while (line < y - 1) {
316 WSETCOLOR(sw, MT_COLOR_NORMAL);
317 waddnstr(sw, blank, x - 1);
318 WSETCOLOR(sw, MT_COLOR_SIDEBAR);
319 waddch(sw, ACS_VLINE);
323 WSETCOLOR(sw, MT_COLOR_STATUS);
324 waddnstr(sw, blank, x);
325 WSETCOLOR(sw, MT_COLOR_NORMAL);
330 void sidebar_scroll(int op)
336 case OP_SIDEBAR_NEXT:
337 if (!option(OPTSIDEBARNEWMAILONLY)) {
338 CurBuffy = (CurBuffy + 1) % Incoming.len;
342 case OP_SIDEBAR_NEXT_NEW:
343 for (int i = 1; i < Incoming.len; i++) {
344 if (Incoming.arr[(CurBuffy + i) % Incoming.len]->new > 0) {
345 CurBuffy = (CurBuffy + i) % Incoming.len;
351 case OP_SIDEBAR_PREV:
352 if (!option(OPTSIDEBARNEWMAILONLY)) {
354 CurBuffy = Incoming.len;
360 case OP_SIDEBAR_PREV_NEW:
361 for (int i = Incoming.len - 1; i > 0; i--) {
362 if (Incoming.arr[(CurBuffy + i) % Incoming.len]->new > 0) {
363 CurBuffy = (CurBuffy + i) % Incoming.len;
369 case OP_SIDEBAR_SCROLL_UP:
370 CurBuffy -= LINES - 3;
374 case OP_SIDEBAR_SCROLL_DOWN:
375 CurBuffy += LINES - 3;
376 if (CurBuffy >= Incoming.len)
377 CurBuffy = Incoming.len - 1;