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