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