Nico Golde:
[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 *
62 status_format_str (char *buf, size_t buflen, char op, const char *src,
63                    const char *prefix, 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   {
74     case 'b':
75       if (!optional)
76       {
77         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
78         snprintf (buf, buflen, fmt, mutt_buffy_check (0));
79       }
80       else if (!mutt_buffy_check (0))
81         optional = 0;
82       break;
83
84     case 'B':
85       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
86 #ifdef USE_COMPRESSED
87       if (Context && Context->compressinfo && Context->realpath)
88       {
89         if ((p = strrchr (Context->realpath, '/')))
90           strfcpy (tmp, p + 1, sizeof (tmp));
91         else
92           strfcpy (tmp, Context->realpath, sizeof (tmp));
93       } 
94       else
95 #endif
96       if (Context && Context->path)
97       {
98         if ((p = strrchr (Context->path, '/')))
99           strfcpy (tmp, p + 1, sizeof (tmp));
100         else
101           strfcpy (tmp, Context->path, sizeof (tmp));
102       }
103       else
104           strfcpy (tmp, _("no mailbox"), sizeof (tmp));
105       snprintf (buf, buflen, fmt, tmp);
106       break;
107
108     case 'd':
109       if (!optional)
110       {
111         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
112         snprintf (buf, buflen, fmt, Context ? Context->deleted : 0);
113       }
114       else if (!Context || !Context->deleted)
115         optional = 0;
116       break;
117
118     case 'h':
119       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
120       snprintf (buf, buflen, fmt, NONULL(Hostname));
121       break;
122
123     case 'f':
124       snprintf (fmt, sizeof(fmt), "%%%ss", prefix);
125 #ifdef USE_COMPRESSED
126       if (Context && Context->compressinfo && Context->realpath)
127       {
128          strfcpy (tmp, Context->realpath, sizeof (tmp));
129          mutt_pretty_mailbox (tmp);
130       }
131       else
132 #endif
133       if (Context && Context->path)
134       {
135         strfcpy (tmp, Context->path, sizeof (tmp));
136         mutt_pretty_mailbox (tmp);
137       }
138       else
139         strfcpy (tmp, _("(no mailbox)"), sizeof (tmp));
140       snprintf (buf, buflen, fmt, tmp);
141       break;
142
143     case 'F':
144       if (!optional)
145       {
146         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
147         snprintf (buf, buflen, fmt, Context ? Context->flagged : 0);
148       }
149       else if (!Context || !Context->flagged)
150         optional = 0;
151       break;
152
153     case 'l':
154       if (!optional)
155       {
156         snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
157         mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->size : 0);
158         snprintf (buf, buflen, fmt, tmp);
159       }
160       else if (!Context || !Context->size)
161         optional = 0;
162       break;
163
164     case 'L':
165       if (!optional)
166       {
167         snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
168         mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->vsize: 0);
169         snprintf (buf, buflen, fmt, tmp);
170       }
171       else if (!Context || !Context->pattern)
172         optional = 0;
173       break;
174
175     case 'm':
176       if (!optional)
177       {
178         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
179         snprintf (buf, buflen, fmt, Context ? Context->msgcount : 0);
180       }
181       else if (!Context || !Context->msgcount)
182         optional = 0;
183       break;
184
185     case 'M':
186       if (!optional)
187       {
188         snprintf (fmt, sizeof(fmt), "%%%sd", prefix);
189         snprintf (buf, buflen, fmt, Context ? Context->vcount : 0);
190       }
191       else if (!Context || !Context->pattern)
192         optional = 0;
193       break;
194
195     case 'n':
196       if (!optional)
197       {
198         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
199         snprintf (buf, buflen, fmt, Context ? Context->new : 0);
200       }
201       else if (!Context || Context->new <= 0)
202         optional = 0;
203       break;
204
205     case 'o':
206       if (!optional)
207       {
208         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
209         snprintf (buf, buflen, fmt, Context ? Context->unread - Context->new : 0);
210       }
211       else if (!Context || !(Context->unread - Context->new))
212         optional = 0;
213       break;
214
215     case 'p':
216       count = mutt_num_postponed (0);
217       if (!optional)
218       {
219         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
220         snprintf (buf, buflen, fmt, count);
221       }
222       else if (!count)
223         optional = 0;
224       break;
225
226     case 'P':
227       if (menu->top + menu->pagelen >= menu->max)
228         cp = menu->top ? "end" : "all";
229       else
230       {
231         count = (100 * (menu->top + menu->pagelen)) / menu->max;
232         snprintf (tmp, sizeof (tmp), "%d%%", count);
233         cp = tmp;
234       }
235       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
236       snprintf (buf, buflen, fmt, cp);
237       break;
238
239     case 'r':
240     {
241       int i = 0;
242
243       if (Context)
244       {
245         i = option(OPTATTACHMSG) ? 3 : ((Context->readonly ||
246           Context->dontwrite) ? 2 : (Context->changed || (
247 #ifdef USE_IMAP
248         /* deleted doesn't necessarily mean changed in IMAP */
249           Context->magic != M_IMAP &&
250 #endif
251           Context->deleted)) ? 1 : 0);
252       }
253       
254       if (!StChars)
255         buf[0] = 0;
256       else if (i >= mutt_strlen(StChars))
257         buf[0] = StChars[0];
258       else
259         buf[0] = StChars[i];
260
261       buf[1] = 0;
262       break;
263     }
264       
265     case 's':
266       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
267       snprintf (buf, buflen, fmt,
268                 get_sort_str (tmp, sizeof (tmp), Sort));
269       break;
270
271     case 'S':
272       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
273       snprintf (buf, buflen, fmt,
274                 get_sort_str (tmp, sizeof (tmp), SortAux));
275       break;
276
277     case 't':
278       if (!optional)
279       {
280         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
281         snprintf (buf, buflen, fmt, Context ? Context->tagged : 0);
282       }
283       else if (!Context || !Context->tagged)
284         optional = 0;
285       break;
286
287     case 'u':
288       if (!optional)
289       {
290         snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
291         snprintf (buf, buflen, fmt, Context ? Context->unread : 0);
292       }
293       else if (!Context || !Context->unread)
294         optional = 0;
295       break;
296
297     case 'v':
298       snprintf (fmt, sizeof (fmt), "Mutt-ng %%s");
299       snprintf (buf, buflen, fmt, MUTT_VERSION);
300       break;
301
302     case 'V':
303       if (!optional)
304       {
305         snprintf (fmt, sizeof(fmt), "%%%ss", prefix);
306         snprintf (buf, buflen, fmt, (Context && Context->pattern) ? Context->pattern : "");
307       }
308       else if (!Context || !Context->pattern)
309         optional = 0;
310       break;
311
312     case 0:
313       *buf = 0;
314       return (src);
315
316     default:
317       snprintf (buf, buflen, "%%%s%c", prefix, op);
318       break;
319   }
320
321   if (optional)
322     menu_status_line (buf, buflen, menu, ifstring);
323   else if (flags & M_FORMAT_OPTIONAL)
324     menu_status_line (buf, buflen, menu, elsestring);
325
326   return (src);
327 }
328
329 void menu_status_line (char *buf, size_t buflen, MUTTMENU *menu, const char *p)
330 {
331   mutt_FormatString (buf, buflen, p, status_format_str, (unsigned long) menu, 0);
332 }