1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: setup.c 918 2008-01-23 19:39:38Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2008 University of Washington
8 * Copyright 2013-2015 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 * ========================================================================
23 #include "confscroll.h"
24 #include "colorconf.h"
30 #include "../pith/state.h"
31 #include "../pith/conf.h"
32 #include "../pith/util.h"
33 #include "../pith/sort.h"
34 #include "../pith/folder.h"
35 #include "../pith/list.h"
36 #include "../pith/icache.h"
42 int inbox_path_text_tool(struct pine
*, int, CONF_S
**, unsigned);
43 int incoming_monitoring_list_tool(struct pine
*, int, CONF_S
**, unsigned);
44 int stayopen_list_tool(struct pine
*, int, CONF_S
**, unsigned);
45 char **adjust_list_of_monitored_incoming(CONTEXT_S
*, EditWhich
, int);
46 int to_charsets_text_tool(struct pine
*, int, CONF_S
**, unsigned);
49 #define CONFIG_SCREEN_TITLE _("SETUP CONFIGURATION")
50 #define CONFIG_SCREEN_TITLE_EXC _("SETUP CONFIGURATION EXCEPTIONS")
54 /*----------------------------------------------------------------------
55 Present pinerc data for manipulation
59 Result: help edit certain pinerc fields.
62 option_screen(struct pine
*ps
, int edit_exceptions
)
64 char tmp
[MAXPATH
+1], *pval
, **lval
;
65 int i
, j
, ln
= 0, readonly_warning
= 0, pos
;
66 struct variable
*vtmp
;
67 CONF_S
*ctmpa
= NULL
, *ctmpb
, *first_line
= NULL
;
70 SAVED_CONFIG_S
*vsave
;
72 int expose_hidden_config
, add_hidden_vars_title
= 0;
74 dprint((3, "-- option_screen --\n"));
76 expose_hidden_config
= F_ON(F_EXPOSE_HIDDEN_CONFIG
, ps_global
);
77 treat_color_vars_as_text
= expose_hidden_config
;
79 ew
= edit_exceptions
? ps_global
->ew_for_except_vars
: Main
;
95 readonly_warning
= prc
? prc
->readonly
: 1;
96 if(prc
&& prc
->quit_to_edit
){
97 quit_to_edit_msg(prc
);
98 treat_color_vars_as_text
= 0;
103 ps
->next_screen
= SCREEN_FUN_NULL
;
105 mailcap_free(); /* free resources we won't be using for a while */
107 if(ps
->fix_fixed_warning
)
108 offer_to_fix_pinerc(ps
);
111 do { /* Beginning of BIG LOOP */
112 ctmpa
= first_line
= NULL
;
115 * First, find longest variable name
117 for(vtmp
= ps
->vars
; vtmp
->name
; vtmp
++){
118 if(exclude_config_var(ps
, vtmp
, expose_hidden_config
))
121 if((i
= utf8_width(pretty_var_name(vtmp
->name
))) > ln
)
125 dprint((9, "initialize config list\n"));
128 * Next, allocate and initialize config line list...
130 for(vtmp
= ps
->vars
; vtmp
->name
; vtmp
++){
132 * INCOMING_FOLDERS is currently the first of the normally
133 * hidden variables. Should probably invent a more robust way
134 * to keep this up to date.
136 if(expose_hidden_config
&& vtmp
== &ps
->vars
[V_INCOMING_FOLDERS
])
137 add_hidden_vars_title
= 1;
139 if(exclude_config_var(ps
, vtmp
, expose_hidden_config
))
142 if(add_hidden_vars_title
){
144 add_hidden_vars_title
= 0;
146 new_confline(&ctmpa
); /* Blank line */
147 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
149 new_confline(&ctmpa
)->var
= NULL
;
150 ctmpa
->help
= NO_HELP
;
151 ctmpa
->valoffset
= 2;
152 ctmpa
->flags
|= CF_NOSELECT
;
153 ctmpa
->value
= cpystr("--- [ Normally hidden configuration options ] ---");
155 new_confline(&ctmpa
); /* Blank line */
156 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
160 lval
= LVAL(vtmp
, ew
);
162 pval
= PVAL(vtmp
, ew
);
164 new_confline(&ctmpa
)->var
= vtmp
;
168 ctmpa
->valoffset
= ln
+ 3;
170 ctmpa
->keymenu
= &config_text_wshuf_keymenu
;
172 ctmpa
->keymenu
= &config_text_keymenu
;
174 ctmpa
->help
= config_help(vtmp
- ps
->vars
, 0);
175 ctmpa
->tool
= text_tool
;
177 utf8_snprintf(tmp
, sizeof(tmp
), "%-*.100w =", ln
, pretty_var_name(vtmp
->name
));
178 tmp
[sizeof(tmp
)-1] = '\0';
179 ctmpa
->varname
= cpystr(tmp
);
180 ctmpa
->varnamep
= ctmpb
= ctmpa
;
181 ctmpa
->flags
|= CF_STARTITEM
;
182 if(vtmp
== &ps
->vars
[V_FEATURE_LIST
]){ /* special checkbox case */
183 char *this_sect
, *new_sect
;
185 ctmpa
->flags
|= CF_NOSELECT
;
186 ctmpa
->keymenu
= &config_checkbox_keymenu
;
189 /* put a nice delimiter before list */
190 new_confline(&ctmpa
)->var
= NULL
;
191 ctmpa
->varnamep
= ctmpb
;
192 ctmpa
->keymenu
= &config_checkbox_keymenu
;
193 ctmpa
->help
= NO_HELP
;
194 ctmpa
->tool
= checkbox_tool
;
195 ctmpa
->valoffset
= feature_indent();
196 ctmpa
->flags
|= CF_NOSELECT
;
197 ctmpa
->value
= cpystr("Set Feature Name");
199 new_confline(&ctmpa
)->var
= NULL
;
200 ctmpa
->varnamep
= ctmpb
;
201 ctmpa
->keymenu
= &config_checkbox_keymenu
;
202 ctmpa
->help
= NO_HELP
;
203 ctmpa
->tool
= checkbox_tool
;
204 ctmpa
->valoffset
= feature_indent();
205 ctmpa
->flags
|= CF_NOSELECT
;
206 ctmpa
->value
= cpystr("--- ----------------------");
208 for(i
= 0, this_sect
= NULL
; (feature
= feature_list(i
)); i
++)
209 if((new_sect
= feature_list_section(feature
)) &&
210 (strcmp(new_sect
, HIDDEN_PREF
) != 0)){
211 if(this_sect
!= new_sect
){
212 new_confline(&ctmpa
)->var
= NULL
;
213 ctmpa
->varnamep
= ctmpb
;
214 ctmpa
->keymenu
= &config_checkbox_keymenu
;
215 ctmpa
->help
= NO_HELP
;
216 ctmpa
->tool
= checkbox_tool
;
217 ctmpa
->valoffset
= 2;
218 ctmpa
->flags
|= (CF_NOSELECT
| CF_STARTITEM
);
219 snprintf(tmp
, sizeof(tmp
), "[ %s ]", this_sect
= new_sect
);
220 tmp
[sizeof(tmp
)-1] = '\0';
221 ctmpa
->value
= cpystr(tmp
);
224 new_confline(&ctmpa
)->var
= vtmp
;
225 ctmpa
->varnamep
= ctmpb
;
226 ctmpa
->keymenu
= &config_checkbox_keymenu
;
227 ctmpa
->help
= config_help(vtmp
-ps
->vars
,
229 ctmpa
->tool
= checkbox_tool
;
230 ctmpa
->valoffset
= feature_indent();
232 ctmpa
->value
= pretty_value(ps
, ctmpa
);
235 else if(standard_radio_var(ps
, vtmp
)){
236 standard_radio_setup(ps
, &ctmpa
, vtmp
, NULL
);
238 else if(vtmp
== &ps
->vars
[V_SORT_KEY
]){ /* radio case */
242 ctmpa
->flags
|= CF_NOSELECT
;
243 ctmpa
->keymenu
= &config_radiobutton_keymenu
;
246 /* put a nice delimiter before list */
247 new_confline(&ctmpa
)->var
= NULL
;
248 ctmpa
->varnamep
= ctmpb
;
249 ctmpa
->keymenu
= &config_radiobutton_keymenu
;
250 ctmpa
->help
= NO_HELP
;
251 ctmpa
->tool
= radiobutton_tool
;
252 ctmpa
->valoffset
= 12;
253 ctmpa
->flags
|= CF_NOSELECT
;
254 ctmpa
->value
= cpystr("Set Sort Options");
256 new_confline(&ctmpa
)->var
= NULL
;
257 ctmpa
->varnamep
= ctmpb
;
258 ctmpa
->keymenu
= &config_radiobutton_keymenu
;
259 ctmpa
->help
= NO_HELP
;
260 ctmpa
->tool
= radiobutton_tool
;
261 ctmpa
->valoffset
= 12;
262 ctmpa
->flags
|= CF_NOSELECT
;
263 ctmpa
->value
= cpystr("--- ----------------------");
265 decode_sort(pval
, &def_sort
, &def_sort_rev
);
267 for(j
= 0; j
< 2; j
++){
268 for(i
= 0; ps
->sort_types
[i
] != EndofList
; i
++){
269 new_confline(&ctmpa
)->var
= vtmp
;
270 ctmpa
->varnamep
= ctmpb
;
271 ctmpa
->keymenu
= &config_radiobutton_keymenu
;
272 ctmpa
->help
= config_help(vtmp
- ps
->vars
, 0);
273 ctmpa
->tool
= radiobutton_tool
;
274 ctmpa
->valoffset
= 12;
275 ctmpa
->varmem
= i
+ (j
* EndofList
);
276 ctmpa
->value
= pretty_value(ps
, ctmpa
);
280 else if(vtmp
== &ps
->vars
[V_USE_ONLY_DOMAIN_NAME
]){ /* yesno case */
281 ctmpa
->keymenu
= &config_yesno_keymenu
;
282 ctmpa
->tool
= yesno_tool
;
283 ctmpa
->value
= pretty_value(ps
, ctmpa
);
285 else if(vtmp
== &ps
->vars
[V_LITERAL_SIG
]){
286 ctmpa
->tool
= litsig_text_tool
;
287 ctmpa
->value
= pretty_value(ps
, ctmpa
);
289 else if(vtmp
== &ps
->vars
[V_INBOX_PATH
]){
290 ctmpa
->tool
= inbox_path_text_tool
;
291 ctmpa
->value
= pretty_value(ps
, ctmpa
);
293 else if(vtmp
== &ps
->vars
[V_POST_CHAR_SET
]
295 || vtmp
== &ps
->vars
[V_CHAR_SET
]
296 || vtmp
== &ps
->vars
[V_KEY_CHAR_SET
]
297 #endif /* !_WINDOWS */
298 || vtmp
== &ps
->vars
[V_UNK_CHAR_SET
]){
299 ctmpa
->keymenu
= &config_text_to_charsets_keymenu
;
300 ctmpa
->tool
= to_charsets_text_tool
;
301 ctmpa
->value
= pretty_value(ps
, ctmpa
);
303 else if(vtmp
->is_list
){
304 int (*t_tool
)(struct pine
*, int, CONF_S
**, unsigned);
309 if(vtmp
== &ps
->vars
[V_INCCHECKLIST
]){
310 t_tool
= incoming_monitoring_list_tool
;
311 km
= &config_text_keymenu
;
313 else if(vtmp
== &ps
->vars
[V_PERMLOCKED
]){
314 t_tool
= stayopen_list_tool
;
315 km
= &config_text_wshufandfldr_keymenu
;
319 for(i
= 0; lval
[i
]; i
++){
321 (void)new_confline(&ctmpa
);
325 ctmpa
->valoffset
= ln
+ 3;
326 ctmpa
->value
= pretty_value(ps
, ctmpa
);
327 ctmpa
->keymenu
= km
? km
: &config_text_wshuf_keymenu
;
328 ctmpa
->help
= config_help(vtmp
- ps
->vars
, 0);
329 ctmpa
->tool
= t_tool
? t_tool
: text_tool
;
330 ctmpa
->varnamep
= ctmpb
;
335 ctmpa
->value
= pretty_value(ps
, ctmpa
);
336 ctmpa
->tool
= t_tool
? t_tool
: text_tool
;
337 ctmpa
->keymenu
= km
? km
: &config_text_wshuf_keymenu
;
341 if(vtmp
== &ps
->vars
[V_FILLCOL
]
342 || vtmp
== &ps
->vars
[V_SLEEP
]
343 || vtmp
== &ps
->vars
[V_QUOTE_SUPPRESSION
]
344 || vtmp
== &ps
->vars
[V_OVERLAP
]
345 || vtmp
== &ps
->vars
[V_MAXREMSTREAM
]
346 || vtmp
== &ps
->vars
[V_MARGIN
]
347 || vtmp
== &ps
->vars
[V_DEADLETS
]
348 || vtmp
== &ps
->vars
[V_NMW_WIDTH
]
349 || vtmp
== &ps
->vars
[V_STATUS_MSG_DELAY
]
350 || vtmp
== &ps
->vars
[V_ACTIVE_MSG_INTERVAL
]
351 || vtmp
== &ps
->vars
[V_MAILCHECK
]
352 || vtmp
== &ps
->vars
[V_MAILCHECKNONCURR
]
353 || vtmp
== &ps
->vars
[V_MAILDROPCHECK
]
354 || vtmp
== &ps
->vars
[V_NNTPRANGE
]
355 || vtmp
== &ps
->vars
[V_TCPOPENTIMEO
]
356 || vtmp
== &ps
->vars
[V_TCPREADWARNTIMEO
]
357 || vtmp
== &ps
->vars
[V_TCPWRITEWARNTIMEO
]
358 || vtmp
== &ps
->vars
[V_TCPQUERYTIMEO
]
359 || vtmp
== &ps
->vars
[V_RSHOPENTIMEO
]
360 || vtmp
== &ps
->vars
[V_SSHOPENTIMEO
]
361 || vtmp
== &ps
->vars
[V_INCCHECKTIMEO
]
362 || vtmp
== &ps
->vars
[V_INCCHECKINTERVAL
]
363 || vtmp
== &ps
->vars
[V_INC2NDCHECKINTERVAL
]
364 || vtmp
== &ps
->vars
[V_USERINPUTTIMEO
]
365 || vtmp
== &ps
->vars
[V_REMOTE_ABOOK_VALIDITY
]
366 || vtmp
== &ps
->vars
[V_REMOTE_ABOOK_HISTORY
])
367 ctmpa
->flags
|= CF_NUMBER
;
369 ctmpa
->value
= pretty_value(ps
, ctmpa
);
373 dprint((9, "add hidden features\n"));
375 /* add the hidden features */
376 if(expose_hidden_config
){
379 new_confline(&ctmpa
); /* Blank line */
380 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
382 new_confline(&ctmpa
)->var
= NULL
;
383 ctmpa
->help
= NO_HELP
;
384 ctmpa
->valoffset
= 2;
385 ctmpa
->flags
|= CF_NOSELECT
;
386 ctmpa
->value
= cpystr("--- [ Normally hidden configuration features ] ---");
388 new_confline(&ctmpa
); /* Blank line */
389 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
391 vtmp
= &ps
->vars
[V_FEATURE_LIST
];
393 ctmpa
->flags
|= CF_NOSELECT
;
394 ctmpa
->keymenu
= &config_checkbox_keymenu
;
397 /* put a nice delimiter before list */
398 new_confline(&ctmpa
)->var
= NULL
;
399 ctmpa
->varnamep
= ctmpb
;
400 ctmpa
->keymenu
= &config_checkbox_keymenu
;
401 ctmpa
->help
= NO_HELP
;
402 ctmpa
->tool
= checkbox_tool
;
403 ctmpa
->valoffset
= feature_indent();
404 ctmpa
->flags
|= CF_NOSELECT
;
405 ctmpa
->value
= cpystr("Set Feature Name");
407 new_confline(&ctmpa
)->var
= NULL
;
408 ctmpa
->varnamep
= ctmpb
;
409 ctmpa
->keymenu
= &config_checkbox_keymenu
;
410 ctmpa
->help
= NO_HELP
;
411 ctmpa
->tool
= checkbox_tool
;
412 ctmpa
->valoffset
= feature_indent();
413 ctmpa
->flags
|= CF_NOSELECT
;
414 ctmpa
->value
= cpystr("--- ----------------------");
416 for(i
= 0; (feature
= feature_list(i
)); i
++)
417 if((new_sect
= feature_list_section(feature
)) &&
418 (strcmp(new_sect
, HIDDEN_PREF
) == 0)){
420 new_confline(&ctmpa
)->var
= vtmp
;
421 ctmpa
->varnamep
= ctmpb
;
422 ctmpa
->keymenu
= &config_checkbox_keymenu
;
423 ctmpa
->help
= config_help(vtmp
-ps
->vars
,
425 ctmpa
->tool
= checkbox_tool
;
426 ctmpa
->valoffset
= feature_indent();
428 ctmpa
->value
= pretty_value(ps
, ctmpa
);
432 vsave
= save_config_vars(ps
, expose_hidden_config
);
433 first_line
= pos
< 0 ? first_sel_confline(first_line
) : set_confline_number(first_line
, pos
);
435 memset(&screen
, 0, sizeof(screen
));
436 screen
.ro_warning
= readonly_warning
;
437 /* TRANSLATORS: Print something1 using something2.
438 "configuration" is something1 */
439 switch(conf_scroll_screen(ps
, &screen
, first_line
,
440 edit_exceptions
? CONFIG_SCREEN_TITLE_EXC
441 : CONFIG_SCREEN_TITLE
,
442 _("configuration"), 0, &pos
)){
447 write_pinerc(ps
, ew
, WRP_NONE
);
451 revert_to_saved_config(ps
, vsave
, expose_hidden_config
);
453 prc
->outstanding_pinerc_changes
= 0;
458 q_status_message(SM_ORDER
,7,10,
459 "conf_scroll_screen bad ret, not supposed to happen");
464 pval
= PVAL(&ps
->vars
[V_SORT_KEY
], ew
);
465 if(vsave
[V_SORT_KEY
].saved_user_val
.p
&& pval
466 && strcmp(vsave
[V_SORT_KEY
].saved_user_val
.p
, pval
)){
467 if(!mn_get_mansort(ps_global
->msgmap
)){
468 clear_index_cache(ps_global
->mail_stream
, 0);
469 reset_sort_order(SRT_VRB
);
473 treat_color_vars_as_text
= 0;
474 free_saved_config(ps
, &vsave
, expose_hidden_config
);
476 mswin_set_quit_confirm (F_OFF(F_QUIT_WO_CONFIRM
, ps_global
));
482 litsig_text_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
487 if(cmd
!= MC_EXIT
&& fixed_var((*cl
)->var
, NULL
, NULL
))
490 apval
= APVAL((*cl
)->var
, ew
);
496 char *input
= NULL
, *result
= NULL
, *err
= NULL
, *cstring_version
;
497 char *olddefval
= NULL
, *start_with
;
500 if(!*apval
&& (*cl
)->var
->current_val
.p
&&
501 (*cl
)->var
->current_val
.p
[0]){
502 if(!strncmp((*cl
)->var
->current_val
.p
,
504 (len
=strlen(DSTRING
)))){
505 /* strip DSTRING and trailing paren */
506 olddefval
= (char *)fs_get(strlen((*cl
)->var
->current_val
.p
)+1);
507 strncpy(olddefval
, (*cl
)->var
->current_val
.p
+len
,
508 strlen((*cl
)->var
->current_val
.p
)-len
-1);
509 olddefval
[strlen((*cl
)->var
->current_val
.p
)-len
-1] = '\0';
510 start_with
= olddefval
;
513 olddefval
= cpystr((*cl
)->var
->current_val
.p
);
514 start_with
= olddefval
;
518 start_with
= (*apval
) ? *apval
: "";
520 input
= (char *)fs_get((strlen(start_with
)+1) * sizeof(char));
522 cstring_to_string(start_with
, input
);
523 err
= signature_edit_lit(input
, &result
,
524 ((*cl
)->var
== role_comment_ptr
)
526 : "SIGNATURE EDITOR",
527 ((*cl
)->var
== role_comment_ptr
)
528 ? h_composer_commentedit
529 : h_composer_sigedit
);
532 if(olddefval
&& !strcmp(input
, result
) &&
533 want_to(_("Leave unset and use default "), 'y',
534 'y', NO_HELP
, WT_FLUSH_IN
) == 'y'){
538 cstring_version
= string_to_cstring(result
);
541 fs_give((void **)apval
);
544 *apval
= cstring_version
;
545 cstring_version
= NULL
;
549 fs_give((void **)&cstring_version
);
558 q_status_message1(SM_ORDER
, 3, 5, "%s", err
);
559 fs_give((void **)&err
);
563 fs_give((void **)&result
);
565 fs_give((void **)&olddefval
);
567 fs_give((void **)&input
);
570 ps
->mangled_screen
= 1;
574 rv
= text_tool(ps
, cmd
, cl
, flags
);
579 * At this point, if changes occurred, var->user_val.X is set.
580 * So, fix the current_val, and handle special cases...
582 * NOTE: we don't worry about the "fixed variable" case here, because
583 * editing such vars should have been prevented above...
587 * Now go and set the current_val based on user_val changes
588 * above. Turn off command line settings...
590 set_current_val((*cl
)->var
, TRUE
, FALSE
);
593 fs_give((void **)&(*cl
)->value
);
595 (*cl
)->value
= pretty_value(ps
, *cl
);
597 exception_override_warning((*cl
)->var
);
600 * The value of literal sig can affect whether signature file is
601 * used or not. So it affects what we display for sig file variable.
603 if((*cl
)->next
&& (*cl
)->next
->var
== &ps
->vars
[V_SIGNATURE_FILE
]){
604 if((*cl
)->next
->value
)
605 fs_give((void **)&(*cl
)->next
->value
);
607 (*cl
)->next
->value
= pretty_value(ps
, (*cl
)->next
);
616 inbox_path_text_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
620 char new_inbox_path
[2*MAXFOLDER
+1];
624 if(cmd
!= MC_EXIT
&& fixed_var((*cl
)->var
, NULL
, NULL
))
627 apval
= APVAL((*cl
)->var
, ew
);
632 cntxt
= ps
->context_list
;
633 if(cmd
== MC_EDIT
&& (*cl
)->var
){
634 if(ew
== Post
&& (*cl
)->var
->post_user_val
.p
)
635 def
= (*cl
)->var
->post_user_val
.p
;
636 else if(ew
== Main
&& (*cl
)->var
->main_user_val
.p
)
637 def
= (*cl
)->var
->main_user_val
.p
;
638 else if((*cl
)->var
->current_val
.p
)
639 def
= (*cl
)->var
->current_val
.p
;
642 rv
= add_new_folder(cntxt
, ew
, V_INBOX_PATH
, new_inbox_path
,
643 sizeof(new_inbox_path
), NULL
, def
);
646 ps
->mangled_screen
= 1;
650 rv
= text_tool(ps
, cmd
, cl
, flags
);
655 * This is just like the end of text_tool.
659 * Now go and set the current_val based on user_val changes
660 * above. Turn off command line settings...
662 set_current_val((*cl
)->var
, TRUE
, FALSE
);
663 fix_side_effects(ps
, (*cl
)->var
, 0);
666 fs_give((void **) &(*cl
)->value
);
668 (*cl
)->value
= pretty_value(ps
, *cl
);
670 exception_override_warning((*cl
)->var
);
678 incoming_monitoring_list_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
685 OPT_SCREEN_S
*saved_screen
;
687 if(cmd
!= MC_EXIT
&& fixed_var((*cl
)->var
, NULL
, NULL
))
693 cntxt
= ps
->context_list
;
694 if(!(cntxt
&& cntxt
->use
& CNTXT_INCMNG
)){
695 q_status_message1(SM_ORDER
, 3, 3, _("Turn on incoming folders with Config feature \"%s\""), pretty_feature_name(feature_list_name(F_ENABLE_INCOMING
), -1));
699 saved_screen
= opt_screen
;
701 the_list
= adjust_list_of_monitored_incoming(cntxt
, ew
, V_INCCHECKLIST
);
703 /* adjust top if it might be necessary */
704 for(ctmp
= (*cl
)->varnamep
;
705 ctmp
&& ctmp
->varnamep
== (*cl
)->varnamep
;
706 ctmp
= next_confline(ctmp
))
707 if(ctmp
== opt_screen
->top_line
)
708 opt_screen
->top_line
= (*cl
)->varnamep
;
711 alval
= ALVAL((*cl
)->var
, ew
);
712 free_list_array(alval
);
714 q_status_message(SM_ORDER
, 0, 3, _("Using default, monitor all incoming folders"));
717 * Remove config lines except for first one.
719 *cl
= (*cl
)->varnamep
;
720 while((*cl
)->next
&& (*cl
)->next
->varnamep
== (*cl
)->varnamep
)
721 snip_confline(&(*cl
)->next
);
725 config_add_list(ps
, cl
, the_list
, NULL
, 0);
727 /* only have to free the top-level pointer */
728 fs_give((void **) &the_list
);
732 if(LVAL((*cl
)->var
, ew
))
733 q_status_message(SM_ORDER
, 0, 3, _("List is unchanged"));
735 q_status_message(SM_ORDER
, 0, 3, _("Using default, monitor all incoming folders"));
738 opt_screen
= saved_screen
;
739 ps
->mangled_screen
= 1;
743 rv
= text_tool(ps
, cmd
, cl
, flags
);
744 /* if we deleted last one, reverts to default */
745 if(cmd
== MC_DELETE
&& rv
== 1 && (*cl
)->varmem
== 0
746 && (!(*cl
)->next
|| (*cl
)->next
->varnamep
!= (*cl
)))
747 q_status_message(SM_ORDER
, 0, 3, _("Using default, monitor all incoming folders"));
753 * This is just like the end of text_tool.
757 * Now go and set the current_val based on user_val changes
758 * above. Turn off command line settings...
760 set_current_val((*cl
)->var
, TRUE
, FALSE
);
761 fix_side_effects(ps
, (*cl
)->var
, 0);
764 fs_give((void **) &(*cl
)->value
);
766 (*cl
)->value
= pretty_value(ps
, *cl
);
768 exception_override_warning((*cl
)->var
);
776 adjust_list_of_monitored_incoming(CONTEXT_S
*cntxt
, EditWhich which
, int varnum
)
778 LIST_SEL_S
*listhead
, *p
, *ls
;
782 char **the_list
= NULL
, buf
[1000];
784 if(!(cntxt
&& cntxt
->use
& CNTXT_INCMNG
))
789 /* this width is determined by select_from_list_screen() */
790 width
= ps_global
->ttyo
->screen_cols
- 4;
793 * Put together a list of folders to select from.
794 * We could choose to use the list associated with
795 * the config we're editing, and that may be correct.
796 * However, we think most users will expect the list
797 * to be the list that is in use. In any case, these
798 * are almost always the same.
801 ftotal
= folder_total(FOLDERS(cntxt
));
803 for(i
= 0; i
< ftotal
; i
++){
805 f
= folder_entry(i
, FOLDERS(cntxt
));
807 ls
= (LIST_SEL_S
*) fs_get(sizeof(*ls
));
808 memset(ls
, 0, sizeof(*ls
));
810 if(f
&& f
->nickname
){
811 ls
->item
= cpystr(f
->nickname
);
812 snprintf(buf
, sizeof(buf
), "%s (%s)", f
->nickname
, f
->name
? f
->name
: "?");
813 ls
->display_item
= cpystr(buf
);
816 ls
->item
= cpystr((f
&& f
->name
) ? f
->name
: "?");
818 if(f
&& f
->last_unseen_update
!= LUU_NEVERCHK
)
827 listhead
= (LIST_SEL_S
*) fs_get(sizeof(*ls
));
828 memset(listhead
, 0, sizeof(*listhead
));
829 listhead
->flags
= SFL_NOSELECT
;
830 listhead
->display_item
= cpystr(_("Incoming folders to be monitored"));
831 listhead
->next
= (LIST_SEL_S
*) fs_get(sizeof(*ls
));
832 memset(listhead
->next
, 0, sizeof(*listhead
));
833 listhead
->next
->flags
= SFL_NOSELECT
;
834 listhead
->next
->display_item
= cpystr(repeat_char(width
, '-'));
836 listhead
->next
->next
= ls
;
842 q_status_message1(SM_ORDER
, 3, 3, _("Turn on incoming folders with Config feature \"%s\""), pretty_feature_name(feature_list_name(F_ENABLE_INCOMING
), -1));
846 if(!select_from_list_screen(listhead
,
847 SFL_ALLOW_LISTMODE
|SFL_STARTIN_LISTMODE
|SFL_ONLY_LISTMODE
|SFL_CTRLC
,
848 _("SELECT FOLDERS TO MONITOR"), _("folders"),
849 h_select_incoming_to_monitor
,
850 _("HELP FOR SELECTING FOLDERS"), NULL
)){
852 for(cnt
= 0, p
= listhead
; p
; p
= p
->next
)
856 if(cnt
>= 0 && cnt
<= ftotal
){
857 the_list
= (char **) fs_get((cnt
+1) * sizeof(*the_list
));
858 memset(the_list
, 0, (cnt
+1) * sizeof(*the_list
));
859 for(i
= 0, p
= listhead
; p
; p
= p
->next
)
861 the_list
[i
++] = cpystr(p
->item
? p
->item
: "");
865 free_list_sel(&listhead
);
872 stayopen_list_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
875 char **newval
= NULL
;
878 void (*prev_screen
)(struct pine
*) = ps
->prev_screen
,
879 (*redraw
)(void) = ps
->redrawer
;
880 OPT_SCREEN_S
*saved_screen
= NULL
;
884 if(fixed_var((*cl
)->var
, NULL
, NULL
))
888 ps
->next_screen
= SCREEN_FUN_NULL
;
889 saved_screen
= opt_screen
;
890 folder
= folder_for_config(FOR_OPTIONSCREEN
);
891 removing_leading_and_trailing_white_space(folder
);
892 if(folder
&& *folder
){
893 ltmp
= (char **) fs_get(2 * sizeof(char *));
894 ltmp
[0] = cpystr(folder
);
897 config_add_list(ps
, cl
, ltmp
, &newval
, 0);
900 fs_give((void **) <mp
);
904 /* this stuff is from bottom of text_toolit() */
907 * At this point, if changes occurred, var->user_val.X is set.
908 * So, fix the current_val, and handle special cases...
910 * NOTE: we don't worry about the "fixed variable" case here, because
911 * editing such vars should have been prevented above...
915 * Now go and set the current_val based on user_val changes
916 * above. Turn off command line settings...
918 set_current_val((*cl
)->var
, TRUE
, FALSE
);
919 fix_side_effects(ps
, (*cl
)->var
, 0);
922 * Delay setting the displayed value until "var.current_val" is set
923 * in case current val get's changed due to a special case above.
927 fs_give((void **) newval
);
929 *newval
= pretty_value(ps
, *cl
);
932 exception_override_warning((*cl
)->var
);
935 fs_give((void **) &folder
);
938 ps
->next_screen
= prev_screen
;
939 ps
->redrawer
= redraw
;
943 opt_screen
= saved_screen
;
944 ps
->mangled_screen
= 1;
948 rv
= text_tool(ps
, cmd
, cl
, flags
);
957 to_charsets_text_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
960 char **newval
= NULL
;
961 void (*prev_screen
)(struct pine
*) = ps
->prev_screen
,
962 (*redraw
)(void) = ps
->redrawer
;
963 OPT_SCREEN_S
*saved_screen
= NULL
;
965 char *charset
= NULL
;
969 if(fixed_var((*cl
)->var
, NULL
, NULL
))
972 apval
= APVAL((*cl
)->var
, ew
);
975 int cac_flags
= CAC_ALL
;
978 ps
->next_screen
= SCREEN_FUN_NULL
;
979 saved_screen
= opt_screen
;
981 if((*cl
)->var
== &ps
->vars
[V_POST_CHAR_SET
])
982 cac_flags
= CAC_POSTING
;
984 else if((*cl
)->var
== &ps
->vars
[V_CHAR_SET
]
985 || (*cl
)->var
== &ps
->vars
[V_KEY_CHAR_SET
])
986 cac_flags
= CAC_DISPLAY
;
987 #endif /* !_WINDOWS */
989 charset
= choose_a_charset(cac_flags
);
991 removing_leading_and_trailing_white_space(charset
);
992 if(charset
&& *charset
){
995 fs_give((void **) apval
);
999 newval
= &(*cl
)->value
;
1001 /* this stuff is from bottom of text_toolit() */
1004 * At this point, if changes occurred, var->user_val.X is set.
1005 * So, fix the current_val, and handle special cases...
1007 * NOTE: we don't worry about the "fixed variable" case here, because
1008 * editing such vars should have been prevented above...
1012 * Now go and set the current_val based on user_val changes
1013 * above. Turn off command line settings...
1015 set_current_val((*cl
)->var
, TRUE
, FALSE
);
1016 fix_side_effects(ps
, (*cl
)->var
, 0);
1019 fs_give((void **) newval
);
1021 *newval
= pretty_value(ps
, *cl
);
1024 exception_override_warning((*cl
)->var
);
1027 ps
->next_screen
= prev_screen
;
1028 ps
->redrawer
= redraw
;
1033 fs_give((void **) &charset
);
1035 opt_screen
= saved_screen
;
1036 ps
->mangled_screen
= 1;
1041 rv
= text_tool(ps
, cmd
, cl
, flags
);
1050 * pretty_var_name - return a pleasantly displayable form
1051 * of variable name variable
1054 pretty_var_name(char *varname
)
1058 static char vbuf
[100];
1061 v
= var_from_name(varname
);
1066 if(v
->dname
&& v
->dname
[0])
1069 if(!(v
->name
&& v
->name
[0]))
1072 /* default: uppercase first letters, dashes to spaces */
1073 for(i
= 0; i
< sizeof(vbuf
)-1 && v
->name
[i
]; i
++)
1075 vbuf
[i
] = (islower((unsigned char) v
->name
[i
]))
1076 ? toupper((unsigned char) v
->name
[i
])
1080 else if(v
->name
[i
] == '-'){
1085 vbuf
[i
] = v
->name
[i
];
1093 * pretty_feature_name - return a pleasantly displayable form
1094 * of feature name variable
1097 pretty_feature_name(char *feat
, int width
)
1101 static char fbuf
[100];
1103 f
= feature_list(feature_list_index(feature_list_id(feat
)));
1104 if(f
&& f
->dname
&& f
->dname
[0])
1107 /* default: uppercase first letters, dashes become spaces */
1108 for(i
= 0; i
< sizeof(fbuf
)-1 && feat
[i
]; i
++)
1110 fbuf
[i
] = (islower((unsigned char) feat
[i
]))
1111 ? toupper((unsigned char) feat
[i
])
1115 else if(feat
[i
] == '-'){
1124 /* cut off right hand edge if necessary */
1128 p
= short_str(fbuf
, gbuf
, sizeof(gbuf
), width
, EndDots
);
1131 strncpy(fbuf
, p
, sizeof(fbuf
)-1);
1132 fbuf
[sizeof(fbuf
)-1] = '\0';