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