* Further improvements to color code to remove a bug that makes Pico
[alpine.git] / alpine / flagmaint.c
blobadab3c54d97c0d01c088f8a87bcf755066df587b
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: flagmaint.c 807 2007-11-09 01:21:33Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2016 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 #include "headers.h"
20 #include "flagmaint.h"
21 #include "confscroll.h"
22 #include "../pith/state.h"
23 #include "../pith/flag.h"
24 #include "../pith/status.h"
25 #include "../pith/mailcmd.h"
26 #include "../pith/icache.h"
29 #define FLAG_ADD_RETURN 15
33 * Internal prototypes
35 int flag_checkbox_tool(struct pine *, int, CONF_S **, unsigned);
38 /*----------------------------------------------------------------------
39 Function to control flag set/clearing
41 Basically, turn the flags into a fake list of features...
43 Returns 0 unless user has added a keyword, then 1.
45 ----*/
46 int
47 flag_maintenance_screen(struct pine *ps, struct flag_screen *flags)
49 int i, lv, lc, maxwidth, offset, need, rv = 0;
50 char tmp[1200], **p, *spacer;
51 CONF_S *ctmpa, *first_line;
52 struct flag_table *fp;
53 OPT_SCREEN_S screen;
55 try_again:
56 maxwidth = MAX(MIN((ps->ttyo ? ps->ttyo->screen_cols : 80), 150), 30);
57 first_line = NULL;
58 ctmpa = NULL;
60 for(p = flags->explanation; p && *p; p++){
61 new_confline(&ctmpa);
62 ctmpa->keymenu = &flag_keymenu;
63 ctmpa->help = NO_HELP;
64 ctmpa->tool = flag_checkbox_tool;
65 ctmpa->flags |= CF_NOSELECT;
66 ctmpa->valoffset = 0;
67 ctmpa->value = cpystr(_(*p));
70 /* Now wire flags checkboxes together */
71 for(lv = 0, lc = 0, fp = (flags->flag_table ? *flags->flag_table : NULL);
72 fp && fp->name; fp++){ /* longest name */
73 if(fp->flag != F_COMMENT){
74 if(lv < (i = utf8_width(_(fp->name))))
75 lv = i;
76 if(fp->comment && lc < (i = utf8_width(fp->comment)))
77 lc = i;
81 lv = MIN(lv,100);
82 lc = MIN(lc,100);
83 if(lc > 0)
84 spacer = " ";
85 else
86 spacer = "";
88 offset = 6;
89 if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth){
90 offset -= (need - maxwidth);
91 offset = MAX(0,offset);
92 if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth){
93 spacer = " ";
94 if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth){
95 lc -= (need - maxwidth);
96 lc = MAX(0,lc);
97 if(lc == 0)
98 spacer = "";
103 new_confline(&ctmpa);
104 ctmpa->keymenu = &flag_keymenu;
105 ctmpa->help = NO_HELP;
106 ctmpa->tool = flag_checkbox_tool;
107 ctmpa->flags |= CF_NOSELECT;
108 ctmpa->valoffset = 0;
109 ctmpa->value = cpystr("");
111 new_confline(&ctmpa);
112 ctmpa->keymenu = &flag_keymenu;
113 ctmpa->help = NO_HELP;
114 ctmpa->tool = flag_checkbox_tool;
115 ctmpa->flags |= CF_NOSELECT;
116 ctmpa->valoffset = 0;
117 utf8_snprintf(tmp, sizeof(tmp), "%*.*w %s", offset+3, offset+3, _("Set"), _("Flag/Keyword Name"));
118 tmp[sizeof(tmp)-1] = '\0';
119 ctmpa->value = cpystr(tmp);
121 new_confline(&ctmpa);
122 ctmpa->keymenu = &flag_keymenu;
123 ctmpa->help = NO_HELP;
124 ctmpa->tool = flag_checkbox_tool;
125 ctmpa->flags |= CF_NOSELECT;
126 ctmpa->valoffset = 0;
127 snprintf(tmp, sizeof(tmp), "%*.*s--- %.*s",
128 offset, offset, "",
129 (int)(lv+lc+strlen(spacer)), repeat_char(lv+lc+strlen(spacer), '-'));
130 tmp[sizeof(tmp)-1] = '\0';
131 ctmpa->value = cpystr(tmp);
133 for(fp = (flags->flag_table ? *flags->flag_table : NULL);
134 fp && fp->name; fp++){ /* build the list */
135 new_confline(&ctmpa);
136 if(!first_line && (fp->flag != F_COMMENT))
137 first_line = ctmpa;
139 ctmpa->keymenu = &flag_keymenu;
140 ctmpa->tool = flag_checkbox_tool;
141 ctmpa->valoffset = offset;
143 if(fp->flag == F_COMMENT){
144 ctmpa->help = NO_HELP;
145 ctmpa->flags |= CF_NOSELECT;
146 ctmpa->value = cpystr(fp->name);
148 else{
149 ctmpa->help = fp->help;
150 ctmpa->d.f.ftbl = flags->flag_table;
151 ctmpa->d.f.fp = fp;
153 utf8_snprintf(tmp, sizeof(tmp), "[%c] %-*.*w%s%-*.*w",
154 (fp->set == 0) ? ' ' : (fp->set == 1) ? 'X' : '?',
155 lv, lv, _(fp->name),
156 spacer, lc, lc, fp->comment ? fp->comment : "");
157 ctmpa->value = cpystr(tmp);
161 memset(&screen, 0, sizeof(screen));
163 * TRANSLATORS: FLAG MAINTENANCE is a screen title.
164 * Print something1 using something2. configuration is something1
166 if(conf_scroll_screen(ps, &screen, first_line,
167 _("FLAG MAINTENANCE"),
168 _("configuration"), 0, NULL) == FLAG_ADD_RETURN){
169 int flags, r;
170 char keyword[500];
171 char nickname[500];
172 char prompt[500];
173 char *error = NULL;
174 KEYWORD_S *kw;
175 HelpType help;
178 * User is asking to add a new keyword. We will add it to the
179 * mailbox if necessary and add it to the keywords list from
180 * Setup/Config. Then we will modify the flag_table and present
181 * the flag modification screen again.
184 ps->mangled_screen = 1;
185 keyword[0] = '\0';
186 flags = OE_APPEND_CURRENT;
187 help = NO_HELP;
190 if(error){
191 q_status_message(SM_ORDER, 3, 4, error);
192 fs_give((void **) &error);
195 strncpy(prompt, _("Keyword to be added : "), sizeof(prompt)-1);
196 prompt[sizeof(prompt)-1] = '\0';
197 r = optionally_enter(keyword, -FOOTER_ROWS(ps_global), 0,
198 sizeof(keyword), prompt, NULL, help, &flags);
200 if(r == 3)
201 help = help == NO_HELP ? h_type_keyword : NO_HELP;
202 else if(r == 1){
203 cmd_cancelled("Add Keyword");
204 goto try_again;
207 removing_leading_and_trailing_white_space(keyword);
209 }while(r == 3 || keyword_check(keyword, &error));
211 for(kw = ps->keywords; kw; kw = kw->next){
212 if(kw->kw && !strucmp(kw->kw, keyword)){
213 q_status_message(SM_ORDER, 3, 4, _("Keyword already configured, changing nickname"));
214 break;
218 snprintf(prompt, sizeof(prompt), _("Optional nickname for \"%s\" : "), keyword);
220 nickname[0] = '\0';
221 help = NO_HELP;
224 r = optionally_enter(nickname, -FOOTER_ROWS(ps_global), 0,
225 sizeof(nickname), prompt, NULL, help, &flags);
227 if(r == 3)
228 help = help == NO_HELP ? h_type_keyword_nickname : NO_HELP;
229 else if(r == 1){
230 cmd_cancelled("Add Keyword");
231 goto try_again;
234 removing_leading_and_trailing_white_space(nickname);
236 }while(r == 3);
238 if(keyword[0]){
239 char ***alval;
240 int offset = -1;
241 struct variable *var;
243 var = &ps_global->vars[V_KEYWORDS];
244 alval = ALVAL(var, Main);
246 for(kw = ps->keywords; kw; kw = kw->next){
247 offset++;
248 if(kw->kw && !strucmp(kw->kw, keyword)){
249 /* looks like it should already exist at offset */
250 break;
254 if(!kw)
255 offset = -1;
257 if(offset >= 0 && (*alval) && (*alval)[offset]){
258 fs_give((void **) &(*alval)[offset]);
259 (*alval)[offset] = put_pair(nickname, keyword);
261 else if(!*alval){
262 offset = 0;
263 *alval = (char **) fs_get(2*sizeof(char *));
264 (*alval)[offset] = put_pair(nickname, keyword);
265 (*alval)[offset+1] = NULL;
267 else{
268 for(offset=0; (*alval)[offset]; offset++)
271 fs_resize((void **) alval, (offset + 2) * sizeof(char *));
272 (*alval)[offset] = put_pair(nickname, keyword);
273 (*alval)[offset+1] = NULL;
276 set_current_val(var, TRUE, FALSE);
277 if(ps_global->prc)
278 ps_global->prc->outstanding_pinerc_changes = 1;
280 if(ps_global->keywords)
281 free_keyword_list(&ps_global->keywords);
283 if(var->current_val.l && var->current_val.l[0])
284 ps_global->keywords = init_keyword_list(var->current_val.l);
286 clear_index_cache(ps_global->mail_stream, 0);
288 rv = 1;
292 ps->mangled_screen = 1;
294 return(rv);
299 * Message flag manipulation tool
302 * returns: -1 on unrecognized cmd, 0 if no change, 1 if change
305 flag_checkbox_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
307 int rv = 0, state;
309 switch(cmd){
310 case MC_TOGGLE: /* mark/unmark feature */
311 state = (*cl)->d.f.fp->set;
312 state = (state == 1) ? 0 : (!state && ((*cl)->d.f.fp->ukn)) ? 2 : 1;
313 (*cl)->value[1] = (state == 0) ? ' ' : ((state == 1) ? 'X': '?');
314 (*cl)->d.f.fp->set = state;
315 rv = 1;
316 break;
318 case MC_ADD:
319 rv = FLAG_ADD_RETURN;
320 break;
322 case MC_EXIT: /* exit */
323 rv = simple_exit_cmd(flags);
324 break;
326 default :
327 rv = -1;
328 break;
331 return(rv);