sort out some prototypes, put them where they belong.
[apps/madmutt.git] / lib-ui / 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 <lib-lib/lib-lib.h>
15
16 #include <lib-ui/curses.h>
17 #include <lib-ui/menu.h>
18
19 #include "mutt.h"
20 #include "sort.h"
21 #include "mx.h"
22 #include "buffy.h"
23
24
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28
29 #define SW              (option(OPTMBOXPANE)?SidebarWidth:0)
30
31 static char *get_sort_str (char *buf, ssize_t buflen, int method)
32 {
33   snprintf (buf, buflen, "%s%s%s",
34             (method & SORT_REVERSE) ? "reverse-" : "",
35             (method & SORT_LAST) ? "last-" : "",
36             mutt_getnamebyvalue (method & SORT_MASK, SortMethods));
37   return buf;
38 }
39
40 /* %b = number of incoming folders with unread messages [option]
41  * %B = short mailbox path
42  * %d = number of deleted messages [option]
43  * %f = full mailbox path
44  * %F = number of flagged messages [option]
45  * %h = hostname
46  * %l = length of mailbox (in bytes) [option]
47  * %m = total number of messages [option]
48  * %M = number of messages shown (virutal message count when limiting) [option]
49  * %n = number of new messages [option]
50  * %p = number of postponed messages [option]
51  * %P = percent of way through index
52  * %r = readonly/wontwrite/changed flag
53  * %s = current sorting method ($sort)
54  * %S = current aux sorting method ($sort_aux)
55  * %t = # of tagged messages [option]
56  * %v = Madmutt version 
57  * %V = currently active limit pattern [option] */
58 static const char *status_format_str (char *buf, ssize_t buflen, char op,
59                                       const char *src, const char *prefix,
60                                       const char *ifstring,
61                                       const char *elsestring,
62                                       unsigned long data, format_flag flags)
63 {
64   char fmt[SHORT_STRING], tmp[SHORT_STRING];
65   const char *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     if (Context && Context->compressinfo && Context->realpath) {
83       if ((p = strrchr (Context->realpath, '/')))
84         m_strcpy(tmp, sizeof(tmp), p + 1);
85       else
86         m_strcpy(tmp, sizeof(tmp), Context->realpath);
87     }
88     else
89     if (Context && Context->path) {
90       if ((p = strrchr (Context->path, '/')))
91         m_strcpy(tmp, sizeof(tmp), p + 1);
92       else
93         m_strcpy(tmp, sizeof(tmp), Context->path);
94     }
95     else
96       m_strcpy(tmp, sizeof(tmp), _("no mailbox"));
97     snprintf (buf, buflen, fmt, tmp);
98     break;
99
100   case 'd':
101     if (!optional) {
102       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
103       snprintf (buf, buflen, fmt, Context ? Context->deleted : 0);
104     }
105     else if (!Context || !Context->deleted)
106       optional = 0;
107     break;
108
109   case 'h':
110     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
111     snprintf (buf, buflen, fmt, NONULL (Hostname));
112     break;
113
114   case 'f':
115     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
116     if (Context && Context->compressinfo && Context->realpath) {
117       m_strcpy(tmp, sizeof(tmp), Context->realpath);
118       mutt_pretty_mailbox (tmp);
119     }
120     else
121     if (Context && Context->path) {
122       m_strcpy(tmp, sizeof(tmp), Context->path);
123       mutt_pretty_mailbox (tmp);
124     }
125     else
126       m_strcpy(tmp, sizeof(tmp), _("(no mailbox)"));
127     snprintf (buf, buflen, fmt, tmp);
128     break;
129
130   case 'F':
131     if (!optional) {
132       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
133       snprintf (buf, buflen, fmt, Context ? Context->flagged : 0);
134     }
135     else if (!Context || !Context->flagged)
136       optional = 0;
137     break;
138
139   case 'l':
140     if (!optional) {
141       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
142       mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->size : 0);
143       snprintf (buf, buflen, fmt, tmp);
144     }
145     else if (!Context || !Context->size)
146       optional = 0;
147     break;
148
149   case 'L':
150     if (!optional) {
151       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
152       mutt_pretty_size (tmp, sizeof (tmp), Context ? Context->vsize : 0);
153       snprintf (buf, buflen, fmt, tmp);
154     }
155     else if (!Context || !Context->pattern)
156       optional = 0;
157     break;
158
159   case 'm':
160     if (!optional) {
161       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
162       snprintf (buf, buflen, fmt, Context ? Context->msgcount : 0);
163     }
164     else if (!Context || !Context->msgcount)
165       optional = 0;
166     break;
167
168   case 'M':
169     if (!optional) {
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       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
180       snprintf (buf, buflen, fmt, Context ? Context->new : 0);
181     }
182     else if (!Context || Context->new <= 0)
183       optional = 0;
184     break;
185
186   case 'o':
187     if (!optional) {
188       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
189       snprintf (buf, buflen, fmt,
190                 Context ? Context->unread - Context->new : 0);
191     }
192     else if (!Context || !(Context->unread - Context->new))
193       optional = 0;
194     break;
195
196   case 'p':
197     count = mutt_num_postponed (0);
198     if (!optional) {
199       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
200       snprintf (buf, buflen, fmt, count);
201     }
202     else if (!count)
203       optional = 0;
204     break;
205
206   case 'P':
207     if (menu->top + menu->pagelen >= menu->max)
208       cp = menu->top ? "end" : "all";
209     else {
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       int i = 0;
221
222       if (Context) {
223         /* XXX: deleted doesn't necessarily mean changed in IMAP */
224         i = option (OPTATTACHMSG) ? 3
225             : ((Context->readonly || Context->dontwrite) ? 2
226                : (Context->changed || (Context-> magic != M_IMAP && Context->
227                                         deleted)) ? 1 : 0);
228       }
229
230       if (!StChars)
231         buf[0] = 0;
232       else if (i >= m_strlen(StChars))
233         buf[0] = StChars[0];
234       else
235         buf[0] = StChars[i];
236
237       buf[1] = 0;
238       break;
239     }
240
241   case 's':
242     snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
243     snprintf (buf, buflen, fmt, 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, get_sort_str (tmp, sizeof (tmp), SortAux));
249     break;
250
251   case 't':
252     if (!optional) {
253       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
254       snprintf (buf, buflen, fmt, Context ? Context->tagged : 0);
255     }
256     else if (!Context || !Context->tagged)
257       optional = 0;
258     break;
259
260   case 'u':
261     if (!optional) {
262       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
263       snprintf (buf, buflen, fmt, Context ? Context->unread : 0);
264     }
265     else if (!Context || !Context->unread)
266       optional = 0;
267     break;
268
269   case 'v':
270     m_strcpy(buf, buflen, mutt_make_version(0));
271     break;
272
273   case 'V':
274     if (!optional) {
275       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
276       snprintf (buf, buflen, fmt,
277                 (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, menu, ifstring);
294   else if (flags & M_FORMAT_OPTIONAL)
295     menu_status_line (buf, buflen, menu, elsestring);
296
297   return (src);
298 }
299
300 void menu_status_line (char* buf, ssize_t len, MUTTMENU* menu, const char* p) {
301   /*
302    * if we have enough space for buffer, format lines to $COLS-$SidebarWidth
303    * only to not wrap past end of screen
304    */
305   int width = COLS - SW;
306   mutt_FormatString (buf, (width >= len ? len : (width + 1)),
307                      p, status_format_str,
308                      (unsigned long) menu, 0);
309 }