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