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