2 * ========================================================================
3 * Copyright 2006-2007 University of Washington
4 * Copyright 2013-2022 Eduardo Chappa
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
17 #include "confscroll.h"
25 #include "../pith/list.h"
26 #include "../pith/state.h"
27 #include "../pith/conf.h"
28 #include "../pith/thread.h"
34 int context_config_tool(struct pine
*, int, CONF_S
**, unsigned);
35 int context_config_add(struct pine
*, CONF_S
**);
36 int context_config_shuffle(struct pine
*, CONF_S
**);
37 int context_config_edit(struct pine
*, CONF_S
**);
38 int context_config_delete(struct pine
*, CONF_S
**);
39 int ccs_var_delete(struct pine
*, CONTEXT_S
*);
40 int ccs_var_insert(struct pine
*, char *, struct variable
*, char **, int);
41 int context_select_tool(struct pine
*, int, CONF_S
**, unsigned);
45 * Setup CollectionLists. Build a context list on the fly from the config
46 * variable and edit it. This won't include Incoming-Folders because that
47 * is a pseudo collection, but that's ok since we can't do the operations
48 * on it, anyway. Reset real config list at the end.
51 context_config_screen(struct pine
*ps
, CONT_SCR_S
*cs
, int edit_exceptions
)
53 CONTEXT_S
*top
, **clist
, *cp
;
54 CONF_S
*ctmpa
, *first_line
, *heading
;
56 int i
, readonly_warning
, some_defined
, ret
;
57 int reinit_contexts
= 0, prime
;
58 char **lval
, **lval1
, **lval2
, ***alval
;
59 struct variable fake_fspec_var
, fake_nspec_var
;
60 struct variable
*fake_fspec
, *fake_nspec
;
62 ew
= edit_exceptions
? ps_global
->ew_for_except_vars
: Main
;
80 readonly_warning
= prc
? prc
->readonly
: 1;
81 if(prc
&& prc
->quit_to_edit
){
82 quit_to_edit_msg(prc
);
88 top
= NULL
; ctmpa
= NULL
; first_line
= NULL
;
89 some_defined
= 0, prime
= 0;
90 fake_fspec
= &fake_fspec_var
;
91 fake_nspec
= &fake_nspec_var
;
92 memset((void *)fake_fspec
, 0, sizeof(*fake_fspec
));
93 memset((void *)fake_nspec
, 0, sizeof(*fake_nspec
));
95 /* so fixed_var() will work right */
96 fake_fspec
->is_list
= 1;
97 fake_nspec
->is_list
= 1;
98 if((ps
->vars
[V_FOLDER_SPEC
]).is_fixed
){
99 fake_fspec
->is_fixed
= 1;
100 if((ps
->vars
[V_FOLDER_SPEC
]).fixed_val
.l
101 && (ps
->vars
[V_FOLDER_SPEC
]).fixed_val
.l
[0]){
102 fake_fspec
->fixed_val
.l
= (char **) fs_get(2 * sizeof(char *));
103 fake_fspec
->fixed_val
.l
[0]
104 = cpystr((ps
->vars
[V_FOLDER_SPEC
]).fixed_val
.l
[0]);
105 fake_fspec
->fixed_val
.l
[1] = NULL
;
109 if((ps
->vars
[V_NEWS_SPEC
]).is_fixed
){
110 fake_nspec
->is_fixed
= 1;
111 if((ps
->vars
[V_NEWS_SPEC
]).fixed_val
.l
112 && (ps
->vars
[V_NEWS_SPEC
]).fixed_val
.l
[0]){
113 fake_nspec
->fixed_val
.l
= (char **) fs_get(2 * sizeof(char *));
114 fake_nspec
->fixed_val
.l
[0] = cpystr(INHERIT
);
115 fake_nspec
->fixed_val
.l
[0]
116 = cpystr((ps
->vars
[V_NEWS_SPEC
]).fixed_val
.l
[0]);
117 fake_nspec
->fixed_val
.l
[1] = NULL
;
122 lval1
= LVAL(&ps
->vars
[V_FOLDER_SPEC
], ew
);
123 lval2
= LVAL(&ps
->vars
[V_NEWS_SPEC
], ew
);
125 alval
= ALVAL(fake_fspec
, ew
);
127 *alval
= copy_list_array(lval1
);
128 else if(!edit_exceptions
&& ps
->VAR_FOLDER_SPEC
&& ps
->VAR_FOLDER_SPEC
[0] &&
129 ps
->VAR_FOLDER_SPEC
[0][0])
130 *alval
= copy_list_array(ps
->VAR_FOLDER_SPEC
);
135 lval
= LVAL(fake_fspec
, ew
);
136 for(i
= 0; lval
&& lval
[i
]; i
++){
138 if(i
== 0 && !strcmp(lval
[i
], INHERIT
)){
139 cp
= (CONTEXT_S
*)fs_get(sizeof(*cp
));
140 memset((void *)cp
, 0, sizeof(*cp
));
141 cp
->use
= CNTXT_INHERIT
;
142 cp
->label
= cpystr("Default collections are inherited");
144 else if((cp
= new_context(lval
[i
], &prime
)) != NULL
){
145 cp
->var
.v
= fake_fspec
;
150 *clist
= cp
; /* add it to list */
151 clist
= &cp
->next
; /* prepare for next */
155 set_current_val(fake_fspec
, FALSE
, FALSE
);
158 alval
= ALVAL(fake_nspec
, ew
);
160 *alval
= copy_list_array(lval2
);
161 else if(!edit_exceptions
&& ps
->VAR_NEWS_SPEC
&& ps
->VAR_NEWS_SPEC
[0] &&
162 ps
->VAR_NEWS_SPEC
[0][0])
163 *alval
= copy_list_array(ps
->VAR_NEWS_SPEC
);
168 lval
= LVAL(fake_nspec
, ew
);
169 for(i
= 0; lval
&& lval
[i
]; i
++){
171 if(i
== 0 && !strcmp(lval
[i
], INHERIT
)){
172 cp
= (CONTEXT_S
*)fs_get(sizeof(*cp
));
173 memset((void *)cp
, 0, sizeof(*cp
));
174 cp
->use
= CNTXT_INHERIT
;
175 cp
->label
= cpystr("Default collections are inherited");
177 else if((cp
= new_context(lval
[i
], &prime
)) != NULL
){
178 cp
->var
.v
= fake_nspec
;
183 *clist
= cp
; /* add it to list */
184 clist
= &cp
->next
; /* prepare for next */
188 set_current_val(fake_nspec
, FALSE
, FALSE
);
191 for(cp
= top
; cp
; cp
= cp
->next
)
192 if(!(cp
->use
& CNTXT_INHERIT
)){
197 if(edit_exceptions
&& !some_defined
){
198 q_status_message(SM_ORDER
, 3, 7,
199 _("No exceptions to edit. First collection exception must be set by editing file"));
202 free_contexts(&ps_global
->context_list
);
203 init_folders(ps_global
);
210 /* fix up prev pointers */
211 for(cp
= top
; cp
; cp
= cp
->next
)
215 new_confline(&ctmpa
); /* blank line */
216 ctmpa
->keymenu
= cs
->keymenu
;
217 ctmpa
->help
= cs
->help
.text
;
218 ctmpa
->help_title
= cs
->help
.title
;
219 ctmpa
->tool
= context_config_tool
;
220 ctmpa
->flags
|= (CF_NOSELECT
| CF_B_LINE
);
222 for(cp
= top
; cp
; cp
= cp
->next
){
223 new_confline(&ctmpa
);
225 if(!(cp
->use
& CNTXT_INHERIT
))
226 ctmpa
->value
= cpystr(cp
->nickname
? cp
->nickname
: cp
->context
);
228 ctmpa
->var
= cp
->var
.v
;
229 ctmpa
->keymenu
= cs
->keymenu
;
230 ctmpa
->help
= cs
->help
.text
;
231 ctmpa
->help_title
= cs
->help
.title
;
232 ctmpa
->tool
= context_config_tool
;
233 ctmpa
->flags
|= CF_STARTITEM
;
234 ctmpa
->valoffset
= 4;
237 if(cp
->use
& CNTXT_INHERIT
)
238 ctmpa
->flags
|= CF_INHERIT
| CF_NOSELECT
;
240 if((!first_line
&& !(cp
->use
& CNTXT_INHERIT
)) ||
241 (!(cp
->use
& CNTXT_INHERIT
) &&
243 (cs
->starting_var
== cp
->var
.v
) &&
244 (cs
->starting_varmem
== cp
->var
.i
)))
247 /* Add explanatory text */
248 new_confline(&ctmpa
);
249 ctmpa
->value
= cpystr(cp
->label
? cp
->label
: "* * *");
250 ctmpa
->keymenu
= cs
->keymenu
;
251 ctmpa
->help
= cs
->help
.text
;
252 ctmpa
->help_title
= cs
->help
.title
;
253 ctmpa
->tool
= context_config_tool
;
254 ctmpa
->flags
|= CF_NOSELECT
;
255 ctmpa
->valoffset
= 8;
257 /* Always add blank line, make's shuffling a little easier */
258 new_confline(&ctmpa
);
259 heading
->headingp
= ctmpa
; /* use headingp to mark end */
260 ctmpa
->keymenu
= cs
->keymenu
;
261 ctmpa
->help
= cs
->help
.text
;
262 ctmpa
->help_title
= cs
->help
.title
;
263 ctmpa
->tool
= context_config_tool
;
264 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
265 ctmpa
->valoffset
= 0;
268 cs
->starting_var
= NULL
;
271 memset(&screen
, 0, sizeof(screen
));
272 screen
.ro_warning
= readonly_warning
;
273 ret
= conf_scroll_screen(ps
, &screen
, first_line
, cs
->title
,
274 cs
->print_string
, 0, NULL
);
282 * 15 means the tool wants us to reset and go again. The config var
283 * has been changed. The contexts will be built again from the
284 * config variable and the real contexts will be rebuilt below.
285 * This is easier and safer than having the tools rebuild the context
286 * list and the display correct. It's difficult to do because of all
287 * the inheriting and defaulting going on.
290 if(edit_exceptions
&& !LVAL(fake_fspec
, ew
) && !LVAL(fake_nspec
, ew
)){
291 if(want_to(_("Really delete last exceptional collection"),
292 'n', 'n', h_config_context_del_except
,
293 WT_FLUSH_IN
) != 'y'){
294 free_variable_values(fake_fspec
);
295 free_variable_values(fake_nspec
);
300 /* resolve variable changes */
301 if((lval1
&& !equal_list_arrays(lval1
, LVAL(fake_fspec
, ew
))) ||
302 (fake_fspec
&& !equal_list_arrays(ps
->VAR_FOLDER_SPEC
,
303 LVAL(fake_fspec
, ew
)))){
304 i
= set_variable_list(V_FOLDER_SPEC
,
305 LVAL(fake_fspec
, ew
), TRUE
, ew
);
306 set_current_val(&ps
->vars
[V_FOLDER_SPEC
], TRUE
, FALSE
);
309 q_status_message(SM_ORDER
, 3, 3,
310 _("Trouble saving change, cancelled"));
311 else if(!edit_exceptions
&& lval1
&& !LVAL(fake_fspec
, ew
)){
312 cs
->starting_var
= fake_fspec
;
313 cs
->starting_varmem
= 0;
314 q_status_message(SM_ORDER
, 3, 3,
315 _("Deleted last Folder-Collection, reverting to default"));
317 else if(!edit_exceptions
&& !lval1
&& !LVAL(fake_fspec
, ew
)){
318 cs
->starting_var
= fake_fspec
;
319 cs
->starting_varmem
= 0;
320 q_status_message(SM_ORDER
, 3, 3,
321 _("Deleted default Folder-Collection, reverting back to default"));
325 if((lval2
&& !equal_list_arrays(lval2
, LVAL(fake_nspec
, ew
))) ||
326 (fake_nspec
&& !equal_list_arrays(ps
->VAR_NEWS_SPEC
,
327 LVAL(fake_nspec
, ew
)))){
328 i
= set_variable_list(V_NEWS_SPEC
,
329 LVAL(fake_nspec
, ew
), TRUE
, ew
);
330 set_news_spec_current_val(TRUE
, FALSE
);
333 q_status_message(SM_ORDER
, 3, 3,
334 _("Trouble saving change, cancelled"));
335 else if(!edit_exceptions
&& lval2
&& !LVAL(fake_nspec
, ew
) &&
336 ps
->VAR_NEWS_SPEC
&& ps
->VAR_NEWS_SPEC
[0] &&
337 ps
->VAR_NEWS_SPEC
[0][0]){
338 cs
->starting_var
= fake_nspec
;
339 cs
->starting_varmem
= 0;
340 q_status_message(SM_ORDER
, 3, 3,
341 _("Deleted last News-Collection, reverting to default"));
343 else if(!edit_exceptions
&& !lval2
&& !LVAL(fake_nspec
, ew
) &&
344 ps
->VAR_NEWS_SPEC
&& ps
->VAR_NEWS_SPEC
[0] &&
345 ps
->VAR_NEWS_SPEC
[0][0]){
346 cs
->starting_var
= fake_nspec
;
347 cs
->starting_varmem
= 0;
348 q_status_message(SM_ORDER
, 3, 3,
349 _("Deleted default News-Collection, reverting back to default"));
353 free_variable_values(fake_fspec
);
354 free_variable_values(fake_nspec
);
358 ps
->mangled_screen
= 1;
360 /* make the real context list match the changed config variables */
362 free_contexts(&ps_global
->context_list
);
363 init_folders(ps_global
);
368 /*----------------------------------------------------------------------
369 Function to display/manage collections
373 context_select_screen(struct pine
*ps
, CONT_SCR_S
*cs
, int ro_warn
)
376 CONF_S
*ctmpa
= NULL
, *first_line
= NULL
, *heading
;
377 OPT_SCREEN_S screen
, *saved_screen
;
378 int readonly_warning
= 0;
380 /* restrict to normal config */
384 readonly_warning
= 0;
385 else if(ps
->restricted
)
386 readonly_warning
= 1;
388 PINERC_S
*prc
= NULL
;
401 readonly_warning
= prc
? prc
->readonly
: 1;
402 if(ro_warn
&& prc
&& prc
->quit_to_edit
){
403 quit_to_edit_msg(prc
);
408 readonly_warning
*= ro_warn
;
411 * Loop thru available contexts, setting up for display
412 * (note: if no "cp" we're hosed. should never happen ;)
414 for(cp
= *cs
->contexts
; cp
->prev
; cp
= cp
->prev
)
417 /* delimiter for Mail Collections */
418 new_confline(&ctmpa
); /* blank line */
419 ctmpa
->keymenu
= cs
->keymenu
;
420 ctmpa
->help
= cs
->help
.text
;
421 ctmpa
->help_title
= cs
->help
.title
;
422 ctmpa
->tool
= context_select_tool
;
423 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
426 new_confline(&ctmpa
);
428 ctmpa
->value
= cpystr(cp
->nickname
? cp
->nickname
: cp
->context
);
429 ctmpa
->var
= cp
->var
.v
;
430 ctmpa
->keymenu
= cs
->keymenu
;
431 ctmpa
->help
= cs
->help
.text
;
432 ctmpa
->help_title
= cs
->help
.title
;
433 ctmpa
->tool
= context_select_tool
;
434 ctmpa
->flags
|= CF_STARTITEM
;
435 ctmpa
->valoffset
= 4;
439 if(!first_line
|| cp
== cs
->start
)
442 /* Add explanatory text */
443 new_confline(&ctmpa
);
444 ctmpa
->value
= cpystr(cp
->label
? cp
->label
: "* * *");
445 ctmpa
->keymenu
= cs
->keymenu
;
446 ctmpa
->help
= cs
->help
.text
;
447 ctmpa
->help_title
= cs
->help
.title
;
448 ctmpa
->tool
= context_select_tool
;
449 ctmpa
->flags
|= CF_NOSELECT
;
450 ctmpa
->valoffset
= 8;
452 /* Always add blank line, make's shuffling a little easier */
453 new_confline(&ctmpa
);
454 heading
->headingp
= ctmpa
;
455 ctmpa
->keymenu
= cs
->keymenu
;
456 ctmpa
->help
= cs
->help
.text
;
457 ctmpa
->help_title
= cs
->help
.title
;
458 ctmpa
->tool
= context_select_tool
;
459 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
460 ctmpa
->valoffset
= 0;
462 while((cp
= cp
->next
) != NULL
);
465 saved_screen
= opt_screen
;
466 memset(&screen
, 0, sizeof(screen
));
467 screen
.ro_warning
= readonly_warning
;
468 (void) conf_scroll_screen(ps
, &screen
, first_line
, cs
->title
,
469 cs
->print_string
, 0, NULL
);
470 opt_screen
= saved_screen
;
471 ps
->mangled_screen
= 1;
472 return(cs
->selected
);
477 context_config_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
483 if(!fixed_var((*cl
)->var
, "delete", "collection"))
484 retval
= context_config_delete(ps
, cl
);
489 if(!fixed_var((*cl
)->var
, "change", "collection"))
490 retval
= context_config_edit(ps
, cl
);
495 if(!fixed_var((*cl
)->var
, "add to", "collection"))
496 retval
= context_config_add(ps
, cl
);
501 if(!fixed_var((*cl
)->var
, "shuffle", "collection"))
502 retval
= context_config_shuffle(ps
, cl
);
507 retval
= simple_exit_cmd(flags
);
516 ps
->mangled_body
= 1;
523 context_config_add(struct pine
*ps
, CONF_S
**cl
)
526 struct variable
*var
;
530 if((raw_ctxt
= context_edit_screen(ps
, "ADD", NULL
, NULL
, NULL
, NULL
)) != NULL
){
533 * If var is non-NULL we add to the end of that var.
534 * If it is NULL, that means we're adding to the current_val, so
535 * we'll have to soak up the default values from there into our
540 lval
= LVAL((*cl
)->var
, ew
);
543 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
544 "Programmer botch in context_config_add");
548 for(count
= 0; lval
&& lval
[count
]; count
++)
551 if(!ccs_var_insert(ps
, raw_ctxt
, var
, lval
, count
)){
552 fs_give((void **)&raw_ctxt
);
553 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
554 _("Error adding new collection"));
558 fs_give((void **)&raw_ctxt
);
560 (*cl
)->d
.c
.cs
->starting_var
= var
;
561 (*cl
)->d
.c
.cs
->starting_varmem
= count
;
562 q_status_message(SM_ORDER
, 0, 3,
563 _("New collection added. Use \"$\" to adjust order."));
567 ps
->mangled_screen
= 1;
573 context_config_shuffle(struct pine
*ps
, CONF_S
**cl
)
576 int n
= 0, cmd
, i1
, i2
, count
= 0, insert_num
, starting_varmem
;
577 int news_problem
= 0, deefault
= 0;
579 CONTEXT_S
*cur_ctxt
, *other_ctxt
= NULL
;
580 char *tmp
, **lval
, **lval1
, **lval2
;
581 struct variable
*cur_var
, *other_var
;
583 if(!((*cl
)->d
.c
.ct
&& (*cl
)->var
))
587 if((*cl
)->d
.c
.ct
->prev
&& !((*cl
)->d
.c
.ct
->prev
->use
& CNTXT_INHERIT
)){
589 * Don't allow shuffling news collection up to become
590 * the primary collection. That would happen if prev is primary
591 * and this one is news.
593 if((*cl
)->d
.c
.ct
->prev
->use
& CNTXT_SAVEDFLT
&&
594 (*cl
)->d
.c
.ct
->use
& CNTXT_NEWS
)
600 ekey
[n
++].label
= N_("Up");
606 if((*cl
)->d
.c
.ct
->next
&& !((*cl
)->d
.c
.ct
->next
->use
& CNTXT_INHERIT
)){
608 * Don't allow shuffling down past news collection if this
609 * is primary collection.
611 if((*cl
)->d
.c
.ct
->use
& CNTXT_SAVEDFLT
&&
612 (*cl
)->d
.c
.ct
->next
->use
& CNTXT_NEWS
)
618 ekey
[n
++].label
= N_("Down");
626 snprintf(prompt
, sizeof(prompt
), _("Shuffle selected context %s%s%s? "),
627 (ekey
[0].ch
== 'u') ? _("UP") : "",
628 (n
> 1) ? " or " : "",
629 (ekey
[0].ch
== 'd' || n
> 1) ? _("DOWN") : "");
630 prompt
[sizeof(prompt
)-1] = '\0';
632 cmd
= radio_buttons(prompt
, -FOOTER_ROWS(ps
), ekey
,
633 deefault
, 'x', NO_HELP
, RB_NORM
);
637 cmd_cancelled("Shuffle");
646 * This is complicated by the fact that there are two
647 * vars involved, the folder-collections and the news-collections.
648 * We may have to shuffle across collections.
650 cur_ctxt
= (*cl
)->d
.c
.ct
;
652 other_ctxt
= (*cl
)->d
.c
.ct
->next
;
654 other_ctxt
= (*cl
)->d
.c
.ct
->prev
;
656 cur_var
= cur_ctxt
->var
.v
;
657 other_var
= other_ctxt
->var
.v
;
659 /* swap elements of config var */
660 if(cur_var
== other_var
){
661 i1
= cur_ctxt
->var
.i
;
662 i2
= other_ctxt
->var
.i
;
663 lval
= LVAL(cur_var
, ew
);
670 starting_varmem
= i2
;
673 /* swap into the other_var */
674 i1
= cur_ctxt
->var
.i
;
675 i2
= other_ctxt
->var
.i
;
676 lval1
= LVAL(cur_var
, ew
);
677 lval2
= LVAL(other_var
, ew
);
679 for(count
= 0; lval2
&& lval2
[count
]; count
++)
682 insert_num
= count
? 1 : 0;
684 insert_num
= count
? count
- 1 : count
;
687 starting_varmem
= insert_num
;
688 if(ccs_var_insert(ps
,lval1
[i1
],other_var
,lval2
,insert_num
)){
689 if(!ccs_var_delete(ps
, cur_ctxt
)){
690 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
691 _("Error deleting shuffled context"));
696 q_status_message(SM_ORDER
, 3, 3,
697 _("Trouble shuffling, cancelled"));
702 (*cl
)->d
.c
.cs
->starting_var
= other_var
;
703 (*cl
)->d
.c
.cs
->starting_varmem
= starting_varmem
;
705 q_status_message(SM_ORDER
, 0, 3, _("Collections shuffled"));
710 /* TRANSLATORS: Sorry, can't move news group collections above email collections */
711 q_status_message(SM_ORDER
, 0, 3, _("Sorry, cannot Shuffle news to top"));
713 q_status_message(SM_ORDER
, 0, 3, _("Sorry, nothing to Shuffle"));
720 context_config_edit(struct pine
*ps
, CONF_S
**cl
)
722 char *raw_ctxt
, tpath
[MAILTMPLEN
], *p
, **lval
;
723 struct variable
*var
;
729 /* Undigest the context */
730 strncpy(tpath
, ((*cl
)->d
.c
.ct
->context
[0] == '{'
731 && (p
= strchr((*cl
)->d
.c
.ct
->context
, '}')))
733 : (*cl
)->d
.c
.ct
->context
, sizeof(tpath
)-1);
734 tpath
[sizeof(tpath
)-1] = '\0';
736 if((p
= strstr(tpath
, "%s")) != NULL
)
739 if((raw_ctxt
= context_edit_screen(ps
, "EDIT", (*cl
)->d
.c
.ct
->nickname
,
740 (*cl
)->d
.c
.ct
->server
, tpath
,
742 (*cl
)->d
.c
.ct
->dir
->view
.user
747 lval
= LVAL(var
, ew
);
748 i
= (*cl
)->d
.c
.ct
->var
.i
;
750 if(lval
&& lval
[i
] && !strcmp(lval
[i
], raw_ctxt
))
751 q_status_message(SM_ORDER
, 0, 3, _("No change"));
754 fs_give((void **) &lval
[i
]);
759 q_status_message(SM_ORDER
, 0, 3, _("Collection list entry updated"));
762 (*cl
)->d
.c
.cs
->starting_var
= var
;
763 (*cl
)->d
.c
.cs
->starting_varmem
= i
;
766 fs_give((void **) &raw_ctxt
);
769 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
770 "Programmer botch in context_config_edit");
777 ps
->mangled_screen
= 1;
783 context_config_delete(struct pine
*ps
, CONF_S
**cl
)
785 char tmp
[MAILTMPLEN
];
788 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
789 "Programmer botch in context_config_delete");
793 if((*cl
)->d
.c
.ct
->use
& CNTXT_SAVEDFLT
&&
794 (*cl
)->d
.c
.ct
->next
&&
795 (*cl
)->d
.c
.ct
->next
->use
& CNTXT_NEWS
&&
796 (*cl
)->d
.c
.ct
->var
.v
== (*cl
)->d
.c
.ct
->next
->var
.v
){
797 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
798 _("Sorry, cannot Delete causing news to move to top"));
802 snprintf(tmp
, sizeof(tmp
), _("Delete the collection definition for \"%s\""),
804 tmp
[sizeof(tmp
)-1] = '\0';
805 if(want_to(tmp
, 'n', 'n', NO_HELP
, WT_FLUSH_IN
) == 'y'){
807 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->var
;
808 (*cl
)->d
.c
.cs
->starting_varmem
= (*cl
)->d
.c
.ct
->var
.i
;
809 if((*cl
)->d
.c
.ct
->next
){
810 if((*cl
)->d
.c
.ct
->next
->var
.v
!= (*cl
)->var
){
811 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->d
.c
.ct
->next
->var
.v
;
812 (*cl
)->d
.c
.cs
->starting_varmem
= 0;
815 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->var
;
816 (*cl
)->d
.c
.cs
->starting_varmem
= (*cl
)->d
.c
.ct
->var
.i
;
820 if((*cl
)->d
.c
.ct
->var
.i
> 0){
821 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->var
;
822 (*cl
)->d
.c
.cs
->starting_varmem
= (*cl
)->d
.c
.ct
->var
.i
- 1;
825 if((*cl
)->d
.c
.ct
->prev
){
826 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->d
.c
.ct
->prev
->var
.v
;
827 (*cl
)->d
.c
.cs
->starting_varmem
= (*cl
)->d
.c
.ct
->prev
->var
.i
;
832 /* Remove from var list */
833 if(!ccs_var_delete(ps
, (*cl
)->d
.c
.ct
)){
834 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
835 _("Error deleting renamed context"));
839 q_status_message(SM_ORDER
, 0, 3, _("Collection deleted"));
844 q_status_message(SM_ORDER
, 0, 3, _("No collections deleted"));
850 ccs_var_delete(struct pine
*ps
, CONTEXT_S
*ctxt
)
853 char **newl
= NULL
, **lval
, **lp
, ***alval
;
856 lval
= LVAL(ctxt
->var
.v
, ew
);
860 for(count
= 0; lval
&& lval
[count
]; count
++)
864 newl
= (char **) fs_get(count
* sizeof(char *));
865 for(i
= 0, lp
= newl
; lval
[i
]; i
++)
867 *lp
++ = cpystr(lval
[i
]);
872 alval
= ALVAL(ctxt
->var
.v
, ew
);
874 free_list_array(alval
);
876 for(i
= 0; newl
[i
] ; i
++) /* count elements */
879 *alval
= (char **) fs_get((i
+1) * sizeof(char *));
881 for(i
= 0; newl
[i
] ; i
++)
882 (*alval
)[i
] = cpystr(newl
[i
]);
888 free_list_array(&newl
);
894 * Insert into "var", which currently has values "oldvarval", the "newline"
895 * at position "insert".
898 ccs_var_insert(struct pine
*ps
, char *newline
, struct variable
*var
, char **oldvarval
, int insert
)
900 int count
, i
, offset
;
901 char **newl
, ***alval
;
903 for(count
= 0; oldvarval
&& oldvarval
[count
]; count
++)
906 if(insert
< 0 || insert
> count
){
907 q_status_message(SM_ORDER
,3,5, "unexpected problem inserting folder");
911 newl
= (char **)fs_get((count
+ 2) * sizeof(char *));
912 newl
[insert
] = cpystr(newline
);
913 newl
[count
+ 1] = NULL
;
914 for(i
= offset
= 0; oldvarval
&& oldvarval
[i
]; i
++){
918 newl
[i
+ offset
] = cpystr(oldvarval
[i
]);
921 alval
= ALVAL(var
, ew
);
923 free_list_array(alval
);
925 for(i
= 0; newl
[i
] ; i
++) /* count elements */
928 *alval
= (char **) fs_get((i
+1) * sizeof(char *));
930 for(i
= 0; newl
[i
] ; i
++)
931 (*alval
)[i
] = cpystr(newl
[i
]);
937 free_list_array(&newl
);
943 context_select_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
949 (*cl
)->d
.c
.cs
->selected
= (*cl
)->d
.c
.ct
;
950 retval
= simple_exit_cmd(flags
);
954 retval
= simple_exit_cmd(flags
);
958 retval
= simple_exit_cmd(flags
);
959 ps_global
->next_screen
= main_menu_screen
;
964 && sp_viewing_a_thread(ps_global
->mail_stream
)
965 && unview_thread(ps_global
, ps_global
->mail_stream
, ps_global
->msgmap
)){
966 ps_global
->next_screen
= mail_index_screen
;
967 ps_global
->view_skipped_index
= 0;
968 ps_global
->mangled_screen
= 1;
971 retval
= simple_exit_cmd(flags
);
972 ps_global
->next_screen
= mail_index_screen
;
976 retval
= simple_exit_cmd(flags
);
977 ps_global
->next_screen
= compose_screen
;
981 retval
= simple_exit_cmd(flags
);
982 ps_global
->next_screen
= alt_compose_screen
;
988 CONTEXT_S
*c
= (*cl
)->d
.c
.ct
;
989 char *new_fold
= broach_folder(-FOOTER_ROWS(ps
), 0, ¬realinbox
, &c
);
991 if(new_fold
&& do_broach_folder(new_fold
, c
, NULL
, notrealinbox
? 0L : DB_INBOXWOCNTXT
) > 0){
992 ps_global
->next_screen
= mail_index_screen
;
993 retval
= simple_exit_cmd(flags
);
996 ps
->mangled_footer
= 1;
1002 retval
= simple_exit_cmd(flags
);
1003 ps_global
->next_screen
= quit_screen
;
1012 ps
->mangled_body
= 1;