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 "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
34static 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
43static void _menu_status_line (char *buf, size_t buflen, size_t col, int cols, 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] */
64static const char *
65status_format_str (char *buf, size_t buflen, size_t col, int cols, 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 & MUTT_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#ifdef USE_COMPRESSED
100 if (Context && Context->compress_info && Context->realpath) {
101 strfcpy (tmp, Context->realpath, sizeof (tmp));
102 mutt_pretty_mailbox (tmp, sizeof (tmp));
103 } else
104#endif
105 if (Context && Context->path)
106 {
107 strfcpy (tmp, Context->path, sizeof (tmp));
108 mutt_pretty_mailbox (tmp, sizeof (tmp));
109 }
110 else
111 strfcpy (tmp, _("(no mailbox)"), sizeof (tmp));
112 snprintf (buf, buflen, fmt, tmp);
113 break;
114
115 case 'F':
116 if (!optional)
117 {
118 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
119 snprintf (buf, buflen, fmt, Context ? Context->flagged : 0);
120 }
121 else if (!Context || !Context->flagged)
122 optional = 0;
123 break;
124
125 case 'h':
126 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
127 snprintf (buf, buflen, fmt, NONULL(Hostname));
128 break;
129
130 case 'l':
131 if (!optional)
132 {
133 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
134 mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->size : 0);
135 snprintf (buf, buflen, fmt, tmp);
136 }
137 else if (!Context || !Context->size)
138 optional = 0;
139 break;
140
141 case 'L':
142 if (!optional)
143 {
144 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
145 mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->vsize: 0);
146 snprintf (buf, buflen, fmt, tmp);
147 }
148 else if (!Context || !Context->pattern)
149 optional = 0;
150 break;
151
152 case 'm':
153 if (!optional)
154 {
155 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
156 snprintf (buf, buflen, fmt, Context ? Context->msgcount : 0);
157 }
158 else if (!Context || !Context->msgcount)
159 optional = 0;
160 break;
161
162 case 'M':
163 if (!optional)
164 {
165 snprintf (fmt, sizeof(fmt), "%%%sd", prefix);
166 snprintf (buf, buflen, fmt, Context ? Context->vcount : 0);
167 }
168 else if (!Context || !Context->pattern)
169 optional = 0;
170 break;
171
172 case 'n':
173 if (!optional)
174 {
175 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
176 snprintf (buf, buflen, fmt, Context ? Context->new : 0);
177 }
178 else if (!Context || !Context->new)
179 optional = 0;
180 break;
181
182 case 'o':
183 if (!optional)
184 {
185 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
186 snprintf (buf, buflen, fmt, Context ? Context->unread - Context->new : 0);
187 }
188 else if (!Context || !(Context->unread - Context->new))
189 optional = 0;
190 break;
191
192 case 'p':
193 count = mutt_num_postponed (0);
194 if (!optional)
195 {
196 snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
197 snprintf (buf, buflen, fmt, count);
198 }
199 else if (!count)
200 optional = 0;
201 break;
202
203 case 'P':
204 if (!menu)
205 break;
206 if (menu->top + menu->pagelen >= menu->max)
207 cp = menu->top ? "end" : "all";
208 else
209 {
210 count = (100 * (menu->top + menu->pagelen)) / menu->max;
211 snprintf (tmp, sizeof (tmp), "%d%%", count);
212 cp = tmp;
213 }
214 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
215 snprintf (buf, buflen, fmt, cp);
216 break;
217
218 case 'r':
219 {
220 size_t i = 0;
221
222 if (Context)
223 {
224 i = option(OPTATTACHMSG) ? 3 : ((Context->readonly ||
225 Context->dontwrite) ? 2 : (Context->changed ||
226 /* deleted doesn't necessarily mean changed in IMAP */
227 (Context->magic != MUTT_IMAP &&
228 Context->deleted)) ? 1 : 0);
229 }
230
231 if (!StChars || !StChars->len)
232 buf[0] = 0;
233 else if (i >= StChars->len)
234 snprintf (buf, buflen, "%s", StChars->chars[0]);
235 else
236 snprintf (buf, buflen, "%s", StChars->chars[i]);
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 %%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, col, cols, menu, ifstring);
298 else if (flags & MUTT_FORMAT_OPTIONAL)
299 _menu_status_line (buf, buflen, col, cols, menu, elsestring);
300
301 return (src);
302}
303
304static void _menu_status_line (char *buf, size_t buflen, size_t col, int cols, MUTTMENU *menu, const char *p)
305{
306 mutt_FormatString (buf, buflen, col, cols, p, status_format_str, (unsigned long) menu, 0);
307}
308
309void menu_status_line (char *buf, size_t buflen, MUTTMENU *menu, const char *p)
310{
311 mutt_FormatString (buf, buflen, 0,
312 menu ? menu->statuswin->cols : MuttStatusWindow->cols,
313 p, status_format_str, (unsigned long) menu, 0);
314}