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