2 * ========================================================================
3 * Copyright 2006-2007 University of Washington
4 * Copyright 2013-2022 Eduardo Chappa
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
16 #include "flagmaint.h"
17 #include "confscroll.h"
18 #include "../pith/state.h"
19 #include "../pith/flag.h"
20 #include "../pith/status.h"
21 #include "../pith/mailcmd.h"
22 #include "../pith/icache.h"
25 #define FLAG_ADD_RETURN 15
31 int flag_checkbox_tool(struct pine
*, int, CONF_S
**, unsigned);
34 /*----------------------------------------------------------------------
35 Function to control flag set/clearing
37 Basically, turn the flags into a fake list of features...
39 Returns 0 unless user has added a keyword, then 1.
43 flag_maintenance_screen(struct pine
*ps
, struct flag_screen
*flags
)
45 int i
, lv
, lc
, maxwidth
, offset
, need
, rv
= 0;
46 char tmp
[1200], **p
, *spacer
;
47 CONF_S
*ctmpa
, *first_line
;
48 struct flag_table
*fp
;
52 maxwidth
= MAX(MIN((ps
->ttyo
? ps
->ttyo
->screen_cols
: 80), 150), 30);
56 for(p
= flags
->explanation
; p
&& *p
; p
++){
58 ctmpa
->keymenu
= &flag_keymenu
;
59 ctmpa
->help
= NO_HELP
;
60 ctmpa
->tool
= flag_checkbox_tool
;
61 ctmpa
->flags
|= CF_NOSELECT
;
63 ctmpa
->value
= cpystr(_(*p
));
66 /* Now wire flags checkboxes together */
67 for(lv
= 0, lc
= 0, fp
= (flags
->flag_table
? *flags
->flag_table
: NULL
);
68 fp
&& fp
->name
; fp
++){ /* longest name */
69 if(fp
->flag
!= F_COMMENT
){
70 if(lv
< (i
= utf8_width(_(fp
->name
))))
72 if(fp
->comment
&& lc
< (i
= utf8_width(fp
->comment
)))
85 if((need
= offset
+ 5 + lv
+ strlen(spacer
) + lc
) > maxwidth
){
86 offset
-= (need
- maxwidth
);
87 offset
= MAX(0,offset
);
88 if((need
= offset
+ 5 + lv
+ strlen(spacer
) + lc
) > maxwidth
){
90 if((need
= offset
+ 5 + lv
+ strlen(spacer
) + lc
) > maxwidth
){
91 lc
-= (need
- maxwidth
);
100 ctmpa
->keymenu
= &flag_keymenu
;
101 ctmpa
->help
= NO_HELP
;
102 ctmpa
->tool
= flag_checkbox_tool
;
103 ctmpa
->flags
|= CF_NOSELECT
;
104 ctmpa
->valoffset
= 0;
105 ctmpa
->value
= cpystr("");
107 new_confline(&ctmpa
);
108 ctmpa
->keymenu
= &flag_keymenu
;
109 ctmpa
->help
= NO_HELP
;
110 ctmpa
->tool
= flag_checkbox_tool
;
111 ctmpa
->flags
|= CF_NOSELECT
;
112 ctmpa
->valoffset
= 0;
113 utf8_snprintf(tmp
, sizeof(tmp
), "%*.*w %s", offset
+3, offset
+3, _("Set"), _("Flag/Keyword Name"));
114 tmp
[sizeof(tmp
)-1] = '\0';
115 ctmpa
->value
= cpystr(tmp
);
117 new_confline(&ctmpa
);
118 ctmpa
->keymenu
= &flag_keymenu
;
119 ctmpa
->help
= NO_HELP
;
120 ctmpa
->tool
= flag_checkbox_tool
;
121 ctmpa
->flags
|= CF_NOSELECT
;
122 ctmpa
->valoffset
= 0;
123 snprintf(tmp
, sizeof(tmp
), "%*.*s--- %.*s",
125 (int)(lv
+lc
+strlen(spacer
)), repeat_char(lv
+lc
+strlen(spacer
), '-'));
126 tmp
[sizeof(tmp
)-1] = '\0';
127 ctmpa
->value
= cpystr(tmp
);
129 for(fp
= (flags
->flag_table
? *flags
->flag_table
: NULL
);
130 fp
&& fp
->name
; fp
++){ /* build the list */
131 new_confline(&ctmpa
);
132 if(!first_line
&& (fp
->flag
!= F_COMMENT
))
135 ctmpa
->keymenu
= &flag_keymenu
;
136 ctmpa
->tool
= flag_checkbox_tool
;
137 ctmpa
->valoffset
= offset
;
139 if(fp
->flag
== F_COMMENT
){
140 ctmpa
->help
= NO_HELP
;
141 ctmpa
->flags
|= CF_NOSELECT
;
142 ctmpa
->value
= cpystr(fp
->name
);
145 ctmpa
->help
= fp
->help
;
146 ctmpa
->d
.f
.ftbl
= flags
->flag_table
;
149 utf8_snprintf(tmp
, sizeof(tmp
), "[%c] %-*.*w%s%-*.*w",
150 (fp
->set
== 0) ? ' ' : (fp
->set
== 1) ? 'X' : '?',
152 spacer
, lc
, lc
, fp
->comment
? fp
->comment
: "");
153 ctmpa
->value
= cpystr(tmp
);
157 memset(&screen
, 0, sizeof(screen
));
159 * TRANSLATORS: FLAG MAINTENANCE is a screen title.
160 * Print something1 using something2. configuration is something1
162 if(conf_scroll_screen(ps
, &screen
, first_line
,
163 _("FLAG MAINTENANCE"),
164 _("configuration"), 0, NULL
) == FLAG_ADD_RETURN
){
174 * User is asking to add a new keyword. We will add it to the
175 * mailbox if necessary and add it to the keywords list from
176 * Setup/Config. Then we will modify the flag_table and present
177 * the flag modification screen again.
180 ps
->mangled_screen
= 1;
182 flags
= OE_APPEND_CURRENT
;
187 q_status_message(SM_ORDER
, 3, 4, error
);
188 fs_give((void **) &error
);
191 strncpy(prompt
, _("Keyword to be added : "), sizeof(prompt
)-1);
192 prompt
[sizeof(prompt
)-1] = '\0';
193 r
= optionally_enter(keyword
, -FOOTER_ROWS(ps_global
), 0,
194 sizeof(keyword
), prompt
, NULL
, help
, &flags
);
197 help
= help
== NO_HELP
? h_type_keyword
: NO_HELP
;
199 cmd_cancelled("Add Keyword");
203 removing_leading_and_trailing_white_space(keyword
);
205 }while(r
== 3 || keyword_check(keyword
, &error
));
207 for(kw
= ps
->keywords
; kw
; kw
= kw
->next
){
208 if(kw
->kw
&& !strucmp(kw
->kw
, keyword
)){
209 q_status_message(SM_ORDER
, 3, 4, _("Keyword already configured, changing nickname"));
214 snprintf(prompt
, sizeof(prompt
), _("Optional nickname for \"%s\" : "), keyword
);
220 r
= optionally_enter(nickname
, -FOOTER_ROWS(ps_global
), 0,
221 sizeof(nickname
), prompt
, NULL
, help
, &flags
);
224 help
= help
== NO_HELP
? h_type_keyword_nickname
: NO_HELP
;
226 cmd_cancelled("Add Keyword");
230 removing_leading_and_trailing_white_space(nickname
);
237 struct variable
*var
;
239 var
= &ps_global
->vars
[V_KEYWORDS
];
240 alval
= ALVAL(var
, Main
);
242 for(kw
= ps
->keywords
; kw
; kw
= kw
->next
){
244 if(kw
->kw
&& !strucmp(kw
->kw
, keyword
)){
245 /* looks like it should already exist at offset */
253 if(offset
>= 0 && (*alval
) && (*alval
)[offset
]){
254 fs_give((void **) &(*alval
)[offset
]);
255 (*alval
)[offset
] = put_pair(nickname
, keyword
);
259 *alval
= (char **) fs_get(2*sizeof(char *));
260 (*alval
)[offset
] = put_pair(nickname
, keyword
);
261 (*alval
)[offset
+1] = NULL
;
264 for(offset
=0; (*alval
)[offset
]; offset
++)
267 fs_resize((void **) alval
, (offset
+ 2) * sizeof(char *));
268 (*alval
)[offset
] = put_pair(nickname
, keyword
);
269 (*alval
)[offset
+1] = NULL
;
272 set_current_val(var
, TRUE
, FALSE
);
274 ps_global
->prc
->outstanding_pinerc_changes
= 1;
276 if(ps_global
->keywords
)
277 free_keyword_list(&ps_global
->keywords
);
279 if(var
->current_val
.l
&& var
->current_val
.l
[0])
280 ps_global
->keywords
= init_keyword_list(var
->current_val
.l
);
282 clear_index_cache(ps_global
->mail_stream
, 0);
288 ps
->mangled_screen
= 1;
295 * Message flag manipulation tool
298 * returns: -1 on unrecognized cmd, 0 if no change, 1 if change
301 flag_checkbox_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
306 case MC_TOGGLE
: /* mark/unmark feature */
307 state
= (*cl
)->d
.f
.fp
->set
;
308 state
= (state
== 1) ? 0 : (!state
&& ((*cl
)->d
.f
.fp
->ukn
)) ? 2 : 1;
309 (*cl
)->value
[1] = (state
== 0) ? ' ' : ((state
== 1) ? 'X': '?');
310 (*cl
)->d
.f
.fp
->set
= state
;
315 rv
= FLAG_ADD_RETURN
;
318 case MC_EXIT
: /* exit */
319 rv
= simple_exit_cmd(flags
);