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