X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-ui%2Fsidebar.c;h=6f35e48cc4672463a27b0610acea7f020fd11bdd;hp=9f6e9cea483d50e26ad743bdf53ae80e3122c513;hb=b2c8662dd3e1d14ed817e9e166f1fd223a5b4754;hpb=b23d5033080fe9f9fba038e3cf1e3ec2b0a0d33d diff --git a/lib-ui/sidebar.c b/lib-ui/sidebar.c index 9f6e9ce..6f35e48 100644 --- a/lib-ui/sidebar.c +++ b/lib-ui/sidebar.c @@ -12,10 +12,9 @@ * please see the file GPL in the top level source directory. */ -#include +#include #include -#include #include #include @@ -24,72 +23,76 @@ #include "buffy.h" #include "keymap.h" -static int TopBuffy = 0; static int CurBuffy = 0; -static int known_lines = 0; -static short initialized = 0; -static short prev_show_value; /* computes first entry to be shown */ -static void calc_boundaries (void) { - if (!Incoming.len) - return; - if (CurBuffy < 0 || CurBuffy >= Incoming.len) - CurBuffy = 0; - if (TopBuffy < 0 || TopBuffy >= Incoming.len) - TopBuffy = 0; - - if (option (OPTSIDEBARNEWMAILONLY)) { - int i = CurBuffy; - TopBuffy = CurBuffy - 1; - while (i >= 0) { - if (Incoming.arr[i]->new > 0) - TopBuffy = i; - i--; +static int calc_boundaries(void) +{ + if (CurBuffy < 0 || CurBuffy >= Incoming.len) + CurBuffy = 0; + + if (option(OPTSIDEBARNEWMAILONLY)) { + int n = 0; + + for (int i = 0; i < CurBuffy; i++) { + n += Incoming.arr[i]->new > 0; + } + + n %= (LINES - 3); + if (!n) + return CurBuffy; + + for (int i = CurBuffy - 1; i >= 0; i--) { + if (Incoming.arr[i]->new > 0 && --n <= 0) { + return i; + } + } + + return 0; + } else { + return CurBuffy - (CurBuffy % (LINES - 3)); } - } else if (known_lines>0) - TopBuffy = CurBuffy - (CurBuffy % known_lines); - if (TopBuffy < 0) - TopBuffy = 0; } -static char *shortened_hierarchy (char *hbox, int maxlen) +static void shortened_hierarchy(char *dst, char *hbox, int maxlen) { - int dots = 0; - char *last_dot = NULL; - int i, j, len = m_strlen(hbox); - char *new_box; - - if (!SidebarBoundary || !*SidebarBoundary) - return (m_strdup(hbox)); - - for (i = 0; i < len; ++i) { - if (strchr (SidebarBoundary, hbox[i])) { - ++dots; - last_dot = &hbox[i]; + int dots = 0, last_dot = 0, len = m_strlen(hbox); + + if (m_strisempty(SidebarBoundary)) { + memcpy(dst, hbox, MIN(len, maxlen)); + return; } - } - if (last_dot) { - ++last_dot; - new_box = p_new(char, maxlen + 1); - new_box[0] = hbox[0]; - for (i = 1, j = 1; j < maxlen && i < len; ++i) { - if (strchr (SidebarBoundary, hbox[i])) { - new_box[j++] = hbox[i]; - new_box[j] = 0; - if (&hbox[i + 1] != last_dot || j + m_strlen(last_dot) > maxlen) { - new_box[j++] = hbox[i + 1]; - new_box[j] = 0; - } else { - m_strcat(&new_box[j], maxlen + 1, last_dot); - break; + for (int i = 0; i < len; ++i) { + if (strchr(SidebarBoundary, hbox[i])) { + ++dots; + last_dot = i; } - } } - return new_box; - } - return m_strdup(hbox); + + if (dots == 0) { + memcpy(dst, hbox, MIN(len, maxlen)); + return; + } + + dst[0] = hbox[0]; + for (int i = 1, j = 1; i < len && j < maxlen - 1; ++i) { + if (!strchr(SidebarBoundary, hbox[i])) + continue; + + if (len - i <= maxlen - j) { + memcpy(dst, hbox + i, len - i); + return; + } + + if (i == last_dot) { + memcpy(dst, hbox + i, maxlen - j); + return; + } + + dst[j++] = hbox[i]; + dst[j++] = hbox[i + 1]; + } } static const char * @@ -170,11 +173,9 @@ sidebar_number_format(char* dest, ssize_t destlen, return src; } -int sidebar_need_count (void) { - if (!option (OPTMBOXPANE) || SidebarWidth == 0 || - !SidebarNumberFormat || !*SidebarNumberFormat) - return (0); - return (1); +int sidebar_need_count(void) +{ + return sidebar_w && !m_strisempty(SidebarNumberFormat); } /* print single item @@ -182,294 +183,190 @@ int sidebar_need_count (void) { * 0 item was not printed ('cause of $sidebar_newmail_only) * 1 item was printed */ -static int make_sidebar_entry (char* sbox, int idx, ssize_t len) +static int make_sidebar_entry(WINDOW *sw, char *sbox, int idx, ssize_t len) { - int shortened = 0, lencnt = 0; - char no[STRING], entry[STRING]; - int l = m_strlen(ImapHomeNamespace); - int l_m = m_strlen(Maildir); - - if (SidebarWidth > COLS) - SidebarWidth = COLS; - - if (option (OPTSIDEBARNEWMAILONLY) && sbox && Context && Context->path && - m_strcmp(Context->path, sbox) && Incoming.arr[idx]->new == 0) - /* if $sidebar_newmail_only is set, don't display the - * box only if it's not the currently opened - * (i.e. always display the currently opened) */ - return 0; - - m_strformat(no, len, SidebarWidth, SidebarNumberFormat, sidebar_number_format, idx, 0); - lencnt = m_strlen(no); - - if (l > 0 && m_strncmp(sbox, ImapHomeNamespace, l) == 0 && - m_strlen(sbox) > l) - sbox += l + 1; /* we're trimming the ImapHomeNamespace, the "+ 1" is for the separator */ - else - if (l_m > 0 && m_strncmp(sbox, Maildir, l_m) == 0 && - m_strlen(sbox) > l_m) { - sbox += l_m; - if (Maildir[strlen(Maildir)-1]!='/') { - sbox += 1; + int lencnt = 0; + char no[STRING], entry[STRING]; + int l_m = m_strlen(Maildir); + + if (option(OPTSIDEBARNEWMAILONLY) && sbox && Context && Context->path + && m_strcmp(Context->path, sbox) && Incoming.arr[idx]->new == 0 + && idx != CurBuffy) + return 0; + + m_strformat(no, sizeof(no), len, SidebarNumberFormat, + sidebar_number_format, idx, 0); + lencnt = m_strlen(no); + + if (l_m > 0 && m_strncmp(sbox, Maildir, l_m) == 0 && m_strlen(sbox) > l_m) + { + sbox += l_m; + if (Maildir[strlen(Maildir) - 1] != '/') { + sbox += 1; + } + } else { + sbox = basename(sbox); } - } else - sbox = basename (sbox); - if (option(OPTSHORTENHIERARCHY) && m_strlen(sbox) > len-lencnt-1) { - sbox = shortened_hierarchy (sbox, len-lencnt-1); - shortened = 1; - } - - snprintf(entry, sizeof(entry), "%*s", (int)len, no); - memcpy(entry, sbox, MIN(len - 1, m_strlen(sbox))); - addnstr(entry, len); - - if (shortened) - p_delete(&sbox); + snprintf(entry, sizeof(entry), "%*s", (int)len, no); + if (option(OPTSHORTENHIERARCHY) && m_strlen(sbox) > len - lencnt - 1) { + shortened_hierarchy(entry, sbox, len - lencnt - 1); + } else { + memcpy(entry, sbox, MIN(len - lencnt - 1, m_strlen(sbox))); + } + waddnstr(sw, entry, len); - return 1; + return 1; } /* returns folder name of currently * selected folder for */ -const char* sidebar_get_current (void) { - if (!Incoming.len) - return (NULL); - return Incoming.arr[CurBuffy]->path; +const char *sidebar_get_current(void) +{ + if (0 <= CurBuffy && CurBuffy < Incoming.len) + return Incoming.arr[CurBuffy]->path; + return NULL; } /* internally sets item to buf */ -void sidebar_set_current (const char* buf) { - int i = buffy_lookup (buf); - if (i >= 0) { - CurBuffy = i; - calc_boundaries(); - } +void sidebar_set_current(const char* buf) +{ + int i = buffy_lookup(buf); + if (i >= 0) { + CurBuffy = i; + } } /* fix counters for a context * FIXME since ctx must not be of our business, move it elsewhere */ -void sidebar_set_buffystats (CONTEXT* curContext) { - int i = 0; - BUFFY* tmp = NULL; - if (!curContext || !Incoming.len || (i = buffy_lookup (curContext->path)) < 0) - return; - tmp = Incoming.arr[i]; - tmp->new = curContext->new; - tmp->msg_unread = curContext->unread; - tmp->msgcount = curContext->msgcount; - tmp->msg_flagged = curContext->flagged; -} - -void sidebar_draw_frames (void) { - ssize_t i,delim_len; - - if (!option(OPTMBOXPANE) || SidebarWidth==0) - return; - - delim_len=m_strlen(NONULL(SidebarDelim)); - - /* draw vertical delimiter */ - SETCOLOR (MT_COLOR_SIDEBAR); - for (i = 0; i < LINES-1; i++) { - move (i, SidebarWidth - delim_len); - if (option (OPTASCIICHARS)) - addstr (NONULL (SidebarDelim)); - else if (!option (OPTASCIICHARS) && !m_strcmp(SidebarDelim, "|")) - addch (ACS_VLINE); - else if ((Charset_is_utf8) && !m_strcmp(SidebarDelim, "|")) - addstr ("\342\224\202"); - else - addstr (NONULL (SidebarDelim)); - } +void sidebar_set_buffystats(CONTEXT *curContext) +{ + int i = 0; + BUFFY *tmp; - /* fill "gaps" at top+bottom */ - SETCOLOR(MT_COLOR_STATUS); - for (i=0; ipath)) < 0) + return; + tmp = Incoming.arr[i]; + tmp->new = curContext->new; + tmp->msg_unread = curContext->unread; + tmp->msgcount = curContext->msgcount; + tmp->msg_flagged = curContext->flagged; } -/* actually draws something - * FIXME this needs some clue when to do it - */ -int sidebar_draw (void) { - int first_line = option (OPTSTATUSONTOP) ? 1 : option (OPTHELP) ? 1 : 0, - last_line = LINES - 2 + (option (OPTSTATUSONTOP) && !option (OPTHELP) ? 1 : 0), - i = 0,line; - BUFFY *tmp; - ssize_t delim_len = m_strlen(SidebarDelim); - char blank[STRING]; - - known_lines=last_line-first_line; - - /* initialize first time */ - if (!initialized) { - prev_show_value = option (OPTMBOXPANE); - initialized = 1; - } - - if (TopBuffy==0 || CurBuffy==0) - calc_boundaries(); - - /* save or restore the value SidebarWidth */ - if (prev_show_value != option (OPTMBOXPANE)) { - if (!prev_show_value && option (OPTMBOXPANE)) { - /* after toggle: force recounting of all mail */ - buffy_check (2); +int sidebar_draw(void) +{ + static short prev_show_value = -1; + int x, y, line; + char blank[STRING]; + WINDOW *sw; + + /* initialize first time */ + if (prev_show_value != option(OPTMBOXPANE)) { + if ((prev_show_value = option(OPTMBOXPANE))) { + /* after toggle: force recounting of all mail */ + buffy_check(2); + } } - prev_show_value = option (OPTMBOXPANE); - } - if (SidebarWidth > 0 && option (OPTMBOXPANE) - && m_strlen(SidebarDelim) >= SidebarWidth) { - mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar.")); - sleep (2); - unset_option (OPTMBOXPANE); - return (0); - } - - if (SidebarWidth == 0 || !option (OPTMBOXPANE)) - return 0; + sw = ui_layout_sidebar_w(); + if (!sw) + return 0; + getmaxyx(sw, y, x); + + memset(&blank, ' ', sizeof(blank)); + + wmove(sw, 0, 0); + WSETCOLOR(sw, MT_COLOR_STATUS); + waddnstr(sw, blank, x); + + line = 1; + for (int i = calc_boundaries(); i < Incoming.len && line < y - 1; i++) { + BUFFY *tmp = Incoming.arr[i]; + + if (i == CurBuffy) + WSETCOLOR(sw, MT_COLOR_INDICATOR); + else if (tmp->new > 0) + WSETCOLOR(sw, MT_COLOR_NEW); + else if (tmp->msg_flagged > 0) + WSETCOLOR(sw, MT_COLOR_FLAGGED); + else + WSETCOLOR(sw, MT_COLOR_NORMAL); + + if (make_sidebar_entry(sw, tmp->path, i, x - 1)) { + WSETCOLOR(sw, MT_COLOR_SIDEBAR); + waddch(sw, ACS_VLINE); + line++; + } + } - sidebar_draw_frames(); + while (line < y - 1) { + WSETCOLOR(sw, MT_COLOR_NORMAL); + waddnstr(sw, blank, x - 1); + WSETCOLOR(sw, MT_COLOR_SIDEBAR); + waddch(sw, ACS_VLINE); + line++; + } - if (!Incoming.len) + WSETCOLOR(sw, MT_COLOR_STATUS); + waddnstr(sw, blank, x); + WSETCOLOR(sw, MT_COLOR_NORMAL); return 0; - - /* actually print items */ - for (i = TopBuffy, line=first_line; i < Incoming.len && line < last_line; i++) { - tmp = Incoming.arr[i]; - - if (i == CurBuffy) - SETCOLOR (MT_COLOR_INDICATOR); - else if (tmp->new > 0) - SETCOLOR (MT_COLOR_NEW); - else if (tmp->msg_flagged > 0) - SETCOLOR (MT_COLOR_FLAGGED); - else - SETCOLOR (MT_COLOR_NORMAL); - - move (line, 0); - line += make_sidebar_entry (tmp->path, i, SidebarWidth-delim_len); - } - - SETCOLOR (MT_COLOR_NORMAL); - - /* fill with blanks to bottom */ - memset(&blank, ' ', sizeof(blank)); - for (; line < last_line; line++) { - move (line, 0); - addnstr (blank, SidebarWidth-delim_len); - } - return 0; } -/* returns index of new item with new mail or -1 */ -static int exist_next_new () { - int i = 0; - if (!Incoming.len) - return (-1); - i = CurBuffy + 1; - while (i < Incoming.len) - if (Incoming.arr[i++]->new > 0) - return (i-1); - return (-1); -} - -/* returns index of prev item with new mail or -1 */ -static int exist_prev_new () { - int i = 0; - if (!Incoming.len) - return (-1); - i = CurBuffy - 1; - while (i >= 0) - if (Incoming.arr[i--]->new > 0) - return (i+1); - return (-1); -} - -void sidebar_scroll (int op) { - int i = 0; - - if (!SidebarWidth || !Incoming.len) - return; - - switch (op) { - case OP_SIDEBAR_NEXT: - if (!option (OPTSIDEBARNEWMAILONLY)) { - if (CurBuffy + 1 == Incoming.len) { - mutt_error (_("You are on the last mailbox.")); +void sidebar_scroll(int op) +{ + if (!Incoming.len) return; - } - CurBuffy++; - break; - } /* the fall-through is intentional */ - case OP_SIDEBAR_NEXT_NEW: - if ((i = exist_next_new ()) < 0) { - mutt_error (_("No next mailboxes with new mail.")); - return; - } - else - CurBuffy = i; - break; - case OP_SIDEBAR_PREV: - if (!option (OPTSIDEBARNEWMAILONLY)) { - if (CurBuffy == 0) { - mutt_error (_("You are on the first mailbox.")); + + switch (op) { + case OP_SIDEBAR_NEXT: + if (!option(OPTSIDEBARNEWMAILONLY)) { + CurBuffy = (CurBuffy + 1) % Incoming.len; + break; + } + /* FALLTHROUGH */ + case OP_SIDEBAR_NEXT_NEW: + for (int i = 1; i < Incoming.len; i++) { + if (Incoming.arr[(CurBuffy + i) % Incoming.len]->new > 0) { + CurBuffy = (CurBuffy + i) % Incoming.len; + break; + } + } + break; + + case OP_SIDEBAR_PREV: + if (!option(OPTSIDEBARNEWMAILONLY)) { + if (!CurBuffy) { + CurBuffy = Incoming.len; + } + CurBuffy--; + break; + } + /* FALLTHROUGH */ + case OP_SIDEBAR_PREV_NEW: + for (int i = Incoming.len - 1; i > 0; i--) { + if (Incoming.arr[(CurBuffy + i) % Incoming.len]->new > 0) { + CurBuffy = (CurBuffy + i) % Incoming.len; + break; + } + } + break; + + case OP_SIDEBAR_SCROLL_UP: + CurBuffy -= LINES - 3; + if (CurBuffy < 0) + CurBuffy = 0; + break; + case OP_SIDEBAR_SCROLL_DOWN: + CurBuffy += LINES - 3; + if (CurBuffy >= Incoming.len) + CurBuffy = Incoming.len - 1; + break; + default: return; - } - CurBuffy--; - break; - } /* the fall-through is intentional */ - case OP_SIDEBAR_PREV_NEW: - if ((i = exist_prev_new ()) < 0) { - mutt_error (_("No previous mailbox with new mail.")); - return; - } - else - CurBuffy = i; - break; - - case OP_SIDEBAR_SCROLL_UP: - if (CurBuffy == 0) { - mutt_error (_("You are on the first mailbox.")); - return; - } - CurBuffy -= known_lines; - if (CurBuffy < 0) - CurBuffy = 0; - break; - case OP_SIDEBAR_SCROLL_DOWN: - if (CurBuffy + 1 == Incoming.len) { - mutt_error (_("You are on the last mailbox.")); - return; } - CurBuffy += known_lines; - if (CurBuffy >= Incoming.len) - CurBuffy = Incoming.len - 1; - break; - default: - return; - } - calc_boundaries (); - sidebar_draw (); + + sidebar_draw(); }