2a6f70b3aee10d0b96ece369a8f1d2980f639226
[apps/madmutt.git] / status.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 #if HAVE_CONFIG_H
11 # include "config.h"
12 #endif
13
14 #include "mutt.h"
15 #include "mutt_menu.h"
16 #include "mutt_curses.h"
17 #include "sort.h"
18 #include "mapping.h"
19 #include "mx.h"
20
21 #include <string.h>
22 #include <ctype.h>
23 #include <unistd.h>
24
25 static char *get_sort_str (char *buf, size_t buflen, int method)
26 {
27   snprintf (buf, buflen, "%s%s%s",
28             (method & SORT_REVERSE) ? "reverse-" : "",
29             (method & SORT_LAST) ? "last-" : "",
30             mutt_getnamebyvalue (method & SORT_MASK, SortMethods));
31   return buf;
32 }
33
34 /* %b = number of incoming folders with unread messages [option]
35  * %B = short mailbox path
36  * %d = number of deleted messages [option]
37  * %f = full mailbox path
38  * %F = number of flagged messages [option]
39  * %h = hostname
40  * %l = length of mailbox (in bytes) [option]
41  * %m = total number of messages [option]
42  * %M = number of messages shown (virutal message count when limiting) [option]
43  * %n = number of new messages [option]
44  * %p = number of postponed messages [option]
45  * %P = percent of way through index
46  * %r = readonly/wontwrite/changed flag
47  * %s = current sorting method ($sort)
48  * %S = current aux sorting method ($sort_aux)
49  * %t = # of tagged messages [option]
50  * %v = Mutt-ng version 
51  * %V = currently active limit pattern [option] */
52 static const char *status_format_str (char *buf, size_t buflen, char op,
53                                       const char *src, const char *prefix,
54                                       const char *ifstring,
55                                       const char *elsestring,
56                                       unsigned long data, format_flag flags)
57 {
58   char fmt[SHORT_STRING], tmp[SHORT_STRING], *cp, *p;
59   int count, optional = (flags & M_FORMAT_OPTIONAL);
60   MUTTMENU *menu = (MUTTMENU *) data;
61
62   *buf = 0;
63   switch (op) {
64   case 'b':
65     if (!optional) {
66       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
67       snprintf (buf, buflen, fmt, mutt_buffy_check (0));
68     }
69     else if (!mutt_buffy_check (0))
70       optional = 0;
71     break;
72
73   case 'B':
74     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
75 #ifdef USE_COMPRESSED
76     if (Context && Context->compressinfo && Context->realpath) {
77       if ((p = strrchr (Context->realpath, '/')))
78         strfcpy (tmp, p + 1, sizeof (tmp));
79       else
80         strfcpy (tmp, Context->realpath, sizeof (tmp));
81     }
82     else
83 #endif
84     if (Context && Context->path) {
85       if ((p = strrchr (Context->path, '/')))
86         strfcpy (tmp, p + 1, sizeof (tmp));
87       else
88         strfcpy (tmp, Context->path, sizeof (tmp));
89     }
90     else
91       strfcpy (tmp, _("no mailbox"), sizeof (tmp));
92     snprintf (buf, buflen, fmt, tmp);
93     break;
94
95   case 'd':
96     if (!optional) {
97       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
98       snprintf (buf, buflen, fmt, Context ? Context->deleted : 0);
99     }
100     else if (!Context || !Context->deleted)
101       optional = 0;
102     break;
103
104   case 'h':
105     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
106     snprintf (buf, buflen, fmt, NONULL (Hostname));
107     break;
108
109   case 'f':
110     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
111 #ifdef USE_COMPRESSED
112     if (Context && Context->compressinfo && Context->realpath) {
113       strfcpy (tmp, Context->realpath, sizeof (tmp));
114       mutt_pretty_mailbox (tmp);
115     }
116     else
117 #endif
118     if (Context && Context->path) {
119       strfcpy (tmp, Context->path, sizeof (tmp));
120       mutt_pretty_mailbox (tmp);
121     }
122     else
123       strfcpy (tmp, _("(no mailbox)"), sizeof (tmp));
124     snprintf (buf, buflen, fmt, tmp);
125     break;
126
127   case 'F':
128     if (!optional) {
129       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
130       snprintf (buf, buflen, fmt, Context ? Context->flagged : 0);
131     }
132     else if (!Context || !Context->flagged)
133       optional = 0;
134     break;
135
136   case 'l':
137     if (!optional) {
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       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
149       mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->vsize : 0);
150       snprintf (buf, buflen, fmt, tmp);
151     }
152     else if (!Context || !Context->pattern)
153       optional = 0;
154     break;
155
156   case 'm':
157     if (!optional) {
158       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
159       snprintf (buf, buflen, fmt, Context ? Context->msgcount : 0);
160     }
161     else if (!Context || !Context->msgcount)
162       optional = 0;
163     break;
164
165   case 'M':
166     if (!optional) {
167       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
168       snprintf (buf, buflen, fmt, Context ? Context->vcount : 0);
169     }
170     else if (!Context || !Context->pattern)
171       optional = 0;
172     break;
173
174   case 'n':
175     if (!optional) {
176       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
177       snprintf (buf, buflen, fmt, Context ? Context->new : 0);
178     }
179     else if (!Context || Context->new <= 0)
180       optional = 0;
181     break;
182
183   case 'o':
184     if (!optional) {
185       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
186       snprintf (buf, buflen, fmt,
187                 Context ? Context->unread - Context->new : 0);
188     }
189     else if (!Context || !(Context->unread - Context->new))
190       optional = 0;
191     break;
192
193   case 'p':
194     count = mutt_num_postponed (0);
195     if (!optional) {
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->top + menu->pagelen >= menu->max)
205       cp = menu->top ? "end" : "all";
206     else {
207       count = (100 * (menu->top + menu->pagelen)) / menu->max;
208       snprintf (tmp, sizeof (tmp), "%d%%", count);
209       cp = tmp;
210     }
211     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
212     snprintf (buf, buflen, fmt, cp);
213     break;
214
215   case 'r':
216     {
217       int i = 0;
218
219       if (Context) {
220         i = option (OPTATTACHMSG) ? 3 : ((Context->readonly ||
221                                           Context->dontwrite) ? 2 : (Context->
222                                                                      changed
223                                                                      || (
224 #ifdef USE_IMAP
225                                                                              /* deleted doesn't necessarily mean changed in IMAP */
226                                                                              Context->
227                                                                              magic
228                                                                              !=
229                                                                              M_IMAP
230                                                                              &&
231 #endif
232                                                                              Context->
233                                                                              deleted))
234                                          ? 1 : 0);
235       }
236
237       if (!StChars)
238         buf[0] = 0;
239       else if (i >= mutt_strlen (StChars))
240         buf[0] = StChars[0];
241       else
242         buf[0] = StChars[i];
243
244       buf[1] = 0;
245       break;
246     }
247
248   case 's':
249     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
250     snprintf (buf, buflen, fmt, get_sort_str (tmp, sizeof (tmp), Sort));
251     break;
252
253   case 'S':
254     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
255     snprintf (buf, buflen, fmt, get_sort_str (tmp, sizeof (tmp), SortAux));
256     break;
257
258   case 't':
259     if (!optional) {
260       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
261       snprintf (buf, buflen, fmt, Context ? Context->tagged : 0);
262     }
263     else if (!Context || !Context->tagged)
264       optional = 0;
265     break;
266
267   case 'u':
268     if (!optional) {
269       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
270       snprintf (buf, buflen, fmt, Context ? Context->unread : 0);
271     }
272     else if (!Context || !Context->unread)
273       optional = 0;
274     break;
275
276   case 'v':
277     snprintf (fmt, sizeof (fmt), "Mutt-ng %%s");
278     snprintf (buf, buflen, fmt, MUTT_VERSION);
279     break;
280
281   case 'V':
282     if (!optional) {
283       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
284       snprintf (buf, buflen, fmt,
285                 (Context && Context->pattern) ? Context->pattern : "");
286     }
287     else if (!Context || !Context->pattern)
288       optional = 0;
289     break;
290
291   case 0:
292     *buf = 0;
293     return (src);
294
295   default:
296     snprintf (buf, buflen, "%%%s%c", prefix, op);
297     break;
298   }
299
300   if (optional)
301     menu_status_line (buf, buflen, menu, ifstring);
302   else if (flags & M_FORMAT_OPTIONAL)
303     menu_status_line (buf, buflen, menu, elsestring);
304
305   return (src);
306 }
307
308 void menu_status_line (char *buf, size_t buflen, MUTTMENU * menu,
309                        const char *p)
310 {
311   mutt_FormatString (buf, buflen, p, status_format_str, (unsigned long) menu,
312                      0);
313 }