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