* Rewrite support for specific SSL encryption protocols, including
[alpine.git] / alpine / colorconf.c
blobf790c768271e498ed9aeee8b1d77edd9bb3f1862
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: colorconf.c 934 2008-02-23 00:44:29Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2013-2018 Eduardo Chappa
8 * Copyright 2006-2008 University of Washington
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 * ========================================================================
20 #include "headers.h"
21 #include "colorconf.h"
22 #include "keymenu.h"
23 #include "status.h"
24 #include "confscroll.h"
25 #include "radio.h"
26 #include "mailview.h"
27 #include "../pith/state.h"
28 #include "../pith/util.h"
29 #include "../pith/color.h"
30 #include "../pith/icache.h"
31 #include "../pith/mailcmd.h"
32 #include "../pith/mailindx.h"
33 #include "../pith/list.h"
37 * Internal prototypes
39 char *colorindexrule(char *);
40 char *color_setting_text_line(struct pine *, struct variable *);
41 void revert_to_saved_color_config(struct pine *, SAVED_CONFIG_S *);
42 SAVED_CONFIG_S *save_color_config_vars(struct pine *);
43 void free_saved_color_config(struct pine *, SAVED_CONFIG_S **);
44 void color_config_init_display(struct pine *, CONF_S **, CONF_S **);
45 void add_header_color_line(struct pine *, CONF_S **, char *, int, int);
46 int is_rgb_color(char *);
47 char *new_color_line(char *, int, int, int);
48 int color_text_tool(struct pine *, int, CONF_S **, unsigned);
49 int offer_normal_color_for_var(struct pine *, struct variable *);
50 int offer_none_color_for_var(struct pine *, struct variable *);
51 void color_update_selected(struct pine *, CONF_S *, char *, char *, int);
52 int color_edit_screen(struct pine *, CONF_S **);
55 int treat_color_vars_as_text;
58 void
59 color_config_screen(struct pine *ps, int edit_exceptions)
61 CONF_S *ctmp = NULL, *first_line = NULL;
62 SAVED_CONFIG_S *vsave;
63 OPT_SCREEN_S screen;
64 int readonly_warning = 0;
66 ps->next_screen = SCREEN_FUN_NULL;
68 mailcap_free(); /* free resources we won't be using for a while */
70 if(ps->fix_fixed_warning)
71 offer_to_fix_pinerc(ps);
73 ew = edit_exceptions ? ps_global->ew_for_except_vars : Main;
75 if(ps->restricted)
76 readonly_warning = 1;
77 else{
78 PINERC_S *prc = NULL;
80 switch(ew){
81 case Main:
82 prc = ps->prc;
83 break;
84 case Post:
85 prc = ps->post_prc;
86 break;
87 default:
88 break;
91 readonly_warning = prc ? prc->readonly : 1;
92 if(prc && prc->quit_to_edit){
93 quit_to_edit_msg(prc);
94 return;
98 color_config_init_display(ps, &ctmp, &first_line);
100 vsave = save_color_config_vars(ps);
102 memset(&screen, 0, sizeof(screen));
103 screen.deferred_ro_warning = readonly_warning;
104 switch(conf_scroll_screen(ps, &screen, first_line,
105 edit_exceptions ? _("SETUP COLOR EXCEPTIONS")
106 : _("SETUP COLOR"),
107 /* TRANSLATORS: Print something1 using something2.
108 configuration is something1 */
109 _("configuration"), 0, NULL)){
110 case 0:
111 break;
113 case 1:
114 write_pinerc(ps, ew, WRP_NONE);
115 break;
117 case 10:
118 revert_to_saved_color_config(ps, vsave);
119 break;
121 default:
122 q_status_message(SM_ORDER, 7, 10,
123 _("conf_scroll_screen bad ret in color_config"));
124 break;
127 free_saved_color_config(ps, &vsave);
129 #ifdef _WINDOWS
130 mswin_set_quit_confirm (F_OFF(F_QUIT_WO_CONFIRM, ps_global));
131 #endif
135 char *
136 sample_text(struct pine *ps, struct variable *v)
138 char *ret = SAMP2;
139 char *pvalfg, *pvalbg;
141 pvalfg = PVAL(v, ew);
142 pvalbg = PVAL(v+1, ew);
144 if((v && v->name &&
145 srchstr(v->name, "-foreground-color") &&
146 pvalfg && pvalfg[0] && pvalbg && pvalbg[0]) ||
147 (v == &ps->vars[V_INDEX_TOKEN_COLORS] ||
148 v == &ps->vars[V_VIEW_HDR_COLORS] || v == &ps->vars[V_KW_COLORS]))
149 ret = SAMP1;
151 return(ret);
155 char *
156 sampleexc_text(struct pine *ps, struct variable *v)
158 char *ret = "";
159 char *pvalfg, *pvalbg;
161 pvalfg = PVAL(v, Post);
162 pvalbg = PVAL(v+1, Post);
163 if(v && color_holding_var(ps, v) &&
164 srchstr(v->name, "-foreground-color")){
165 if(ew == Main && pvalfg && pvalfg[0] && pvalbg && pvalbg[0])
166 ret = SAMPEXC;
169 return(ret);
173 char *
174 color_setting_text_line(struct pine *ps, struct variable *v)
176 char *p;
177 char tmp[1200];
179 p = sampleexc_text(ps, v);
182 * Don't need to use utf8_snprintf if we're not trying to
183 * control the widths of fields.
185 snprintf(tmp, sizeof(tmp), "%s %s%*s%s%s", SAMPLE_LEADER,
186 sample_text(ps,v), *p ? SBS : 0, "", p,
187 color_parenthetical(v));
188 return(cpystr(tmp));
193 * Compare saved user_val with current user_val to see if it changed.
194 * If any have changed, change it back and take the appropriate action.
196 void
197 revert_to_saved_color_config(struct pine *ps, SAVED_CONFIG_S *vsave)
199 struct variable *vreal;
200 SAVED_CONFIG_S *v;
201 int i, n;
202 int changed = 0;
203 char *pval, **apval, **lval, ***alval;
205 v = vsave;
206 for(vreal = ps->vars; vreal->name; vreal++,v++){
207 if(!(color_related_var(ps, vreal) || vreal==&ps->vars[V_FEATURE_LIST]))
208 continue;
210 if(vreal->is_list){
211 lval = LVAL(vreal, ew);
212 alval = ALVAL(vreal, ew);
214 if((v->saved_user_val.l && !lval)
215 || (!v->saved_user_val.l && lval))
216 changed++;
217 else if(!v->saved_user_val.l && !lval)
218 ;/* no change, nothing to do */
219 else
220 for(i = 0; v->saved_user_val.l[i] || lval[i]; i++)
221 if((v->saved_user_val.l[i]
222 && (!lval[i]
223 || strcmp(v->saved_user_val.l[i], lval[i])))
225 (!v->saved_user_val.l[i] && lval[i])){
226 changed++;
227 break;
230 if(changed){
231 char **list;
233 if(alval){
234 if(*alval)
235 free_list_array(alval);
237 /* copy back the original one */
238 if(v->saved_user_val.l){
239 list = v->saved_user_val.l;
240 n = 0;
241 /* count how many */
242 while(list[n])
243 n++;
245 *alval = (char **)fs_get((n+1) * sizeof(char *));
247 for(i = 0; i < n; i++)
248 (*alval)[i] = cpystr(v->saved_user_val.l[i]);
250 (*alval)[n] = NULL;
255 else{
256 pval = PVAL(vreal, ew);
257 apval = APVAL(vreal, ew);
259 if((v->saved_user_val.p &&
260 (!pval || strcmp(v->saved_user_val.p, pval))) ||
261 (!v->saved_user_val.p && pval)){
262 /* It changed, fix it */
263 changed++;
264 if(apval){
265 /* free the changed value */
266 if(*apval)
267 fs_give((void **)apval);
269 if(v->saved_user_val.p)
270 *apval = cpystr(v->saved_user_val.p);
275 if(changed){
276 if(vreal == &ps->vars[V_FEATURE_LIST])
277 set_feature_list_current_val(vreal);
278 else
279 set_current_val(vreal, TRUE, FALSE);
281 fix_side_effects(ps, vreal, 1);
285 if(changed){
286 set_current_color_vals(ps);
287 ClearScreen();
288 ps->mangled_screen = 1;
293 SAVED_CONFIG_S *
294 save_color_config_vars(struct pine *ps)
296 struct variable *vreal;
297 SAVED_CONFIG_S *vsave, *v;
299 vsave = (SAVED_CONFIG_S *)fs_get((V_LAST_VAR+1)*sizeof(SAVED_CONFIG_S));
300 memset((void *)vsave, 0, (V_LAST_VAR+1)*sizeof(SAVED_CONFIG_S));
301 v = vsave;
302 for(vreal = ps->vars; vreal->name; vreal++,v++){
303 if(!(color_related_var(ps, vreal) || vreal==&ps->vars[V_FEATURE_LIST]))
304 continue;
306 if(vreal->is_list){
307 int n, i;
308 char **list;
310 if(LVAL(vreal, ew)){
311 /* count how many */
312 n = 0;
313 list = LVAL(vreal, ew);
314 while(list[n])
315 n++;
317 v->saved_user_val.l = (char **)fs_get((n+1) * sizeof(char *));
318 memset((void *)v->saved_user_val.l, 0, (n+1)*sizeof(char *));
319 for(i = 0; i < n; i++)
320 v->saved_user_val.l[i] = cpystr(list[i]);
322 v->saved_user_val.l[n] = NULL;
325 else{
326 if(PVAL(vreal, ew))
327 v->saved_user_val.p = cpystr(PVAL(vreal, ew));
331 return(vsave);
335 void
336 free_saved_color_config(struct pine *ps, SAVED_CONFIG_S **vsavep)
338 struct variable *vreal;
339 SAVED_CONFIG_S *v;
341 if(vsavep && *vsavep){
342 for(v = *vsavep, vreal = ps->vars; vreal->name; vreal++,v++){
343 if(!(color_related_var(ps, vreal) ||
344 (vreal == &ps->vars[V_FEATURE_LIST])))
345 continue;
347 if(vreal->is_list){ /* free saved_user_val.l */
348 if(v && v->saved_user_val.l)
349 free_list_array(&v->saved_user_val.l);
351 else if(v && v->saved_user_val.p)
352 fs_give((void **)&v->saved_user_val.p);
355 fs_give((void **)vsavep);
360 void
361 color_config_init_display(struct pine *ps, CONF_S **ctmp, CONF_S **first_line)
363 char **lval;
364 int i, saw_first_index = 0;
365 struct variable *vtmp;
366 char *dashes = "--------------";
368 #ifndef _WINDOWS
369 vtmp = &ps->vars[V_COLOR_STYLE];
371 new_confline(ctmp);
372 (*ctmp)->flags |= (CF_NOSELECT | CF_STARTITEM);
373 (*ctmp)->keymenu = &config_radiobutton_keymenu;
374 (*ctmp)->tool = NULL;
375 (*ctmp)->varname = cpystr("Color Style");
376 (*ctmp)->varnamep = *ctmp;
378 standard_radio_setup(ps, ctmp, vtmp, first_line);
380 new_confline(ctmp);
381 /* Blank line */
382 (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
384 if(!pico_usingcolor()){
385 /* add a line explaining that color is not turned on */
386 new_confline(ctmp);
387 (*ctmp)->help = NO_HELP;
388 (*ctmp)->flags |= CF_NOSELECT;
389 (*ctmp)->value = cpystr(COLORNOSET);
391 new_confline(ctmp);
392 /* Blank line */
393 (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
396 #endif
398 vtmp = &ps->vars[V_INDEX_COLOR_STYLE];
400 new_confline(ctmp);
401 (*ctmp)->flags |= (CF_NOSELECT | CF_STARTITEM);
402 (*ctmp)->keymenu = &config_radiobutton_keymenu;
403 (*ctmp)->tool = NULL;
404 (*ctmp)->varname = cpystr(_("Current Indexline Style"));
405 (*ctmp)->varnamep = *ctmp;
407 standard_radio_setup(ps, ctmp, vtmp, NULL);
409 new_confline(ctmp);
410 /* Blank line */
411 (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
413 vtmp = &ps->vars[V_TITLEBAR_COLOR_STYLE];
415 new_confline(ctmp);
416 (*ctmp)->flags |= (CF_NOSELECT | CF_STARTITEM);
417 (*ctmp)->keymenu = &config_radiobutton_keymenu;
418 (*ctmp)->tool = NULL;
419 (*ctmp)->varname = cpystr(_("Titlebar Color Style"));
420 (*ctmp)->varnamep = *ctmp;
422 standard_radio_setup(ps, ctmp, vtmp, NULL);
424 new_confline(ctmp);
425 /* Blank line */
426 (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
428 new_confline(ctmp);
429 /* title before general colors */
430 (*ctmp)->help = NO_HELP;
431 (*ctmp)->flags |= CF_NOSELECT;
432 (*ctmp)->value = cpystr(dashes);
433 new_confline(ctmp);
434 (*ctmp)->help = NO_HELP;
435 (*ctmp)->flags |= CF_NOSELECT;
436 (*ctmp)->value = cpystr(_("GENERAL COLORS"));
437 new_confline(ctmp);
438 (*ctmp)->help = NO_HELP;
439 (*ctmp)->flags |= CF_NOSELECT;
440 (*ctmp)->value = cpystr(dashes);
442 for(vtmp = ps->vars; vtmp->name; vtmp++){
443 if(!color_holding_var(ps, vtmp))
444 continue;
446 /* If not foreground, skip it */
447 if(!srchstr(vtmp->name, "-foreground-color"))
448 continue;
450 /* skip this for now and include it with HEADER COLORS */
451 if(vtmp == &ps->vars[V_HEADER_GENERAL_FORE_COLOR])
452 continue;
454 if(!saw_first_index && !struncmp(vtmp->name, "index-", 6)){
455 saw_first_index++;
456 new_confline(ctmp); /* Blank line */
457 (*ctmp)->flags |= (CF_NOSELECT | CF_B_LINE);
458 new_confline(ctmp);
459 (*ctmp)->help = NO_HELP;
460 (*ctmp)->flags |= CF_NOSELECT;
461 (*ctmp)->value = cpystr(dashes);
462 new_confline(ctmp);
463 (*ctmp)->help = NO_HELP;
464 (*ctmp)->flags |= CF_NOSELECT;
465 (*ctmp)->value = cpystr(_("INDEX COLORS"));
466 new_confline(ctmp);
467 (*ctmp)->help = NO_HELP;
468 (*ctmp)->flags |= CF_NOSELECT;
469 (*ctmp)->value = cpystr(dashes);
472 new_confline(ctmp);
473 /* Blank line */
474 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
476 new_confline(ctmp)->var = vtmp;
477 if(first_line && !*first_line)
478 *first_line = *ctmp;
480 (*ctmp)->varnamep = *ctmp;
481 (*ctmp)->keymenu = &color_setting_keymenu;
482 (*ctmp)->help = config_help(vtmp - ps->vars, 0);
483 (*ctmp)->tool = color_setting_tool;
484 (*ctmp)->flags |= (CF_STARTITEM | CF_COLORSAMPLE | CF_POT_SLCTBL);
485 if(!pico_usingcolor())
486 (*ctmp)->flags |= CF_NOSELECT;
488 (*ctmp)->value = pretty_value(ps, *ctmp);
489 (*ctmp)->valoffset = COLOR_INDENT;
493 * custom index tokens colors
495 vtmp = &ps->vars[V_INDEX_TOKEN_COLORS];
496 lval = LVAL(vtmp, ew);
498 if(lval && lval[0] && lval[0][0]){
499 for(i = 0; lval && lval[i]; i++)
500 add_header_color_line(ps, ctmp, lval[i], i, V_INDEX_TOKEN_COLORS);
502 else{
503 new_confline(ctmp); /* Blank line */
504 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
505 new_confline(ctmp);
506 (*ctmp)->help = NO_HELP;
507 (*ctmp)->flags |= CF_NOSELECT;
508 (*ctmp)->value = cpystr(_(ADDINDEXTOKEN_COMMENT));
509 (*ctmp)->valoffset = COLOR_INDENT;
513 * custom header colors
515 new_confline(ctmp); /* Blank line */
516 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
517 new_confline(ctmp);
518 (*ctmp)->help = NO_HELP;
519 (*ctmp)->flags |= CF_NOSELECT;
520 (*ctmp)->value = cpystr(dashes);
521 new_confline(ctmp);
522 (*ctmp)->help = NO_HELP;
523 (*ctmp)->flags |= CF_NOSELECT;
524 (*ctmp)->value = cpystr(_(HDR_COLORS));
525 new_confline(ctmp);
526 (*ctmp)->help = NO_HELP;
527 (*ctmp)->flags |= CF_NOSELECT;
528 (*ctmp)->value = cpystr(dashes);
530 vtmp = &ps->vars[V_HEADER_GENERAL_FORE_COLOR];
531 new_confline(ctmp);
532 /* Blank line */
533 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
535 new_confline(ctmp)->var = vtmp;
537 (*ctmp)->varnamep = *ctmp;
538 (*ctmp)->keymenu = &color_setting_keymenu;
539 (*ctmp)->help = config_help(vtmp - ps->vars, 0);
540 (*ctmp)->tool = color_setting_tool;
541 (*ctmp)->flags |= (CF_STARTITEM | CF_COLORSAMPLE | CF_POT_SLCTBL);
542 if(!pico_usingcolor())
543 (*ctmp)->flags |= CF_NOSELECT;
545 (*ctmp)->value = pretty_value(ps, *ctmp);
546 (*ctmp)->valoffset = COLOR_INDENT;
548 vtmp = &ps->vars[V_VIEW_HDR_COLORS];
549 lval = LVAL(vtmp, ew);
551 if(lval && lval[0] && lval[0][0]){
552 for(i = 0; lval && lval[i]; i++)
553 add_header_color_line(ps, ctmp, lval[i], i, V_VIEW_HDR_COLORS);
555 else{
556 new_confline(ctmp); /* Blank line */
557 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
558 new_confline(ctmp);
559 (*ctmp)->help = NO_HELP;
560 (*ctmp)->flags |= CF_NOSELECT;
561 (*ctmp)->value = cpystr(_(ADDHEADER_COMMENT));
562 (*ctmp)->valoffset = COLOR_INDENT;
567 * custom keyword colors
569 new_confline(ctmp); /* Blank line */
570 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
571 new_confline(ctmp);
572 (*ctmp)->help = NO_HELP;
573 (*ctmp)->flags |= CF_NOSELECT;
574 (*ctmp)->value = cpystr(dashes);
575 new_confline(ctmp);
576 (*ctmp)->help = NO_HELP;
577 (*ctmp)->flags |= CF_NOSELECT;
578 (*ctmp)->value = cpystr(KW_COLORS_HDR);
579 new_confline(ctmp);
580 (*ctmp)->help = NO_HELP;
581 (*ctmp)->flags |= CF_NOSELECT;
582 (*ctmp)->value = cpystr(dashes);
585 if(ps->keywords){
586 KEYWORD_S *kw;
587 char *name, *comment, *word;
588 int j, lv = 0, lc = 0, ltot = 0, eq_col = EQ_COL;
590 vtmp = &ps->vars[V_KW_COLORS];
592 /* first figure out widths for display */
593 for(kw = ps->keywords; kw; kw = kw->next){
594 word = kw->nick ? kw->nick : kw->kw ? kw->kw : "";
595 i = utf8_width(word);
596 if(lv < i)
597 lv = i;
599 j = 0;
600 if(kw->nick && kw->kw && kw->kw[0]){
601 word = kw->kw;
602 j = utf8_width(word) + 2;
603 if(lc < j)
604 lc = j;
607 if(ltot < (i + (j > 2 ? j : 0)))
608 ltot = (i + (j > 2 ? j : 0));
611 lv = MIN(lv, 100);
612 lc = MIN(lc, 100);
613 ltot = MIN(ltot, 100);
616 * SC is width of " Color"
617 * SS is space between nickname and keyword value
618 * SW is space between words and Sample
620 #define SC 6
621 #define SS 1
622 #define SW 3
623 if(COLOR_INDENT + SC + ltot + (lc>0?SS:0) > eq_col - SW){
624 eq_col = MIN(MAX(ps->ttyo->screen_cols - 10, 20),
625 COLOR_INDENT + SC + ltot + (lc>0?SS:0) + SW);
626 if(COLOR_INDENT + SC + ltot + (lc>0?SS:0) > eq_col - SW){
627 eq_col = MIN(MAX(ps->ttyo->screen_cols - 10, 20),
628 COLOR_INDENT + SC + lv + (lc>0?SS:0) + lc + SW);
629 if(COLOR_INDENT + SC + lv + (lc>0?SS:0) + lc > eq_col - SW){
630 lc = MIN(lc, MAX(eq_col - SW - COLOR_INDENT - SC - lv - SS, 7));
631 if(COLOR_INDENT + SC + lv + (lc>0?SS:0) + lc > eq_col - SW){
632 lc = 0;
633 if(COLOR_INDENT + SC + lv > eq_col - SW){
634 lv = MAX(eq_col - SW - COLOR_INDENT - SC, 7);
641 lval = LVAL(vtmp, ew);
642 if(lval && lval[0] && !strcmp(lval[0], INHERIT)){
643 new_confline(ctmp);
644 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
646 new_confline(ctmp)->var = vtmp;
647 (*ctmp)->varnamep = *ctmp;
648 (*ctmp)->keymenu = &kw_color_setting_keymenu;
649 (*ctmp)->help = config_help(vtmp - ps->vars, 0);
650 (*ctmp)->tool = color_setting_tool;
651 (*ctmp)->varmem = CFC_SET_COLOR(i, 0);
652 (*ctmp)->valoffset = COLOR_INDENT;
654 (*ctmp)->flags = (CF_NOSELECT | CF_INHERIT);
657 /* now create the config lines */
658 for(kw = ps->keywords, i = 0; kw; kw = kw->next, i++){
659 char tmp[2000];
661 /* Blank line */
662 new_confline(ctmp);
663 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
665 new_confline(ctmp)->var = vtmp;
666 (*ctmp)->varnamep = *ctmp;
667 (*ctmp)->keymenu = &kw_color_setting_keymenu;
668 (*ctmp)->help = config_help(vtmp - ps->vars, 0);
669 (*ctmp)->tool = color_setting_tool;
670 (*ctmp)->flags |= (CF_STARTITEM | CF_COLORSAMPLE | CF_POT_SLCTBL);
671 if(!pico_usingcolor())
672 (*ctmp)->flags |= CF_NOSELECT;
675 * Not actually a color in this case, it is an index into
676 * the keywords list.
678 (*ctmp)->varmem = CFC_SET_COLOR(i, 0);
680 name = short_str(kw->nick ? kw->nick : kw->kw ? kw->kw : "",
681 tmp_20k_buf+10000, 1000, lv, EndDots);
682 if(lc > 0 && kw->nick && kw->kw && kw->kw[0])
683 comment = short_str(kw->kw, tmp_20k_buf+11000, SIZEOF_20KBUF - 11000, lc, EndDots);
684 else
685 comment = NULL;
687 utf8_snprintf(tmp, sizeof(tmp), "%.*w%*s%s%.*w%s Color%*s %s%s",
688 lv, name,
689 (lc > 0 && comment) ? SS : 0, "",
690 (lc > 0 && comment) ? "(" : "",
691 (lc > 0 && comment) ? lc : 0, (lc > 0 && comment) ? comment : "",
692 (lc > 0 && comment) ? ")" : "",
693 MAX(MIN(eq_col - COLOR_INDENT - MIN(lv,utf8_width(name))
694 - SC - 1
695 - ((lc > 0 && comment)
696 ? (SS+2+MIN(lc,utf8_width(comment))) : 0), 100), 0), "",
697 sample_text(ps,vtmp),
698 color_parenthetical(vtmp));
700 (*ctmp)->value = cpystr(tmp);
701 (*ctmp)->valoffset = COLOR_INDENT;
704 else{
705 new_confline(ctmp); /* Blank line */
706 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
707 new_confline(ctmp);
708 (*ctmp)->help = NO_HELP;
709 (*ctmp)->flags |= CF_NOSELECT;
710 (*ctmp)->value = cpystr(_("[ Use Setup/Config command to add Keywords ]"));
711 (*ctmp)->valoffset = COLOR_INDENT;
716 char *
717 color_parenthetical(struct variable *var)
719 int norm, exc, exc_inh;
720 char **lval, *ret = "";
722 if(var == &ps_global->vars[V_VIEW_HDR_COLORS]
723 || var == &ps_global->vars[V_INDEX_TOKEN_COLORS]
724 || var == &ps_global->vars[V_KW_COLORS]){
725 norm = (LVAL(var, Main) != NULL);
726 exc = (LVAL(var, ps_global->ew_for_except_vars) != NULL);
727 exc_inh = ((lval=LVAL(var, ps_global->ew_for_except_vars)) &&
728 lval[0] && !strcmp(INHERIT, lval[0]));
730 /* editing normal but there is an exception config */
731 if((ps_global->ew_for_except_vars != Main) && (ew == Main)){
732 if((exc && !exc_inh))
733 ret = _(" (overridden by exceptions)");
734 else if(exc && exc_inh)
735 ret = _(" (more in exceptions)");
737 /* editing exception config */
738 else if((ps_global->ew_for_except_vars != Main) &&
739 (ew == ps_global->ew_for_except_vars)){
740 if(exc && exc_inh && norm)
741 ret = _(" (more in main config)");
745 return(ret);
749 void
750 add_header_color_line(struct pine *ps, CONF_S **ctmp, char *val, int which, int varnum)
752 struct variable *vtmp;
753 SPEC_COLOR_S *hc;
754 char tmp[100+1];
755 int l;
757 hc = spec_color_from_var(val, 0);
758 if(varnum == V_INDEX_TOKEN_COLORS){
759 if(hc == NULL || hc->spec == NULL
760 || itoktype(hc->spec, FOR_INDEX) == NULL)
761 return;
763 vtmp = &ps->vars[varnum];
764 l = strlen(varnum == V_VIEW_HDR_COLORS ? HEADER_WORD : TOKEN_WORD);
766 /* Blank line */
767 new_confline(ctmp);
768 (*ctmp)->flags |= CF_NOSELECT | CF_B_LINE;
770 new_confline(ctmp)->var = vtmp;
771 (*ctmp)->varnamep = *ctmp;
772 (*ctmp)->keymenu = &custom_color_setting_keymenu;
773 (*ctmp)->help = config_help(vtmp - ps->vars, 0);
774 (*ctmp)->tool = color_setting_tool;
775 (*ctmp)->flags |= (CF_STARTITEM | CF_COLORSAMPLE | CF_POT_SLCTBL);
776 if(!pico_usingcolor())
777 (*ctmp)->flags |= CF_NOSELECT;
779 /* which is an index into the variable list */
780 (*ctmp)->varmem = CFC_SET_COLOR(which, 0);
782 if(hc && hc->inherit)
783 (*ctmp)->flags = (CF_NOSELECT | CF_INHERIT);
784 else{
786 * This isn't quite right because of the assumption that the
787 * first character of spec fits in one octet. I haven't tried
788 * to figure out what we're really trying to accomplish
789 * with all this. It probably doesn't happen in real life.
791 utf8_snprintf(tmp, sizeof(tmp), "%s%c%.*w Color%*w %s%s",
792 (varnum == V_VIEW_HDR_COLORS ? HEADER_WORD : TOKEN_WORD),
793 (hc && hc->spec) ? (islower((unsigned char)hc->spec[0])
794 ? toupper((unsigned char)hc->spec[0])
795 : hc->spec[0]) : '?',
796 MIN(utf8_width((hc && hc->spec && hc->spec[0]) ? hc->spec+1 : ""),30-l),
797 (hc && hc->spec && hc->spec[0]) ? hc->spec+1 : "",
798 MAX(EQ_COL - COLOR_INDENT -1 -
799 MIN(utf8_width((hc && hc->spec && hc->spec[0]) ? hc->spec+1 : ""),30-l)
800 - l - 6 - 1, 0), "",
801 sample_text(ps,vtmp),
802 color_parenthetical(vtmp));
803 tmp[sizeof(tmp)-1] = '\0';
804 (*ctmp)->value = cpystr(tmp);
807 (*ctmp)->valoffset = COLOR_INDENT;
809 if(hc)
810 free_spec_colors(&hc);
815 * Set up the standard color setting display for one color.
817 * Args fg -- the current foreground color
818 * bg -- the current background color
819 * def -- default box should be checked
821 void
822 add_color_setting_disp(struct pine *ps, CONF_S **ctmp, struct variable *var,
823 CONF_S *varnamep, struct key_menu *km,
824 struct key_menu *cb_km, HelpType help, int indent,
825 int which, char *fg, char *bg, int def)
827 int i, lv, count, trans_is_on, transparent;
828 char tmp[100+1];
829 char *title = _("HELP FOR SETTING UP COLOR");
830 int fg_is_custom = 1, bg_is_custom = 1;
831 #ifdef _WINDOWS
832 CONF_S *cl_custom = NULL;
833 #else
834 char *pvalfg, *pvalbg;
835 #endif
838 /* find longest value's name */
839 count = pico_count_in_color_table();
840 lv = COLOR_BLOB_LEN;
842 trans_is_on = pico_trans_is_on();
844 /* put a title before list */
845 new_confline(ctmp);
846 (*ctmp)->varnamep = varnamep;
847 (*ctmp)->keymenu = km;
848 (*ctmp)->help = NO_HELP;
849 (*ctmp)->tool = color_setting_tool;
850 (*ctmp)->valoffset = indent;
851 (*ctmp)->flags |= CF_NOSELECT;
852 (*ctmp)->varmem = 0;
855 * The width of Foreground plus the spaces before Background should
856 * be about lv + 5 + SPACE_BETWEEN_DOUBLEVARS.
858 (*ctmp)->value = cpystr("Foreground Background");
860 new_confline(ctmp)->var = var;
861 (*ctmp)->varnamep = varnamep;
862 (*ctmp)->keymenu = km;
863 (*ctmp)->help = NO_HELP;
864 (*ctmp)->tool = color_setting_tool;
865 (*ctmp)->valoffset = indent;
866 (*ctmp)->flags |= (CF_COLORSAMPLE | CF_NOSELECT);
867 (*ctmp)->varmem = CFC_SET_COLOR(which, 0);
868 (*ctmp)->value = color_setting_text_line(ps, var);
870 for(i = 0; i < count; i++){
871 new_confline(ctmp)->var = var;
872 (*ctmp)->varnamep = varnamep;
873 (*ctmp)->keymenu = km;
874 (*ctmp)->help = help;
875 (*ctmp)->help_title = title;
876 (*ctmp)->tool = color_setting_tool;
877 (*ctmp)->valoffset = indent;
878 /* 5 is length of "( ) " */
879 (*ctmp)->val2offset = indent + lv + 5 + SPACE_BETWEEN_DOUBLEVARS;
880 (*ctmp)->flags |= CF_DOUBLEVAR;
881 (*ctmp)->varmem = CFC_SET_COLOR(which, i);
883 transparent = (trans_is_on && i == count-1);
884 if(transparent)
885 (*ctmp)->help = h_config_usetransparent_color;
887 if(fg_is_custom && fg && !strucmp(color_to_canonical_name(fg), colorx(i)))
888 fg_is_custom = 0;
890 if(bg_is_custom && bg && !strucmp(color_to_canonical_name(bg), colorx(i)))
891 bg_is_custom = 0;
893 (*ctmp)->value = new_color_line(transparent ? COLOR_BLOB_TRAN
894 : COLOR_BLOB,
895 fg &&
896 !strucmp(color_to_canonical_name(fg), colorx(i)),
897 bg &&
898 !strucmp(color_to_canonical_name(bg), colorx(i)),
899 lv);
902 #ifdef _WINDOWS
903 new_confline(ctmp)->var = var;
904 (*ctmp)->varnamep = varnamep;
905 (*ctmp)->keymenu = (km == &custom_color_changing_keymenu)
906 ? &custom_rgb_keymenu :
907 (km == &kw_color_changing_keymenu)
908 ? &kw_rgb_keymenu : &color_rgb_keymenu;
909 (*ctmp)->help = help;
910 (*ctmp)->help_title = title;
911 (*ctmp)->tool = color_setting_tool;
912 (*ctmp)->valoffset = indent;
913 /* 5 is length of "( ) " */
914 (*ctmp)->val2offset = indent + lv + 5 + SPACE_BETWEEN_DOUBLEVARS;
915 (*ctmp)->flags |= CF_DOUBLEVAR;
916 (*ctmp)->varmem = CFC_SET_COLOR(which, i);
917 cl_custom = (*ctmp);
918 #endif
920 if(offer_normal_color_for_var(ps, var)){
921 new_confline(ctmp)->var = var;
922 (*ctmp)->varnamep = varnamep;
923 (*ctmp)->keymenu = km;
924 (*ctmp)->help = h_config_usenormal_color;
925 (*ctmp)->help_title = title;
926 (*ctmp)->tool = color_setting_tool;
927 (*ctmp)->valoffset = indent;
928 /* 5 is length of "( ) " */
929 (*ctmp)->val2offset = indent + lv + 5 + SPACE_BETWEEN_DOUBLEVARS;
930 (*ctmp)->flags |= CF_DOUBLEVAR;
931 (*ctmp)->varmem = CFC_SET_COLOR(which, CFC_ICOLOR_NORM);
932 if(fg_is_custom && fg && !struncmp(fg, MATCH_NORM_COLOR, RGBLEN))
933 fg_is_custom = 0;
935 if(bg_is_custom && bg && !struncmp(bg, MATCH_NORM_COLOR, RGBLEN))
936 bg_is_custom = 0;
938 (*ctmp)->value = new_color_line(COLOR_BLOB_NORM,
939 fg && !struncmp(fg, MATCH_NORM_COLOR, RGBLEN),
940 bg && !struncmp(bg, MATCH_NORM_COLOR, RGBLEN),
941 lv);
944 if(offer_none_color_for_var(ps, var)){
945 new_confline(ctmp)->var = var;
946 (*ctmp)->varnamep = varnamep;
947 (*ctmp)->keymenu = km;
948 (*ctmp)->help = h_config_usenone_color;
949 (*ctmp)->help_title = title;
950 (*ctmp)->tool = color_setting_tool;
951 (*ctmp)->valoffset = indent;
952 /* 5 is length of "( ) " */
953 (*ctmp)->val2offset = indent + lv + 5 + SPACE_BETWEEN_DOUBLEVARS;
954 (*ctmp)->flags |= CF_DOUBLEVAR;
955 (*ctmp)->varmem = CFC_SET_COLOR(which, CFC_ICOLOR_NONE);
956 if(fg_is_custom && fg && !struncmp(fg, MATCH_NONE_COLOR, RGBLEN))
957 fg_is_custom = 0;
959 if(bg_is_custom && bg && !struncmp(bg, MATCH_NONE_COLOR, RGBLEN))
960 bg_is_custom = 0;
962 (*ctmp)->value = new_color_line(COLOR_BLOB_NONE,
963 fg && !struncmp(fg, MATCH_NONE_COLOR, RGBLEN),
964 bg && !struncmp(bg, MATCH_NONE_COLOR, RGBLEN),
965 lv);
968 #ifdef _WINDOWS
969 if(cl_custom)
970 cl_custom->value = new_color_line("Custom", fg_is_custom, bg_is_custom, lv);
971 #endif
973 new_confline(ctmp)->var = var;
974 (*ctmp)->varnamep = varnamep;
975 (*ctmp)->keymenu = cb_km;
976 (*ctmp)->help = h_config_dflt_color;
977 (*ctmp)->help_title = title;
978 (*ctmp)->tool = color_setting_tool;
979 (*ctmp)->valoffset = indent;
980 (*ctmp)->varmem = CFC_SET_COLOR(which, 0);
981 #ifdef _WINDOWS
982 snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ', "Default");
983 tmp[sizeof(tmp)-1] = '\0';
984 #else
985 pvalfg = PVAL(var,Main);
986 pvalbg = PVAL(var+1,Main);
987 if(!var->is_list &&
988 ((var == &ps->vars[V_NORM_FORE_COLOR]) ||
989 (ew == Post && pvalfg && pvalfg[0] && pvalbg && pvalbg[0]) ||
990 (var->global_val.p && var->global_val.p[0] &&
991 (var+1)->global_val.p && (var+1)->global_val.p[0])))
992 snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ', "Default");
993 else if(var == &ps->vars[V_REV_FORE_COLOR])
994 snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
995 "Default (terminal's standout mode, usually reverse video)");
996 else if(var == &ps->vars[V_SLCTBL_FORE_COLOR])
997 snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
998 "Default (Bold Normal Color)");
999 else if(var == &ps->vars[V_TITLECLOSED_FORE_COLOR])
1000 snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
1001 "Default (same as Title Color)");
1002 else if(var_defaults_to_rev(var))
1003 snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
1004 "Default (same as Reverse Color)");
1005 else if(km == &kw_color_changing_keymenu)
1006 snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
1007 "Default (same as Indexline Color)");
1008 else
1009 snprintf(tmp, sizeof(tmp), "[%c] %s", def ? 'X' : ' ',
1010 "Default (same as Normal Color)");
1012 tmp[sizeof(tmp)-1] = '\0';
1013 #endif
1014 (*ctmp)->value = cpystr(tmp);
1017 * Add a checkbox to turn bold on or off for selectable-item color.
1019 if(var == &ps->vars[V_SLCTBL_FORE_COLOR]){
1020 char **lval;
1022 new_confline(ctmp)->var = var;
1023 (*ctmp)->varnamep = varnamep;
1024 (*ctmp)->keymenu = &selectable_bold_checkbox_keymenu;
1025 (*ctmp)->help = h_config_bold_slctbl;
1026 (*ctmp)->help_title = title;
1027 (*ctmp)->tool = color_setting_tool;
1028 (*ctmp)->valoffset = indent;
1029 (*ctmp)->varmem = feature_list_index(F_SLCTBL_ITEM_NOBOLD);
1031 lval = LVAL(&ps->vars[V_FEATURE_LIST], ew);
1033 * We don't use checkbox_pretty_value here because we just want
1034 * the word Bold instead of the name of the variable and because
1035 * we are actually using the negative of the feature. That is,
1036 * the feature is really NOBOLD and we are using Bold.
1038 snprintf(tmp, sizeof(tmp), "[%c] %s",
1039 test_feature(lval, feature_list_name(F_SLCTBL_ITEM_NOBOLD), 0)
1040 ? ' ' : 'X', "Bold");
1041 tmp[sizeof(tmp)-1] = '\0';
1043 (*ctmp)->value = cpystr(tmp);
1049 is_rgb_color(char *color)
1051 int i, j;
1053 for(i = 0; i < 3; i++){
1054 if(i && *color++ != ',')
1055 return(FALSE);
1057 for(j = 0; j < 3; j++, color++)
1058 if(!isdigit((unsigned char) *color))
1059 return(FALSE);
1062 return(TRUE);
1066 char *
1067 new_color_line(char *color, int fg, int bg, int len)
1069 char tmp[256];
1071 snprintf(tmp, sizeof(tmp), "(%c) %-*.*s%*s(%c) %-*.*s",
1072 fg ? R_SELD : ' ', len, len, color, SPACE_BETWEEN_DOUBLEVARS, "",
1073 bg ? R_SELD : ' ', len, len, color);
1074 tmp[sizeof(tmp)-1] = '\0';
1075 return(cpystr(tmp));
1080 color_text_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
1082 int rv = 0, i;
1083 struct variable v, *save_var;
1084 SPEC_COLOR_S *hc, *hcolors;
1085 char *starting_val, *val, tmp[100], ***alval, **apval;
1087 if(cmd == MC_EXIT)
1088 return(simple_exit_cmd(flags));
1090 alval = ALVAL((*cl)->var, ew);
1091 if(!alval || !*alval)
1092 return(rv);
1094 hcolors = spec_colors_from_varlist(*alval, 0);
1096 for(hc = hcolors, i=0; hc; hc = hc->next, i++)
1097 if(CFC_ICUST(*cl) == i)
1098 break;
1100 starting_val = (hc && hc->val) ? pattern_to_string(hc->val) : NULL;
1102 memset(&v, 0, sizeof(v));
1103 v.is_used = 1;
1104 v.is_user = 1;
1105 snprintf(tmp, sizeof(tmp), "\"%c%s Pattern\"",
1106 islower((unsigned char)hc->spec[0])
1107 ? toupper((unsigned char)hc->spec[0])
1108 : hc->spec[0],
1109 hc->spec[1] ? hc->spec + 1 : "");
1110 tmp[sizeof(tmp)-1] = '\0';
1111 v.name = tmp;
1112 /* have to use right part of v so text_tool will work right */
1113 apval = APVAL(&v, ew);
1114 *apval = starting_val ? cpystr(starting_val) : NULL;
1115 set_current_val(&v, FALSE, FALSE);
1117 save_var = (*cl)->var;
1118 (*cl)->var = &v;
1119 rv = text_tool(ps, cmd, cl, flags);
1121 if(rv == 1){
1122 val = *apval;
1123 *apval = NULL;
1124 if(val)
1125 removing_leading_and_trailing_white_space(val);
1127 if(hc->val)
1128 fs_give((void **)&hc->val);
1130 hc->val = string_to_pattern(val);
1132 (*cl)->var = save_var;
1134 if((*alval)[CFC_ICUST(*cl)])
1135 fs_give((void **)&(*alval)[CFC_ICUST(*cl)]);
1137 (*alval)[CFC_ICUST(*cl)] = var_from_spec_color(hc);
1138 set_current_color_vals(ps);
1139 ps->mangled_screen = 1;
1141 else
1142 (*cl)->var = save_var;
1144 if(hcolors)
1145 free_spec_colors(&hcolors);
1146 if(*apval)
1147 fs_give((void **)apval);
1148 if(v.current_val.p)
1149 fs_give((void **)&v.current_val.p);
1150 if(starting_val)
1151 fs_give((void **)&starting_val);
1153 return(rv);
1158 * Test whether or not a var is one of the vars which might have a
1159 * color value stored in it.
1161 * returns: 1 if it is a color var, 0 otherwise
1164 color_holding_var(struct pine *ps, struct variable *var)
1166 if(treat_color_vars_as_text)
1167 return(0);
1168 else
1169 return(var && var->name &&
1170 (srchstr(var->name, "-foreground-color") ||
1171 srchstr(var->name, "-background-color") ||
1172 var == &ps->vars[V_INDEX_TOKEN_COLORS] ||
1173 var == &ps->vars[V_VIEW_HDR_COLORS] ||
1174 var == &ps->vars[V_KW_COLORS]));
1179 * test whether or not a var is one of the vars having to do with color
1181 * returns: 1 if it is a color var, 0 otherwise
1184 color_related_var(struct pine *ps, struct variable *var)
1186 return(
1187 #ifndef _WINDOWS
1188 var == &ps->vars[V_COLOR_STYLE] ||
1189 #endif
1190 var == &ps->vars[V_INDEX_COLOR_STYLE] ||
1191 var == &ps->vars[V_TITLEBAR_COLOR_STYLE] ||
1192 color_holding_var(ps, var));
1197 offer_normal_color_for_var(struct pine *ps, struct variable *var)
1199 return(color_holding_var(ps, var)
1200 && var != &ps->vars[V_NORM_FORE_COLOR]
1201 && var != &ps->vars[V_NORM_BACK_COLOR]
1202 && var != &ps->vars[V_REV_FORE_COLOR]
1203 && var != &ps->vars[V_REV_BACK_COLOR]
1204 && var != &ps->vars[V_SLCTBL_FORE_COLOR]
1205 && var != &ps->vars[V_SLCTBL_BACK_COLOR]);
1210 offer_none_color_for_var(struct pine *ps, struct variable *var)
1212 return(color_holding_var(ps, var)
1213 && (!struncmp(var->name, "index-", 6)
1214 || var == &ps->vars[V_KW_COLORS]));
1217 char *
1218 colorindexrule(char *s)
1220 char *conftext;
1221 char ***alval, **t;
1223 if(!strcmp(s, "SUBJECT") || !strcmp(s, "SUBJECTTEXT")
1224 || !strcmp(s, "SUBJKEYTEXT") || !strcmp(s, "SUBJKEYINITTEXT")
1225 || !strcmp(s, "FROMORTO") || !strcmp(s, "FROM"))
1226 return s;
1228 t = NULL;
1229 if((conftext = add_viewerhdr_escapes(s)) != NULL){
1230 if((alval = ALVAL(&ps_global->vars[V_INDEX_TOKEN_COLORS], ew)) != NULL){
1231 if((t = *alval) && t[0] && !t[0][0] && !(t+1)[0])
1232 free_list_array(alval);
1234 for(t = *alval; t && t[0]; t++){
1235 if(strstr(*t, conftext) != NULL)
1236 break;
1239 fs_give((void **)&conftext);
1241 return t && *t ? *t : NULL;
1246 color_setting_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
1248 int rv = 0, i, cancel = 0, deefault;
1249 int curcolor, prevcolor, nextcolor, another;
1250 CONF_S *ctmp, *first_line, *beg = NULL, *end = NULL,
1251 *cur_beg, *cur_end, *prev_beg, *prev_end,
1252 *next_beg, *next_end;
1253 struct variable *v, *fgv, *bgv, *setv = NULL, *otherv;
1254 SPEC_COLOR_S *hc = NULL, *new_hcolor;
1255 SPEC_COLOR_S *hcolors = NULL;
1256 KEYWORD_S *kw;
1257 char *old_val, *confline = NULL;
1258 char prompt[100], sval[MAXPATH+1];
1259 char **lval, **apval, ***alval, **t;
1260 char **apval1, **apval2;
1261 HelpType help;
1262 ESCKEY_S opts[3];
1263 #ifdef _WINDOWS
1264 char *pval;
1265 #endif
1267 sval[0] = '\0';
1269 switch(cmd){
1270 case MC_CHOICE : /* set a color */
1272 if(((*cl)->flags & CF_VAR2 && fixed_var((*cl)->var+1, NULL, NULL)) ||
1273 (!((*cl)->flags & CF_VAR2) && fixed_var((*cl)->var, NULL, NULL))){
1274 if(((*cl)->var->post_user_val.p ||
1275 ((*cl)->var+1)->post_user_val.p ||
1276 (*cl)->var->main_user_val.p ||
1277 ((*cl)->var+1)->main_user_val.p)
1278 && want_to(_("Delete old unused personal option setting"),
1279 'y', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
1280 delete_user_vals((*cl)->var);
1281 delete_user_vals((*cl)->var+1);
1282 q_status_message(SM_ORDER, 0, 3, _("Deleted"));
1283 rv = 1;
1286 return(rv);
1289 fgv = (*cl)->var; /* foreground color */
1290 bgv = (*cl)->var+1; /* background color */
1291 v = ((*cl)->flags & CF_VAR2) ? bgv : fgv; /* var being changed */
1293 apval = APVAL(v, ew);
1294 old_val = apval ? *apval : NULL;
1296 if(apval){
1297 if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
1298 *apval = cpystr(colorx(CFC_ICOLOR(*cl)));
1299 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
1300 *apval = cpystr(MATCH_NORM_COLOR);
1301 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
1302 *apval = cpystr(MATCH_NONE_COLOR);
1303 else if(old_val)
1304 *apval = cpystr(is_rgb_color(old_val)
1305 ? old_val : color_to_asciirgb(old_val));
1306 else if(v->current_val.p)
1307 *apval = cpystr(is_rgb_color(v->current_val.p)
1308 ? v->current_val.p
1309 : color_to_asciirgb(v->current_val.p));
1310 else if(v == fgv)
1311 *apval = cpystr(color_to_asciirgb(colorx(COL_BLACK)));
1312 else
1313 *apval = cpystr(color_to_asciirgb(colorx(COL_WHITE)));
1316 if(old_val)
1317 fs_give((void **)&old_val);
1319 set_current_val(v, TRUE, FALSE);
1322 * If the user sets one of foreground/background and the
1323 * other is not yet set, set the other.
1325 if(PVAL(v, ew)){
1326 if(v == fgv && !PVAL(bgv, ew)){
1327 setv = bgv;
1328 otherv = fgv;
1330 else if(v == bgv && !PVAL(fgv, ew)){
1331 setv = fgv;
1332 otherv = bgv;
1336 if(setv){
1337 if((apval = APVAL(setv, ew)) != NULL){
1338 if(setv->current_val.p)
1339 *apval = cpystr(setv->current_val.p);
1340 else if (setv == fgv && ps_global->VAR_NORM_FORE_COLOR)
1341 *apval = cpystr(ps_global->VAR_NORM_FORE_COLOR);
1342 else if (setv == bgv && ps_global->VAR_NORM_BACK_COLOR)
1343 *apval = cpystr(ps_global->VAR_NORM_BACK_COLOR);
1344 else if(!strucmp(color_to_canonical_name(otherv->current_val.p),
1345 colorx(COL_WHITE)))
1346 *apval = cpystr(colorx(COL_BLACK));
1347 else
1348 *apval = cpystr(colorx(COL_WHITE));
1351 set_current_val(setv, TRUE, FALSE);
1354 fix_side_effects(ps, v, 0);
1355 set_current_color_vals(ps);
1358 * Turn on selected *'s for default selections, if any, and
1359 * for ones we forced on.
1361 color_update_selected(ps, *cl, PVAL(fgv, ew), PVAL(bgv, ew), TRUE);
1363 ClearScreen();
1364 rv = ps->mangled_screen = 1;
1365 break;
1367 case MC_CHOICEB : /* set a custom hdr color */
1369 * Find the SPEC_COLOR_S for header.
1371 lval = LVAL((*cl)->var, ew);
1372 hcolors = spec_colors_from_varlist(lval, 0);
1373 for(hc = hcolors, i=0; hc; hc = hc->next, i++)
1374 if(CFC_ICUST(*cl) == i)
1375 break;
1377 if(hc){
1378 if((*cl)->flags & CF_VAR2){
1379 old_val = hc->bg;
1380 if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
1381 hc->bg = cpystr(colorx(CFC_ICOLOR(*cl)));
1382 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
1383 hc->bg = cpystr(MATCH_NORM_COLOR);
1384 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
1385 hc->bg = cpystr(MATCH_NONE_COLOR);
1386 else if(old_val)
1387 hc->bg = cpystr(is_rgb_color(old_val)
1388 ? old_val
1389 : color_to_asciirgb(old_val));
1390 else
1391 hc->bg = cpystr(color_to_asciirgb(colorx(COL_WHITE)));
1393 if(old_val)
1394 fs_give((void **) &old_val);
1397 * If the user sets one of foreground/background and the
1398 * other is not yet set, set it.
1400 if(!(hc->fg && hc->fg[0])){
1401 if(hc->fg)
1402 fs_give((void **)&hc->fg);
1404 hc->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
1407 else{
1408 old_val = hc->fg;
1410 if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
1411 hc->fg = cpystr(colorx(CFC_ICOLOR(*cl)));
1412 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
1413 hc->fg = cpystr(MATCH_NORM_COLOR);
1414 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
1415 hc->fg = cpystr(MATCH_NONE_COLOR);
1416 else if(old_val)
1417 hc->fg = cpystr(is_rgb_color(old_val)
1418 ? old_val
1419 : color_to_asciirgb(old_val));
1420 else
1421 hc->fg = cpystr(color_to_asciirgb(colorx(COL_BLACK)));
1423 if(old_val)
1424 fs_give((void **) &old_val);
1426 if(!(hc->bg && hc->bg[0])){
1427 if(hc->bg)
1428 fs_give((void **)&hc->bg);
1430 hc->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
1436 * Turn on selected *'s for default selections, if any, and
1437 * for ones we forced on.
1439 color_update_selected(ps, *cl,
1440 (hc && hc->fg && hc->fg[0]
1441 && hc->bg && hc->bg[0])
1442 ? hc->fg : ps->VAR_NORM_FORE_COLOR,
1443 (hc && hc->fg && hc->fg[0]
1444 && hc->bg && hc->bg[0])
1445 ? hc->bg : ps->VAR_NORM_BACK_COLOR,
1446 TRUE);
1448 if(hc && lval && lval[i]){
1449 fs_give((void **)&lval[i]);
1450 lval[i] = var_from_spec_color(hc);
1453 if(hcolors)
1454 free_spec_colors(&hcolors);
1456 fix_side_effects(ps, (*cl)->var, 0);
1457 set_current_color_vals(ps);
1458 ClearScreen();
1459 rv = ps->mangled_screen = 1;
1460 break;
1463 case MC_CHOICEC : /* set a custom keyword color */
1464 /* find keyword associated with color we are editing */
1465 for(kw=ps->keywords, i=0; kw; kw=kw->next, i++)
1466 if(CFC_ICUST(*cl) == i)
1467 break;
1469 if(!kw){ /* can't happen */
1470 dprint((1,
1471 "This can't happen, kw not set when setting keyword color\n"));
1472 break;
1475 hcolors = spec_colors_from_varlist(LVAL((*cl)->var, ew), 0);
1478 * Look through hcolors, derived from lval, to find this keyword
1479 * and its current color.
1481 for(hc = hcolors; hc; hc = hc->next)
1482 if(hc->spec && ((kw->nick && !strucmp(kw->nick, hc->spec))
1483 || (kw->kw && !strucmp(kw->kw, hc->spec))))
1484 break;
1486 if(!hc){ /* this keyword didn't have a color set, add to list */
1487 SPEC_COLOR_S *new;
1489 new = (SPEC_COLOR_S *) fs_get(sizeof(*hc));
1490 memset((void *) new, 0, sizeof(*new));
1491 new->spec = cpystr(kw->kw);
1492 new->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
1493 new->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
1495 if(hcolors){
1496 for(hc = hcolors; hc->next; hc = hc->next)
1499 hc->next = new;
1501 else
1502 hcolors = new;
1504 hc = new;
1507 if(hc){
1508 if((*cl)->flags & CF_VAR2){
1509 old_val = hc->bg;
1510 if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
1511 hc->bg = cpystr(colorx(CFC_ICOLOR(*cl)));
1512 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
1513 hc->bg = cpystr(MATCH_NORM_COLOR);
1514 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
1515 hc->bg = cpystr(MATCH_NONE_COLOR);
1516 else if(old_val)
1517 hc->bg = cpystr(is_rgb_color(old_val)
1518 ? old_val
1519 : color_to_asciirgb(old_val));
1520 else
1521 hc->bg = cpystr(color_to_asciirgb(colorx(COL_WHITE)));
1523 if(old_val)
1524 fs_give((void **) &old_val);
1527 * If the user sets one of foreground/background and the
1528 * other is not yet set, set it.
1530 if(!(hc->fg && hc->fg[0])){
1531 if(hc->fg)
1532 fs_give((void **)&hc->fg);
1534 hc->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
1537 else{
1538 old_val = hc->fg;
1540 if(CFC_ICOLOR(*cl) < pico_count_in_color_table())
1541 hc->fg = cpystr(colorx(CFC_ICOLOR(*cl)));
1542 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NORM)
1543 hc->fg = cpystr(MATCH_NORM_COLOR);
1544 else if(CFC_ICOLOR(*cl) == CFC_ICOLOR_NONE)
1545 hc->fg = cpystr(MATCH_NONE_COLOR);
1546 else if(old_val)
1547 hc->fg = cpystr(is_rgb_color(old_val)
1548 ? old_val
1549 : color_to_asciirgb(old_val));
1550 else
1551 hc->fg = cpystr(color_to_asciirgb(colorx(COL_BLACK)));
1553 if(old_val)
1554 fs_give((void **) &old_val);
1556 if(!(hc->bg && hc->bg[0])){
1557 if(hc->bg)
1558 fs_give((void **)&hc->bg);
1560 hc->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
1566 * Turn on selected *'s for default selections, if any, and
1567 * for ones we forced on.
1569 color_update_selected(ps, *cl,
1570 (hc && hc->fg && hc->fg[0]
1571 && hc->bg && hc->bg[0])
1572 ? hc->fg : ps->VAR_NORM_FORE_COLOR,
1573 (hc && hc->fg && hc->fg[0]
1574 && hc->bg && hc->bg[0])
1575 ? hc->bg : ps->VAR_NORM_BACK_COLOR,
1576 TRUE);
1578 alval = ALVAL((*cl)->var, ew);
1579 free_list_array(alval);
1580 *alval = varlist_from_spec_colors(hcolors);
1582 if(hcolors)
1583 free_spec_colors(&hcolors);
1585 fix_side_effects(ps, (*cl)->var, 0);
1586 set_current_color_vals(ps);
1587 ClearScreen();
1588 rv = ps->mangled_screen = 1;
1589 break;
1591 case MC_TOGGLE : /* toggle default on or off */
1592 fgv = (*cl)->var; /* foreground color */
1593 bgv = (*cl)->var+1; /* background color */
1595 if((*cl)->value[1] == 'X'){ /* turning default off */
1596 (*cl)->value[1] = ' ';
1598 * Take whatever color is the current_val and suck it
1599 * into the user_val. Same colors remain checked.
1601 apval1 = APVAL(fgv, ew);
1602 if(apval1){
1603 if(*apval1)
1604 fs_give((void **)apval1);
1607 apval2 = APVAL(bgv, ew);
1608 if(apval2){
1609 if(*apval2)
1610 fs_give((void **)apval2);
1613 /* editing normal but there is an exception config */
1614 if((ps->ew_for_except_vars != Main) && (ew == Main)){
1615 COLOR_PAIR *newc;
1617 /* use global_val if it is set */
1618 if(fgv && fgv->global_val.p && fgv->global_val.p[0] &&
1619 bgv && bgv->global_val.p && bgv->global_val.p[0]){
1620 *apval1 = cpystr(fgv->global_val.p);
1621 *apval2 = cpystr(bgv->global_val.p);
1623 else if(var_defaults_to_rev(fgv) &&
1624 (newc = pico_get_rev_color())){
1625 *apval1 = cpystr(newc->fg);
1626 *apval2 = cpystr(newc->bg);
1628 else{
1629 *apval1 = cpystr(ps->VAR_NORM_FORE_COLOR);
1630 *apval2 = cpystr(ps->VAR_NORM_BACK_COLOR);
1633 else{ /* editing outermost config */
1634 /* just use current_vals */
1635 if(fgv->current_val.p)
1636 *apval1 = cpystr(fgv->current_val.p);
1637 if(bgv->current_val.p)
1638 *apval2 = cpystr(bgv->current_val.p);
1641 else{ /* turning default on */
1642 char *starred_fg = NULL, *starred_bg = NULL;
1644 (*cl)->value[1] = 'X';
1645 apval = APVAL(fgv, ew);
1646 if(apval && *apval)
1647 fs_give((void **)apval);
1649 apval = APVAL(bgv, ew);
1650 if(apval && *apval)
1651 fs_give((void **)apval);
1653 if(fgv->cmdline_val.p)
1654 fs_give((void **)&fgv->cmdline_val.p);
1656 if(bgv->cmdline_val.p)
1657 fs_give((void **)&bgv->cmdline_val.p);
1659 set_current_color_vals(ps);
1661 if(fgv == &ps->vars[V_SLCTBL_FORE_COLOR]){
1662 F_TURN_OFF(F_SLCTBL_ITEM_NOBOLD, ps);
1663 (*cl)->next->value[1] = 'X';
1666 /* editing normal but there is an exception config */
1667 if((ps->ew_for_except_vars != Main) && (ew == Main)){
1668 COLOR_PAIR *newc;
1670 /* use global_val if it is set */
1671 if(fgv && fgv->global_val.p && fgv->global_val.p[0] &&
1672 bgv && bgv->global_val.p && bgv->global_val.p[0]){
1673 starred_fg = fgv->global_val.p;
1674 starred_bg = bgv->global_val.p;
1676 else if(var_defaults_to_rev(fgv) &&
1677 (newc = pico_get_rev_color())){
1678 starred_fg = newc->fg;
1679 starred_bg = newc->bg;
1681 else{
1682 starred_fg = ps->VAR_NORM_FORE_COLOR;
1683 starred_bg = ps->VAR_NORM_BACK_COLOR;
1686 else{ /* editing outermost config */
1687 starred_fg = fgv->current_val.p;
1688 starred_bg = bgv->current_val.p;
1692 * Turn on selected *'s for default selections.
1694 color_update_selected(ps, prev_confline(*cl),
1695 starred_fg, starred_bg, FALSE);
1697 ps->mangled_body = 1;
1700 fix_side_effects(ps, fgv, 0);
1701 rv = 1;
1702 break;
1704 case MC_TOGGLEB : /* toggle default on or off, hdr color */
1706 * Find the SPEC_COLOR_S for header.
1708 rv = 1;
1709 lval = LVAL((*cl)->var, ew);
1710 hcolors = spec_colors_from_varlist(lval, 0);
1711 for(hc = hcolors, i=0; hc; hc = hc->next, i++)
1712 if(CFC_ICUST(*cl) == i)
1713 break;
1715 if((*cl)->value[1] == 'X'){ /* turning default off */
1716 (*cl)->value[1] = ' ';
1718 * Take whatever color is the default value and suck it
1719 * into the hc structure.
1721 if(hc){
1722 if(hc->bg)
1723 fs_give((void **)&hc->bg);
1724 if(hc->fg)
1725 fs_give((void **)&hc->fg);
1727 if(ps->VAR_NORM_FORE_COLOR &&
1728 ps->VAR_NORM_FORE_COLOR[0] &&
1729 ps->VAR_NORM_BACK_COLOR &&
1730 ps->VAR_NORM_BACK_COLOR[0]){
1731 hc->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
1732 hc->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
1735 if(lval && lval[i]){
1736 fs_give((void **)&lval[i]);
1737 lval[i] = var_from_spec_color(hc);
1741 else{ /* turning default on */
1742 (*cl)->value[1] = 'X';
1743 /* Remove current colors, leaving val */
1744 if(hc){
1745 if(hc->bg)
1746 fs_give((void **)&hc->bg);
1747 if(hc->fg)
1748 fs_give((void **)&hc->fg);
1750 if(lval && lval[i]){
1751 fs_give((void **)&lval[i]);
1752 lval[i] = var_from_spec_color(hc);
1756 set_current_color_vals(ps);
1757 ClearScreen();
1758 ps->mangled_screen = 1;
1762 if(hcolors)
1763 free_spec_colors(&hcolors);
1766 * Turn on selected *'s for default selections.
1768 color_update_selected(ps, prev_confline(*cl),
1769 ps->VAR_NORM_FORE_COLOR,
1770 ps->VAR_NORM_BACK_COLOR,
1771 FALSE);
1773 break;
1775 case MC_TOGGLEC : /* toggle default on or off, keyword color */
1776 for(kw=ps->keywords, i=0; kw; kw=kw->next, i++)
1777 if(CFC_ICUST(*cl) == i)
1778 break;
1780 if(!kw){ /* can't happen */
1781 dprint((1,
1782 "This can't happen, kw not set when togglec keyword color\n"));
1783 break;
1786 hcolors = spec_colors_from_varlist(LVAL((*cl)->var, ew), 0);
1789 * Look through hcolors, derived from lval, to find this keyword
1790 * and its current color.
1792 for(hc = hcolors; hc; hc = hc->next)
1793 if(hc->spec && ((kw->nick && !strucmp(kw->nick, hc->spec))
1794 || (kw->kw && !strucmp(kw->kw, hc->spec))))
1795 break;
1797 /* Remove this color from list */
1798 if(hc){
1799 SPEC_COLOR_S *tmp;
1801 if(hc == hcolors){
1802 hcolors = hc->next;
1803 hc->next = NULL;
1804 free_spec_colors(&hc);
1806 else{
1807 for(tmp = hcolors; tmp->next; tmp = tmp->next)
1808 if(tmp->next == hc)
1809 break;
1811 if(tmp->next){
1812 tmp->next = hc->next;
1813 hc->next = NULL;
1814 free_spec_colors(&hc);
1819 if((*cl)->value[1] == 'X')
1820 (*cl)->value[1] = ' ';
1821 else
1822 (*cl)->value[1] = 'X';
1825 * Turn on selected *'s for default selections, if any, and
1826 * for ones we forced on.
1828 color_update_selected(ps, prev_confline(*cl),
1829 ps->VAR_NORM_FORE_COLOR,
1830 ps->VAR_NORM_BACK_COLOR,
1831 FALSE);
1833 alval = ALVAL((*cl)->var, ew);
1834 free_list_array(alval);
1835 *alval = varlist_from_spec_colors(hcolors);
1837 if(hcolors)
1838 free_spec_colors(&hcolors);
1840 fix_side_effects(ps, (*cl)->var, 0);
1841 set_current_color_vals(ps);
1842 ClearScreen();
1843 rv = ps->mangled_screen = 1;
1844 break;
1846 case MC_TOGGLED : /* toggle selectable item bold on or off */
1847 toggle_feature_bit(ps, feature_list_index(F_SLCTBL_ITEM_NOBOLD),
1848 &ps->vars[V_FEATURE_LIST], *cl, 1);
1849 ps->mangled_body = 1; /* to fix Sample Text */
1850 rv = 1;
1851 break;
1853 case MC_DEFAULT : /* restore default values */
1855 /* First, confirm that user wants to restore all default colors */
1856 if(want_to(_("Really restore all colors to default values"),
1857 'y', 'n', NO_HELP, WT_NORM) != 'y'){
1858 cmd_cancelled("RestoreDefs");
1859 return(rv);
1862 /* get rid of all user set colors */
1863 for(v = ps->vars; v->name; v++){
1864 if(!color_holding_var(ps, v)
1865 || v == &ps->vars[V_INDEX_TOKEN_COLORS]
1866 || v == &ps->vars[V_VIEW_HDR_COLORS]
1867 || v == &ps->vars[V_KW_COLORS])
1868 continue;
1870 apval = APVAL(v, ew);
1871 if(apval && *apval)
1872 fs_give((void **)apval);
1874 if(v->cmdline_val.p)
1875 fs_give((void **)&v->cmdline_val.p);
1879 * For custom header colors, we want to remove the color values
1880 * but leave the spec value so that it is easy to reset.
1882 alval = ALVAL(&ps->vars[V_VIEW_HDR_COLORS], ew);
1883 if(alval && *alval){
1884 SPEC_COLOR_S *global_hcolors = NULL, *hcg;
1886 v = &ps->vars[V_VIEW_HDR_COLORS];
1887 if(v->global_val.l && v->global_val.l[0])
1888 global_hcolors = spec_colors_from_varlist(v->global_val.l, 0);
1890 hcolors = spec_colors_from_varlist(*alval, 0);
1891 for(hc = hcolors; hc; hc = hc->next){
1892 if(hc->fg)
1893 fs_give((void **)&hc->fg);
1894 if(hc->bg)
1895 fs_give((void **)&hc->bg);
1897 for(hcg = global_hcolors; hcg; hcg = hcg->next){
1898 if(hc->spec && hcg->spec && !strucmp(hc->spec, hcg->spec)){
1899 hc->fg = hcg->fg;
1900 hcg->fg = NULL;
1901 hc->bg = hcg->bg;
1902 hcg->bg = NULL;
1903 if(hc->val && !hcg->val)
1904 fs_give((void **) &hc->val);
1908 if(global_hcolors)
1909 free_spec_colors(&global_hcolors);
1912 free_list_array(alval);
1913 *alval = varlist_from_spec_colors(hcolors);
1915 if(hcolors)
1916 free_spec_colors(&hcolors);
1919 /* same for index token colors */
1920 alval = ALVAL(&ps->vars[V_INDEX_TOKEN_COLORS], ew);
1921 if(alval && *alval){
1922 SPEC_COLOR_S *global_hcolors = NULL, *hcg;
1924 v = &ps->vars[V_INDEX_TOKEN_COLORS];
1925 if(v->global_val.l && v->global_val.l[0])
1926 global_hcolors = spec_colors_from_varlist(v->global_val.l, 0);
1928 hcolors = spec_colors_from_varlist(*alval, 0);
1929 for(hc = hcolors; hc; hc = hc->next){
1930 if(hc->fg)
1931 fs_give((void **)&hc->fg);
1932 if(hc->bg)
1933 fs_give((void **)&hc->bg);
1935 for(hcg = global_hcolors; hcg; hcg = hcg->next){
1936 if(hc->spec && hcg->spec && !strucmp(hc->spec, hcg->spec)){
1937 hc->fg = hcg->fg;
1938 hcg->fg = NULL;
1939 hc->bg = hcg->bg;
1940 hcg->bg = NULL;
1941 if(hc->val && !hcg->val)
1942 fs_give((void **) &hc->val);
1946 if(global_hcolors)
1947 free_spec_colors(&global_hcolors);
1950 free_list_array(alval);
1951 *alval = varlist_from_spec_colors(hcolors);
1953 if(hcolors)
1954 free_spec_colors(&hcolors);
1958 * Same for keyword colors.
1960 alval = ALVAL(&ps->vars[V_KW_COLORS], ew);
1961 if(alval && *alval){
1962 hcolors = spec_colors_from_varlist(*alval, 0);
1963 for(hc = hcolors; hc; hc = hc->next){
1964 if(hc->fg)
1965 fs_give((void **)&hc->fg);
1966 if(hc->bg)
1967 fs_give((void **)&hc->bg);
1970 free_list_array(alval);
1971 *alval = varlist_from_spec_colors(hcolors);
1973 if(hcolors)
1974 free_spec_colors(&hcolors);
1977 /* set bold for selectable items */
1978 F_TURN_OFF(F_SLCTBL_ITEM_NOBOLD, ps);
1979 lval = LVAL(&ps->vars[V_FEATURE_LIST], ew);
1980 if(test_feature(lval, feature_list_name(F_SLCTBL_ITEM_NOBOLD), 0))
1981 toggle_feature_bit(ps, feature_list_index(F_SLCTBL_ITEM_NOBOLD),
1982 &ps->vars[V_FEATURE_LIST], *cl, 1);
1984 set_current_color_vals(ps);
1985 clear_index_cache(ps->mail_stream, 0);
1987 /* redo config display */
1988 *cl = first_confline(*cl);
1989 free_conflines(cl);
1990 opt_screen->top_line = NULL;
1991 first_line = NULL;
1992 color_config_init_display(ps, cl, &first_line);
1993 *cl = first_line;
1994 ClearScreen();
1995 ps->mangled_screen = 1;
1996 rv = 1;
1997 break;
1999 case MC_ADDHEADER: /* add custom index token color */
2000 case MC_ADD : /* add custom header color */
2001 /* get header field name */
2002 help = NO_HELP;
2003 while(1){
2004 i = optionally_enter(sval, -FOOTER_ROWS(ps), 0, sizeof(sval),
2005 (cmd == MC_ADD ? _("Enter the name of the header field to be added: ")
2006 : _("Enter the name of the index token to be added: ")),
2007 NULL, help, NULL);
2008 if(i == 0){
2009 if(cmd == MC_ADDHEADER){
2010 if(itoktype(sval, FOR_INDEX) == NULL){
2011 q_status_message1(SM_ORDER, 1, 3,
2012 _("token \"%s\" not recognized"), sval);
2013 continue;
2014 } else if(colorindexrule(sval) != NULL){
2015 q_status_message1(SM_ORDER, 1, 3,
2016 _("Color rule for token \"%s\" already exists"), sval);
2017 continue;
2020 break;
2022 else if(i == 1){
2023 cmd_cancelled("Add");
2024 cancel = 1;
2025 break;
2027 else if(i == 3){
2028 help = help == NO_HELP ? h_config_add_custom_color : NO_HELP;
2029 continue;
2031 else
2032 break;
2035 ps->mangled_footer = 1;
2037 removing_leading_and_trailing_white_space(sval);
2038 if(sval[strlen(sval)-1] == ':') /* remove trailing colon */
2039 sval[strlen(sval)-1] = '\0';
2041 removing_trailing_white_space(sval);
2043 if(cancel || !sval[0])
2044 break;
2046 new_hcolor = (SPEC_COLOR_S *)fs_get(sizeof(*new_hcolor));
2047 memset((void *)new_hcolor, 0, sizeof(*new_hcolor));
2048 new_hcolor->spec = cpystr(sval);
2049 confline = var_from_spec_color(new_hcolor);
2051 /* add it to end of list */
2052 alval = ALVAL(&ps->vars[(cmd == MC_ADD ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS)], ew);
2053 if(alval){
2054 /* get rid of possible empty value first */
2055 if((t = *alval) && t[0] && !t[0][0] && !(t+1)[0])
2056 free_list_array(alval);
2058 for(t = *alval, i=0; t && t[0]; t++)
2059 i++;
2061 if(i)
2062 fs_resize((void **)alval, sizeof(char *) * (i+1+1));
2063 else
2064 *alval = (char **)fs_get(sizeof(char *) * (i+1+1));
2066 (*alval)[i] = confline;
2067 (*alval)[i+1] = NULL;
2070 set_current_color_vals(ps);
2072 /* go to end of display */
2073 for(ctmp = *cl; ctmp && ctmp->next; ctmp = next_confline(ctmp))
2076 /* back up to the KEYWORD COLORS title line */
2077 for(; ctmp && (!ctmp->value || strcmp(ctmp->value, (cmd == MC_ADD ? KW_COLORS_HDR : HDR_COLORS)))
2078 && ctmp->prev;
2079 ctmp = prev_confline(ctmp))
2083 * Back up to last header line, or comment line if no header lines.
2084 * One of many in a long line of dangerous moves in the config
2085 * screens.
2087 ctmp = prev_confline(ctmp); /* ------- line */
2088 ctmp = prev_confline(ctmp); /* blank line */
2089 ctmp = prev_confline(ctmp); /* the line */
2091 *cl = ctmp;
2093 /* delete the comment line if there were no headers before this */
2094 if(i == 0){
2095 beg = ctmp->prev;
2096 end = ctmp;
2098 *cl = beg ? beg->prev : NULL;
2100 if(beg && beg->prev) /* this will always be true */
2101 beg->prev->next = end ? end->next : NULL;
2103 if(end && end->next)
2104 end->next->prev = beg ? beg->prev : NULL;
2106 if(end)
2107 end->next = NULL;
2109 if(beg == opt_screen->top_line || end == opt_screen->top_line)
2110 opt_screen->top_line = NULL;
2112 free_conflines(&beg);
2115 add_header_color_line(ps, cl, confline, i, cmd == MC_ADD
2116 ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS);
2118 /* be sure current is on selectable line */
2119 for(; *cl && ((*cl)->flags & CF_NOSELECT); *cl = next_confline(*cl))
2121 for(; *cl && ((*cl)->flags & CF_NOSELECT); *cl = prev_confline(*cl))
2124 rv = ps->mangled_body = 1;
2125 break;
2127 case MC_DELETE : /* delete custom header color */
2128 if((*cl)->var != &ps->vars[V_VIEW_HDR_COLORS]
2129 && (*cl)->var != &ps->vars[V_INDEX_TOKEN_COLORS]){
2130 q_status_message(SM_ORDER, 0, 2,
2131 _("Can't delete this color setting"));
2132 break;
2135 if(want_to(((*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
2136 ? _("Really delete header color from config")
2137 : _("Really delete index token color from config")),
2138 'y', 'n', NO_HELP, WT_NORM) != 'y'){
2139 cmd_cancelled("Delete");
2140 return(rv);
2143 alval = ALVAL((*cl)->var, ew);
2144 if(alval){
2145 int n, j;
2147 for(t = *alval, n=0; t && t[0]; t++)
2148 n++;
2150 j = CFC_ICUST(*cl);
2152 if(n > j){ /* it better be */
2153 if((*alval)[j])
2154 fs_give((void **)&(*alval)[j]);
2156 for(i = j; i < n; i++)
2157 (*alval)[i] = (*alval)[i+1];
2161 set_current_color_vals(ps);
2164 * Note the conf lines that go with this header. That's the
2165 * blank line before and the current line.
2167 beg = (*cl)->prev;
2168 end = *cl;
2170 another = 0;
2171 /* reset current line */
2172 if(end && end->next && end->next->next &&
2173 end->next->next->var == &ps->vars[(*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
2174 ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS]){
2175 *cl = end->next->next; /* next Header Color */
2176 another++;
2178 else if(beg && beg->prev &&
2179 beg->prev->var == &ps->vars[(*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
2180 ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS]){
2181 *cl = beg->prev; /* prev Header Color */
2182 another++;
2185 /* adjust SPEC_COLOR_S index (varmem) values */
2186 for(ctmp = end; ctmp; ctmp = next_confline(ctmp))
2187 if(ctmp->var == &ps->vars[(*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
2188 ? V_VIEW_HDR_COLORS : V_INDEX_TOKEN_COLORS])
2189 ctmp->varmem = CFC_ICUST_DEC(ctmp);
2192 * If that was the last header color line, add in the comment
2193 * line placeholder. If there is another, just delete the
2194 * old conf lines.
2196 if(another){
2197 if(beg && beg->prev) /* this will always be true */
2198 beg->prev->next = end ? end->next : NULL;
2200 if(end && end->next)
2201 end->next->prev = beg ? beg->prev : NULL;
2203 if(end)
2204 end->next = NULL;
2206 if(beg == opt_screen->top_line || end == opt_screen->top_line)
2207 opt_screen->top_line = NULL;
2209 free_conflines(&beg);
2211 else if(end){
2212 if(end->varname)
2213 fs_give((void **) &end->varname);
2215 if(end->value)
2216 fs_give((void **) &end->value);
2218 end->flags = CF_NOSELECT;
2219 end->help = NO_HELP;
2220 end->value = cpystr((*cl)->var == &ps->vars[V_VIEW_HDR_COLORS]
2221 ? _(ADDHEADER_COMMENT) : _(ADDINDEXTOKEN_COMMENT));
2222 end->valoffset = COLOR_INDENT;
2223 end->varnamep = NULL;
2224 end->varmem = 0;
2225 end->keymenu = NULL;
2226 end->tool = NULL;
2229 /* if not selectable, find next selectable line */
2230 for(; *cl && ((*cl)->flags & CF_NOSELECT) && next_confline(*cl); *cl = next_confline(*cl))
2232 /* if no next selectable line, search backwards for one */
2233 for(; *cl && ((*cl)->flags & CF_NOSELECT) && prev_confline(*cl); *cl = prev_confline(*cl))
2236 rv = ps->mangled_body = 1;
2237 q_status_message(SM_ORDER, 0, 3, _("header color deleted"));
2238 break;
2240 case MC_SHUFFLE : /* shuffle order of custom headers */
2241 if((*cl)->var != &ps->vars[V_VIEW_HDR_COLORS]){
2242 q_status_message(SM_ORDER, 0, 2,
2243 _("Can't shuffle this color setting"));
2244 break;
2247 alval = ALVAL((*cl)->var, ew);
2248 if(!alval)
2249 return(rv);
2251 curcolor = CFC_ICUST(*cl);
2252 prevcolor = curcolor-1;
2253 nextcolor = curcolor+1;
2254 if(!*alval || !(*alval)[nextcolor])
2255 nextcolor = -1;
2257 if((prevcolor < 0 && nextcolor < 0) || !*alval){
2258 q_status_message(SM_ORDER, 0, 3,
2259 _("Shuffle only makes sense when there is more than one Header Color defined"));
2260 return(rv);
2263 /* Move it up or down? */
2264 i = 0;
2265 opts[i].ch = 'u';
2266 opts[i].rval = 'u';
2267 opts[i].name = "U";
2268 opts[i++].label = _("Up");
2270 opts[i].ch = 'd';
2271 opts[i].rval = 'd';
2272 opts[i].name = "D";
2273 opts[i++].label = _("Down");
2275 opts[i].ch = -1;
2276 deefault = 'u';
2278 if(prevcolor < 0){ /* no up */
2279 opts[0].ch = -2;
2280 deefault = 'd';
2282 else if(nextcolor < 0)
2283 opts[1].ch = -2; /* no down */
2285 snprintf(prompt, sizeof(prompt), _("Shuffle %s%s%s ? "),
2286 (opts[0].ch != -2) ? _("UP") : "",
2287 (opts[0].ch != -2 && opts[1].ch != -2) ? " or " : "",
2288 (opts[1].ch != -2) ? _("DOWN") : "");
2289 prompt[sizeof(prompt)-1] = '\0';
2290 help = (opts[0].ch == -2) ? h_hdrcolor_shuf_down
2291 : (opts[1].ch == -2) ? h_hdrcolor_shuf_up
2292 : h_hdrcolor_shuf;
2294 i = radio_buttons(prompt, -FOOTER_ROWS(ps), opts, deefault, 'x',
2295 help, RB_NORM);
2297 switch(i){
2298 case 'x':
2299 cmd_cancelled("Shuffle");
2300 return(rv);
2302 case 'u':
2303 case 'd':
2304 break;
2307 /* swap order */
2308 if(i == 'd'){
2309 old_val = (*alval)[curcolor];
2310 (*alval)[curcolor] = (*alval)[nextcolor];
2311 (*alval)[nextcolor] = old_val;
2313 else if(i == 'u'){
2314 old_val = (*alval)[curcolor];
2315 (*alval)[curcolor] = (*alval)[prevcolor];
2316 (*alval)[prevcolor] = old_val;
2318 else /* can't happen */
2319 return(rv);
2321 set_current_color_vals(ps);
2324 * Swap the conf lines.
2327 cur_beg = (*cl)->prev;
2328 cur_end = *cl;
2330 if(i == 'd'){
2331 next_beg = cur_end->next;
2332 next_end = next_beg ? next_beg->next : NULL;
2334 if(next_end->next)
2335 next_end->next->prev = cur_end;
2336 cur_end->next = next_end->next;
2337 next_end->next = cur_beg;
2338 if(cur_beg->prev)
2339 cur_beg->prev->next = next_beg;
2340 next_beg->prev = cur_beg->prev;
2341 cur_beg->prev = next_end;
2343 /* adjust SPEC_COLOR_S index values */
2344 cur_beg->varmem = CFC_ICUST_INC(cur_beg);
2345 cur_beg->next->varmem = CFC_ICUST_INC(cur_beg->next);
2347 next_beg->varmem = CFC_ICUST_DEC(next_beg);
2348 next_beg->next->varmem = CFC_ICUST_DEC(next_beg->next);
2350 if(opt_screen->top_line == cur_end)
2351 opt_screen->top_line = next_end;
2352 else if(opt_screen->top_line == cur_beg)
2353 opt_screen->top_line = next_beg;
2355 else{
2356 prev_end = cur_beg->prev;
2357 prev_beg = prev_end ? prev_end->prev : NULL;
2359 if(prev_beg && prev_beg->prev)
2360 prev_beg->prev->next = cur_beg;
2361 cur_beg->prev = prev_beg->prev;
2362 prev_beg->prev = cur_end;
2363 if(cur_end->next)
2364 cur_end->next->prev = prev_end;
2365 prev_end->next = cur_end->next;
2366 cur_end->next = prev_beg;
2368 /* adjust SPEC_COLOR_S index values */
2369 cur_beg->varmem = CFC_ICUST_DEC(cur_beg);
2370 cur_beg->next->varmem = CFC_ICUST_DEC(cur_beg->next);
2372 prev_beg->varmem = CFC_ICUST_INC(prev_beg);
2373 prev_beg->next->varmem = CFC_ICUST_INC(prev_beg->next);
2375 if(opt_screen->top_line == prev_end)
2376 opt_screen->top_line = cur_end;
2377 else if(opt_screen->top_line == prev_beg)
2378 opt_screen->top_line = cur_beg;
2381 rv = ps->mangled_body = 1;
2382 q_status_message(SM_ORDER, 0, 3, _("Header Colors shuffled"));
2383 break;
2385 case MC_EDIT:
2386 rv = color_edit_screen(ps, cl);
2387 if((*cl)->value && (*cl)->var &&
2388 srchstr((*cl)->var->name, "-foreground-color")){
2389 fs_give((void **)&(*cl)->value);
2390 (*cl)->value = pretty_value(ps, *cl);
2393 break;
2395 case MC_EXIT: /* exit */
2396 if((*cl)->keymenu == &color_changing_keymenu ||
2397 (*cl)->keymenu == &kw_color_changing_keymenu ||
2398 (*cl)->keymenu == &custom_color_changing_keymenu ||
2399 ((*cl)->prev &&
2400 ((*cl)->prev->keymenu == &color_changing_keymenu ||
2401 (*cl)->prev->keymenu == &kw_color_changing_keymenu ||
2402 (*cl)->prev->keymenu == &custom_color_changing_keymenu)) ||
2403 ((*cl)->prev->prev &&
2404 ((*cl)->prev->prev->keymenu == &color_changing_keymenu ||
2405 (*cl)->prev->prev->keymenu == &kw_color_changing_keymenu ||
2406 (*cl)->prev->prev->keymenu == &custom_color_changing_keymenu)))
2407 rv = simple_exit_cmd(flags);
2408 else
2409 rv = config_exit_cmd(flags);
2411 break;
2413 #ifdef _WINDOWS
2414 case MC_RGB1 :
2415 fgv = (*cl)->var;
2416 bgv = (*cl)->var+1;
2417 v = (*cl)->var;
2418 if((*cl)->flags & CF_VAR2)
2419 v += 1;
2421 pval = PVAL(v, ew);
2422 apval = APVAL(v, ew);
2423 if(old_val = mswin_rgbchoice(pval ? pval : v->current_val.p)){
2424 if(*apval)
2425 fs_give((void **)apval);
2427 *apval = old_val;
2428 set_current_val(v, TRUE, FALSE);
2429 fix_side_effects(ps, v, 0);
2430 set_current_color_vals(ps);
2431 color_update_selected(ps, *cl, PVAL(fgv, ew), PVAL(bgv, ew), TRUE);
2432 rv = ps->mangled_screen = 1;
2435 break;
2437 case MC_RGB2 :
2439 * Find the SPEC_COLOR_S for header.
2441 alval = ALVAL((*cl)->var, ew);
2442 hcolors = spec_colors_from_varlist(*alval, 0);
2444 for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
2445 if(CFC_ICUST(*cl) == i){
2446 char **pc = ((*cl)->flags & CF_VAR2) ? &hc->bg : &hc->fg;
2448 if(old_val = mswin_rgbchoice(*pc)){
2449 fs_give((void **) pc);
2450 *pc = old_val;
2451 color_update_selected(ps, *cl,
2452 (hc->fg && hc->fg[0]
2453 && hc->bg && hc->bg[0])
2454 ? hc->fg : ps->VAR_NORM_FORE_COLOR,
2455 (hc->fg && hc->fg[0]
2456 && hc->bg && hc->bg[0])
2457 ? hc->bg : ps->VAR_NORM_BACK_COLOR,
2458 TRUE);
2460 if(hc && *alval && (*alval)[i]){
2461 fs_give((void **)&(*alval)[i]);
2462 (*alval)[i] = var_from_spec_color(hc);
2465 if(hcolors)
2466 free_spec_colors(&hcolors);
2468 set_current_color_vals(ps);
2469 ClearScreen();
2470 rv = ps->mangled_screen = 1;
2473 break;
2476 break;
2478 case MC_RGB3 :
2480 * Custom colored keywords.
2482 for(kw=ps->keywords, i=0; kw; kw=kw->next, i++)
2483 if(CFC_ICUST(*cl) == i)
2484 break;
2486 if(!kw){ /* can't happen */
2487 dprint((1,
2488 "This can't happen, kw not set in MC_RGB3\n"));
2489 break;
2492 hcolors = spec_colors_from_varlist(LVAL((*cl)->var, ew), 0);
2495 * Look through hcolors, derived from lval, to find this keyword
2496 * and its current color.
2498 for(hc = hcolors; hc; hc = hc->next)
2499 if(hc->spec && ((kw->nick && !strucmp(kw->nick, hc->spec))
2500 || (kw->kw && !strucmp(kw->kw, hc->spec))))
2501 break;
2503 if(!hc){ /* this keyword didn't have a color set, add to list */
2504 SPEC_COLOR_S *new;
2506 new = (SPEC_COLOR_S *) fs_get(sizeof(*hc));
2507 memset((void *) new, 0, sizeof(*new));
2508 new->spec = cpystr(kw->kw);
2509 new->fg = cpystr(ps->VAR_NORM_FORE_COLOR);
2510 new->bg = cpystr(ps->VAR_NORM_BACK_COLOR);
2512 if(hcolors){
2513 for(hc = hcolors; hc->next; hc = hc->next)
2516 hc->next = new;
2518 else
2519 hcolors = new;
2521 hc = new;
2524 if(hc){
2525 char **pc = ((*cl)->flags & CF_VAR2) ? &hc->bg : &hc->fg;
2527 if(old_val = mswin_rgbchoice(*pc)){
2528 fs_give((void **) pc);
2529 *pc = old_val;
2532 * Turn on selected *'s for default selections, if any, and
2533 * for ones we forced on.
2535 color_update_selected(ps, *cl,
2536 (hc && hc->fg && hc->fg[0]
2537 && hc->bg && hc->bg[0])
2538 ? hc->fg : ps->VAR_NORM_FORE_COLOR,
2539 (hc && hc->fg && hc->fg[0]
2540 && hc->bg && hc->bg[0])
2541 ? hc->bg : ps->VAR_NORM_BACK_COLOR,
2542 TRUE);
2544 alval = ALVAL((*cl)->var, ew);
2545 free_list_array(alval);
2546 *alval = varlist_from_spec_colors(hcolors);
2547 fix_side_effects(ps, (*cl)->var, 0);
2548 set_current_color_vals(ps);
2549 ClearScreen();
2550 rv = 1;
2554 if(hcolors)
2555 free_spec_colors(&hcolors);
2557 ps->mangled_screen = 1;
2558 break;
2559 #endif
2561 default :
2562 rv = -1;
2563 break;
2567 if(rv == 1)
2568 exception_override_warning((*cl)->var);
2570 return(rv);
2575 * Turn on selected *'s for default selections, if any, and
2576 * for ones we forced on.
2577 * Adjust the Sample line right above the color selection lines.
2579 void
2580 color_update_selected(struct pine *ps, CONF_S *cl, char *fg, char *bg, int cleardef)
2582 int i, fg_is_custom = 1, bg_is_custom = 1;
2583 #ifdef _WINDOWS
2584 CONF_S *cl_custom = NULL;
2585 #endif
2587 /* back up to header line */
2588 for(; cl && (cl->flags & CF_DOUBLEVAR); cl = prev_confline(cl))
2591 /* adjust sample line */
2592 if(cl && cl->var && cl->flags & CF_COLORSAMPLE){
2593 if(cl->value)
2594 fs_give((void **)&cl->value);
2596 cl->value = color_setting_text_line(ps, cl->var);
2599 for(i = 0, cl = next_confline(cl);
2600 i < pico_count_in_color_table() && cl;
2601 i++, cl = next_confline(cl)){
2602 if(fg && !strucmp(color_to_canonical_name(fg), colorx(i))){
2603 cl->value[1] = R_SELD;
2604 fg_is_custom = 0;
2606 else
2607 cl->value[1] = ' ';
2609 if(bg && !strucmp(color_to_canonical_name(bg), colorx(i))){
2610 cl->value[cl->val2offset - cl->valoffset + 1] = R_SELD;
2611 bg_is_custom = 0;
2613 else
2614 cl->value[cl->val2offset - cl->valoffset + 1] = ' ';
2617 #ifdef _WINDOWS
2618 cl_custom = cl;
2619 cl = next_confline(cl);
2620 #endif
2622 if(cl && cl->var && offer_normal_color_for_var(ps, cl->var)){
2623 if(fg && !struncmp(color_to_canonical_name(fg), MATCH_NORM_COLOR, RGBLEN)){
2624 cl->value[1] = R_SELD;
2625 fg_is_custom = 0;
2627 else
2628 cl->value[1] = ' ';
2630 if(bg && !struncmp(color_to_canonical_name(bg), MATCH_NORM_COLOR, RGBLEN)){
2631 cl->value[cl->val2offset - cl->valoffset + 1] = R_SELD;
2632 bg_is_custom = 0;
2634 else
2635 cl->value[cl->val2offset - cl->valoffset + 1] = ' ';
2637 cl = next_confline(cl);
2640 if(cl && cl->var && offer_none_color_for_var(ps, cl->var)){
2641 if(fg && !struncmp(color_to_canonical_name(fg), MATCH_NONE_COLOR, RGBLEN)){
2642 cl->value[1] = R_SELD;
2643 fg_is_custom = 0;
2645 else
2646 cl->value[1] = ' ';
2648 if(bg && !struncmp(color_to_canonical_name(bg), MATCH_NONE_COLOR, RGBLEN)){
2649 cl->value[cl->val2offset - cl->valoffset + 1] = R_SELD;
2650 bg_is_custom = 0;
2652 else
2653 cl->value[cl->val2offset - cl->valoffset + 1] = ' ';
2655 cl = next_confline(cl);
2658 /* Turn off Default X */
2659 if(cleardef)
2660 cl->value[1] = ' ';
2662 #ifdef _WINDOWS
2663 /* check for a custom setting */
2664 if(cl_custom){
2665 cl_custom->value[1] = fg_is_custom ? R_SELD : ' ';
2666 cl_custom->value[cl_custom->val2offset - cl_custom->valoffset + 1]
2667 = bg_is_custom ? R_SELD : ' ';
2669 #endif
2674 color_edit_screen(struct pine *ps, CONF_S **cl)
2676 OPT_SCREEN_S screen, *saved_screen;
2677 CONF_S *ctmp = NULL, *first_line = NULL, *ctmpb;
2678 int rv, is_index = 0, is_hdrcolor = 0, indent = 12;
2679 int is_general = 0, is_keywordcol = 0, is_idxtokcol = 0;
2680 char tmp[1200+1], name[1200], *p;
2681 struct variable *vtmp, v;
2682 int i, def;
2683 COLOR_PAIR *color = NULL;
2684 SPEC_COLOR_S *hc = NULL, *hcolors = NULL;
2685 KEYWORD_S *kw;
2687 vtmp = (*cl)->var;
2688 if(vtmp == &ps->vars[V_VIEW_HDR_COLORS])
2689 is_hdrcolor++;
2690 else if(vtmp == &ps->vars[V_INDEX_TOKEN_COLORS])
2691 is_idxtokcol++;
2692 else if(vtmp == &ps->vars[V_KW_COLORS])
2693 is_keywordcol++;
2694 else if(color_holding_var(ps, vtmp)){
2695 if(!struncmp(vtmp->name, "index-", 6))
2696 is_index++;
2697 else
2698 is_general++;
2701 new_confline(&ctmp);
2702 /* Blank line */
2703 ctmp->flags |= CF_NOSELECT | CF_B_LINE;
2705 first_line = ctmp;
2707 new_confline(&ctmp)->var = vtmp;
2709 name[0] = '\0';
2710 if(is_general){
2711 p = srchstr(vtmp->name, "-foreground-color");
2712 snprintf(name, sizeof(name), "%.*s", p ? (int) MIN(p - vtmp->name, 30) : 30, vtmp->name);
2713 name[sizeof(name)-1] = '\0';
2714 if(islower((unsigned char)name[0]))
2715 name[0] = toupper((unsigned char)name[0]);
2717 else if(is_index){
2718 p = srchstr(vtmp->name, "-foreground-color");
2719 snprintf(name, sizeof(name), "%.*s Symbol",
2720 p ? (int) MIN(p - vtmp->name, 30) : 30, vtmp->name);
2721 name[sizeof(name)-1] = '\0';
2722 if(islower((unsigned char)name[0]))
2723 name[0] = toupper((unsigned char)name[0]);
2725 else if(is_hdrcolor){
2726 char **lval;
2728 lval = LVAL(vtmp, ew);
2729 hcolors = spec_colors_from_varlist(lval, 0);
2731 for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
2732 if(CFC_ICUST(*cl) == i)
2733 break;
2735 if(hc){
2736 snprintf(name, sizeof(name), "%s%s", HEADER_WORD, hc->spec);
2737 name[sizeof(name)-1] = '\0';
2738 i = sizeof(HEADER_WORD) - 1;
2739 if(islower((unsigned char) name[i]))
2740 name[i] = toupper((unsigned char) name[i]);
2743 else if(is_idxtokcol){
2744 char **lval;
2746 lval = LVAL(vtmp, ew);
2747 hcolors = spec_colors_from_varlist(lval, 0);
2749 for(hc = hcolors, i = 0; hc; hc = hc->next, i++)
2750 if(CFC_ICUST(*cl) == i)
2751 break;
2753 if(hc){
2754 snprintf(name, sizeof(name), "%s%s", TOKEN_WORD, hc->spec);
2755 name[sizeof(name)-1] = '\0';
2756 i = sizeof(TOKEN_WORD) - 1;
2757 if(islower((unsigned char) name[i]))
2758 name[i] = toupper((unsigned char) name[i]);
2761 else if(is_keywordcol){
2762 char **lval;
2764 for(kw=ps->keywords, i=0; kw; kw=kw->next, i++)
2765 if(CFC_ICUST(*cl) == i)
2766 break;
2768 if(kw){
2769 char *nm, *comment = NULL;
2771 nm = kw->nick ? kw->nick : kw->kw ? kw->kw : "";
2772 if(utf8_width(nm) > 60)
2773 nm = short_str(nm, tmp_20k_buf, SIZEOF_20KBUF, 60, EndDots);
2775 if(kw->nick && kw->kw && kw->kw[0])
2776 comment = kw->kw;
2778 if(utf8_width(nm) + (comment ? utf8_width(comment) : 0) < 60)
2779 utf8_snprintf(name, sizeof(name), "%.50w%s%.50w%s",
2781 comment ? " (" : "",
2782 comment ? comment : "",
2783 comment ? ")" : "");
2784 else
2785 snprintf(name, sizeof(name), "%s", nm);
2787 name[sizeof(name)-1] = '\0';
2789 lval = LVAL(vtmp, ew);
2790 hcolors = spec_colors_from_varlist(lval, 0);
2791 if(kw && hcolors)
2792 if(!(kw->nick && kw->nick[0]
2793 && (color=hdr_color(kw->nick, NULL, hcolors))))
2794 if(kw->kw && kw->kw[0])
2795 color = hdr_color(kw->kw, NULL, hcolors);
2799 snprintf(tmp, sizeof(tmp), "%s Color =", name[0] ? name : "?");
2800 tmp[sizeof(tmp)-1] = '\0';
2801 ctmp->varname = cpystr(tmp);
2802 ctmp->varnamep = ctmpb = ctmp;
2803 ctmp->flags |= (CF_STARTITEM | CF_NOSELECT);
2804 ctmp->keymenu = &color_changing_keymenu;
2806 if(is_hdrcolor || is_idxtokcol){
2807 char **apval;
2809 def = !(hc && hc->fg && hc->fg[0] && hc->bg && hc->bg[0]);
2811 add_color_setting_disp(ps, &ctmp, vtmp, ctmpb,
2812 &custom_color_changing_keymenu,
2813 &hdr_color_checkbox_keymenu,
2814 config_help(vtmp - ps->vars, 0),
2815 indent, CFC_ICUST(*cl),
2816 def ? ps_global->VAR_NORM_FORE_COLOR
2817 : hc->fg,
2818 def ? ps_global->VAR_NORM_BACK_COLOR
2819 : hc->bg,
2820 def);
2822 /* optional string to match in header value */
2823 new_confline(&ctmp);
2824 ctmp->varnamep = ctmpb;
2825 ctmp->keymenu = &color_pattern_keymenu;
2826 ctmp->help = h_config_customhdr_pattern;
2827 ctmp->tool = color_text_tool;
2828 ctmp->varoffset = indent-5;
2829 ctmp->varname = cpystr(_("Pattern to match ="));
2830 ctmp->valoffset = indent-5 + strlen(ctmp->varname) + 1;
2831 ctmp->varmem = (*cl)->varmem;
2834 * This is really ugly. This is just to get the value correct.
2836 memset(&v, 0, sizeof(v));
2837 v.is_used = 1;
2838 v.is_user = 1;
2839 apval = APVAL(&v, ew);
2840 if(hc && hc->val && apval)
2841 *apval = pattern_to_string(hc->val);
2843 set_current_val(&v, FALSE, FALSE);
2844 ctmp->var = &v;
2845 ctmp->value = pretty_value(ps, ctmp);
2846 ctmp->var = vtmp;
2847 if(apval && *apval)
2848 fs_give((void **)apval);
2850 if(v.current_val.p)
2851 fs_give((void **)&v.current_val.p);
2853 if(hcolors)
2854 free_spec_colors(&hcolors);
2856 else if(is_keywordcol){
2858 def = !(color && color->fg && color->fg[0]
2859 && color->bg && color->bg[0]);
2861 add_color_setting_disp(ps, &ctmp, vtmp, ctmpb,
2862 &kw_color_changing_keymenu,
2863 &kw_color_checkbox_keymenu,
2864 config_help(vtmp - ps->vars, 0),
2865 indent, CFC_ICUST(*cl),
2866 def ? ps_global->VAR_NORM_FORE_COLOR
2867 : color->fg,
2868 def ? ps_global->VAR_NORM_BACK_COLOR
2869 : color->bg,
2870 def);
2872 if(hcolors)
2873 free_spec_colors(&hcolors);
2875 else{
2876 char *pvalfg, *pvalbg;
2877 int def;
2878 COLOR_PAIR *newc;
2880 pvalfg = PVAL(vtmp, ew);
2881 pvalbg = PVAL(vtmp+1, ew);
2882 def = !(pvalfg && pvalfg[0] && pvalbg && pvalbg[0]);
2883 if(def){
2884 /* display default val, if there is one */
2885 pvalfg = PVAL(vtmp, Main);
2886 pvalbg = PVAL(vtmp+1, Main);
2887 if(ew == Post && pvalfg && pvalfg[0] && pvalbg && pvalbg[0]){
2890 else if(vtmp && vtmp->global_val.p && vtmp->global_val.p[0] &&
2891 (vtmp+1)->global_val.p && (vtmp+1)->global_val.p[0]){
2892 pvalfg = vtmp->global_val.p;
2893 pvalbg = (vtmp+1)->global_val.p;
2895 else{
2896 if(var_defaults_to_rev(vtmp) && (newc = pico_get_rev_color())){
2897 pvalfg = newc->fg;
2898 pvalbg = newc->bg;
2900 else{
2901 pvalfg = NULL;
2902 pvalbg = NULL;
2907 add_color_setting_disp(ps, &ctmp, vtmp, ctmpb,
2908 &color_changing_keymenu,
2909 &config_checkbox_keymenu,
2910 config_help(vtmp - ps->vars, 0),
2911 indent, 0, pvalfg, pvalbg, def);
2914 first_line = first_sel_confline(first_line);
2916 saved_screen = opt_screen;
2917 memset(&screen, 0, sizeof(screen));
2918 screen.ro_warning = saved_screen ? saved_screen->deferred_ro_warning : 0;
2919 rv = conf_scroll_screen(ps, &screen, first_line,
2920 ew == Post ? _("SETUP COLOR EXCEPTIONS")
2921 : _("SETUP COLOR"),
2922 _("configuration"), 1, NULL);
2924 opt_screen = saved_screen;
2925 ps->mangled_screen = 1;
2926 return(rv);