2dbf7e7c850f9ae6debefca74f84b6f1b04ddb6e
[apps/madmutt.git] / lib-ui / status.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 #include <lib-lib/lib-lib.h>
11
12 #include <lib-ui/curses.h>
13 #include <lib-ui/menu.h>
14
15 #include "mutt.h"
16 #include "sort.h"
17 #include "mx.h"
18 #include "buffy.h"
19
20 #define SW              (option(OPTMBOXPANE)?SidebarWidth:0)
21
22 static char *get_sort_str (char *buf, ssize_t buflen, int method)
23 {
24   snprintf (buf, buflen, "%s%s%s",
25             (method & SORT_REVERSE) ? "reverse-" : "",
26             (method & SORT_LAST) ? "last-" : "",
27             mutt_getnamebyvalue (method & SORT_MASK, SortMethods));
28   return buf;
29 }
30
31 /* %b = number of incoming folders with unread messages [option]
32  * %B = short mailbox path
33  * %d = number of deleted messages [option]
34  * %f = full mailbox path
35  * %F = number of flagged messages [option]
36  * %h = hostname
37  * %l = length of mailbox (in bytes) [option]
38  * %m = total number of messages [option]
39  * %M = number of messages shown (virutal message count when limiting) [option]
40  * %n = number of new messages [option]
41  * %p = number of postponed messages [option]
42  * %P = percent of way through index
43  * %r = readonly/wontwrite/changed flag
44  * %s = current sorting method ($sort)
45  * %S = current aux sorting method ($sort_aux)
46  * %t = # of tagged messages [option]
47  * %v = Madmutt version 
48  * %V = currently active limit pattern [option] */
49 static const char *status_format_str (char *buf, ssize_t buflen, char op,
50                                       const char *src, const char *prefix,
51                                       const char *ifstring,
52                                       const char *elsestring,
53                                       unsigned long data, format_flag flags)
54 {
55   char fmt[SHORT_STRING], tmp[SHORT_STRING];
56   const char *cp, *p;
57   int count, optional = (flags & M_FORMAT_OPTIONAL);
58   MUTTMENU *menu = (MUTTMENU *) data;
59
60   *buf = 0;
61   switch (op) {
62   case 'b':
63     if (!optional) {
64       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
65       snprintf (buf, buflen, fmt, buffy_check (0));
66     }
67     else if (!buffy_check (0))
68       optional = 0;
69     break;
70
71   case 'B':
72     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
73     if (Context && Context->compressinfo && Context->realpath) {
74       if ((p = strrchr (Context->realpath, '/')))
75         m_strcpy(tmp, sizeof(tmp), p + 1);
76       else
77         m_strcpy(tmp, sizeof(tmp), Context->realpath);
78     }
79     else
80     if (Context && Context->path) {
81       if ((p = strrchr (Context->path, '/')))
82         m_strcpy(tmp, sizeof(tmp), p + 1);
83       else
84         m_strcpy(tmp, sizeof(tmp), Context->path);
85     }
86     else
87       m_strcpy(tmp, sizeof(tmp), _("no mailbox"));
88     snprintf (buf, buflen, fmt, tmp);
89     break;
90
91   case 'd':
92     if (!optional) {
93       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
94       snprintf (buf, buflen, fmt, Context ? Context->deleted : 0);
95     }
96     else if (!Context || !Context->deleted)
97       optional = 0;
98     break;
99
100   case 'h':
101     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
102     snprintf (buf, buflen, fmt, NONULL (Hostname));
103     break;
104
105   case 'f':
106     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
107     if (Context && Context->compressinfo && Context->realpath) {
108       m_strcpy(tmp, sizeof(tmp), Context->realpath);
109       mutt_pretty_mailbox (tmp);
110     }
111     else
112     if (Context && Context->path) {
113       m_strcpy(tmp, sizeof(tmp), Context->path);
114       mutt_pretty_mailbox (tmp);
115     }
116     else
117       m_strcpy(tmp, sizeof(tmp), _("(no mailbox)"));
118     snprintf (buf, buflen, fmt, tmp);
119     break;
120
121   case 'F':
122     if (!optional) {
123       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
124       snprintf (buf, buflen, fmt, Context ? Context->flagged : 0);
125     }
126     else if (!Context || !Context->flagged)
127       optional = 0;
128     break;
129
130   case 'l':
131     if (!optional) {
132       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
133       mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->size : 0);
134       snprintf (buf, buflen, fmt, tmp);
135     }
136     else if (!Context || !Context->size)
137       optional = 0;
138     break;
139
140   case 'L':
141     if (!optional) {
142       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
143       mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->vsize : 0);
144       snprintf (buf, buflen, fmt, tmp);
145     }
146     else if (!Context || !Context->pattern)
147       optional = 0;
148     break;
149
150   case 'm':
151     if (!optional) {
152       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
153       snprintf (buf, buflen, fmt, Context ? Context->msgcount : 0);
154     }
155     else if (!Context || !Context->msgcount)
156       optional = 0;
157     break;
158
159   case 'M':
160     if (!optional) {
161       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
162       snprintf (buf, buflen, fmt, Context ? Context->vcount : 0);
163     }
164     else if (!Context || !Context->pattern)
165       optional = 0;
166     break;
167
168   case 'n':
169     if (!optional) {
170       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
171       snprintf (buf, buflen, fmt, Context ? Context->new : 0);
172     }
173     else if (!Context || Context->new <= 0)
174       optional = 0;
175     break;
176
177   case 'o':
178     if (!optional) {
179       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
180       snprintf (buf, buflen, fmt,
181                 Context ? Context->unread - Context->new : 0);
182     }
183     else if (!Context || !(Context->unread - Context->new))
184       optional = 0;
185     break;
186
187   case 'p':
188     count = mutt_num_postponed (0);
189     if (!optional) {
190       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
191       snprintf (buf, buflen, fmt, count);
192     }
193     else if (!count)
194       optional = 0;
195     break;
196
197   case 'P':
198     if (menu->top + menu->pagelen >= menu->max)
199       cp = menu->top ? "end" : "all";
200     else {
201       count = (100 * (menu->top + menu->pagelen)) / menu->max;
202       snprintf (tmp, sizeof (tmp), "%d%%", count);
203       cp = tmp;
204     }
205     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
206     snprintf (buf, buflen, fmt, cp);
207     break;
208
209   case 'r':
210     {
211       int i = 0;
212
213       if (Context) {
214         /* XXX: deleted doesn't necessarily mean changed in IMAP */
215         i = option (OPTATTACHMSG) ? 3
216             : ((Context->readonly || Context->dontwrite) ? 2
217                : (Context->changed || (Context-> magic != M_IMAP && Context->
218                                         deleted)) ? 1 : 0);
219       }
220
221       if (!StChars)
222         buf[0] = 0;
223       else if (i >= m_strlen(StChars))
224         buf[0] = StChars[0];
225       else
226         buf[0] = StChars[i];
227
228       buf[1] = 0;
229       break;
230     }
231
232   case 's':
233     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
234     snprintf (buf, buflen, fmt, get_sort_str (tmp, sizeof (tmp), Sort));
235     break;
236
237   case 'S':
238     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
239     snprintf (buf, buflen, fmt, get_sort_str (tmp, sizeof (tmp), SortAux));
240     break;
241
242   case 't':
243     if (!optional) {
244       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
245       snprintf (buf, buflen, fmt, Context ? Context->tagged : 0);
246     }
247     else if (!Context || !Context->tagged)
248       optional = 0;
249     break;
250
251   case 'u':
252     if (!optional) {
253       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
254       snprintf (buf, buflen, fmt, Context ? Context->unread : 0);
255     }
256     else if (!Context || !Context->unread)
257       optional = 0;
258     break;
259
260   case 'v':
261     m_strcpy(buf, buflen, mutt_make_version(0));
262     break;
263
264   case 'V':
265     if (!optional) {
266       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
267       snprintf (buf, buflen, fmt,
268                 (Context && Context->pattern) ? Context->pattern : "");
269     }
270     else if (!Context || !Context->pattern)
271       optional = 0;
272     break;
273
274   case 0:
275     *buf = 0;
276     return (src);
277
278   default:
279     snprintf (buf, buflen, "%%%s%c", prefix, op);
280     break;
281   }
282
283   if (optional)
284     menu_status_line (buf, buflen, menu, ifstring);
285   else if (flags & M_FORMAT_OPTIONAL)
286     menu_status_line (buf, buflen, menu, elsestring);
287
288   return (src);
289 }
290
291 void menu_status_line (char* buf, ssize_t len, MUTTMENU* menu, const char* p) {
292   /*
293    * if we have enough space for buffer, format lines to $COLS-$SidebarWidth
294    * only to not wrap past end of screen
295    */
296   int width = COLS - SW;
297   mutt_FormatString (buf, (width >= len ? len : (width + 1)),
298                      p, status_format_str,
299                      (unsigned long) menu, 0);
300 }