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