1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: context.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2015 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
21 #include "confscroll.h"
29 #include "../pith/list.h"
30 #include "../pith/state.h"
31 #include "../pith/conf.h"
32 #include "../pith/thread.h"
38 int context_config_tool(struct pine
*, int, CONF_S
**, unsigned);
39 int context_config_add(struct pine
*, CONF_S
**);
40 int context_config_shuffle(struct pine
*, CONF_S
**);
41 int context_config_edit(struct pine
*, CONF_S
**);
42 int context_config_delete(struct pine
*, CONF_S
**);
43 int ccs_var_delete(struct pine
*, CONTEXT_S
*);
44 int ccs_var_insert(struct pine
*, char *, struct variable
*, char **, int);
45 int context_select_tool(struct pine
*, int, CONF_S
**, unsigned);
49 * Setup CollectionLists. Build a context list on the fly from the config
50 * variable and edit it. This won't include Incoming-Folders because that
51 * is a pseudo collection, but that's ok since we can't do the operations
52 * on it, anyway. Reset real config list at the end.
55 context_config_screen(struct pine
*ps
, CONT_SCR_S
*cs
, int edit_exceptions
)
57 CONTEXT_S
*top
, **clist
, *cp
;
58 CONF_S
*ctmpa
, *first_line
, *heading
;
60 int i
, readonly_warning
, some_defined
, ret
;
61 int reinit_contexts
= 0, prime
;
62 char **lval
, **lval1
, **lval2
, ***alval
;
63 struct variable fake_fspec_var
, fake_nspec_var
;
64 struct variable
*fake_fspec
, *fake_nspec
;
66 ew
= edit_exceptions
? ps_global
->ew_for_except_vars
: Main
;
84 readonly_warning
= prc
? prc
->readonly
: 1;
85 if(prc
&& prc
->quit_to_edit
){
86 quit_to_edit_msg(prc
);
92 top
= NULL
; ctmpa
= NULL
; first_line
= NULL
;
93 some_defined
= 0, prime
= 0;
94 fake_fspec
= &fake_fspec_var
;
95 fake_nspec
= &fake_nspec_var
;
96 memset((void *)fake_fspec
, 0, sizeof(*fake_fspec
));
97 memset((void *)fake_nspec
, 0, sizeof(*fake_nspec
));
99 /* so fixed_var() will work right */
100 fake_fspec
->is_list
= 1;
101 fake_nspec
->is_list
= 1;
102 if((ps
->vars
[V_FOLDER_SPEC
]).is_fixed
){
103 fake_fspec
->is_fixed
= 1;
104 if((ps
->vars
[V_FOLDER_SPEC
]).fixed_val
.l
105 && (ps
->vars
[V_FOLDER_SPEC
]).fixed_val
.l
[0]){
106 fake_fspec
->fixed_val
.l
= (char **) fs_get(2 * sizeof(char *));
107 fake_fspec
->fixed_val
.l
[0]
108 = cpystr((ps
->vars
[V_FOLDER_SPEC
]).fixed_val
.l
[0]);
109 fake_fspec
->fixed_val
.l
[1] = NULL
;
113 if((ps
->vars
[V_NEWS_SPEC
]).is_fixed
){
114 fake_nspec
->is_fixed
= 1;
115 if((ps
->vars
[V_NEWS_SPEC
]).fixed_val
.l
116 && (ps
->vars
[V_NEWS_SPEC
]).fixed_val
.l
[0]){
117 fake_nspec
->fixed_val
.l
= (char **) fs_get(2 * sizeof(char *));
118 fake_nspec
->fixed_val
.l
[0] = cpystr(INHERIT
);
119 fake_nspec
->fixed_val
.l
[0]
120 = cpystr((ps
->vars
[V_NEWS_SPEC
]).fixed_val
.l
[0]);
121 fake_nspec
->fixed_val
.l
[1] = NULL
;
126 lval1
= LVAL(&ps
->vars
[V_FOLDER_SPEC
], ew
);
127 lval2
= LVAL(&ps
->vars
[V_NEWS_SPEC
], ew
);
129 alval
= ALVAL(fake_fspec
, ew
);
131 *alval
= copy_list_array(lval1
);
132 else if(!edit_exceptions
&& ps
->VAR_FOLDER_SPEC
&& ps
->VAR_FOLDER_SPEC
[0] &&
133 ps
->VAR_FOLDER_SPEC
[0][0])
134 *alval
= copy_list_array(ps
->VAR_FOLDER_SPEC
);
139 lval
= LVAL(fake_fspec
, ew
);
140 for(i
= 0; lval
&& lval
[i
]; i
++){
142 if(i
== 0 && !strcmp(lval
[i
], INHERIT
)){
143 cp
= (CONTEXT_S
*)fs_get(sizeof(*cp
));
144 memset((void *)cp
, 0, sizeof(*cp
));
145 cp
->use
= CNTXT_INHERIT
;
146 cp
->label
= cpystr("Default collections are inherited");
148 else if((cp
= new_context(lval
[i
], &prime
)) != NULL
){
149 cp
->var
.v
= fake_fspec
;
154 *clist
= cp
; /* add it to list */
155 clist
= &cp
->next
; /* prepare for next */
159 set_current_val(fake_fspec
, FALSE
, FALSE
);
162 alval
= ALVAL(fake_nspec
, ew
);
164 *alval
= copy_list_array(lval2
);
165 else if(!edit_exceptions
&& ps
->VAR_NEWS_SPEC
&& ps
->VAR_NEWS_SPEC
[0] &&
166 ps
->VAR_NEWS_SPEC
[0][0])
167 *alval
= copy_list_array(ps
->VAR_NEWS_SPEC
);
172 lval
= LVAL(fake_nspec
, ew
);
173 for(i
= 0; lval
&& lval
[i
]; i
++){
175 if(i
== 0 && !strcmp(lval
[i
], INHERIT
)){
176 cp
= (CONTEXT_S
*)fs_get(sizeof(*cp
));
177 memset((void *)cp
, 0, sizeof(*cp
));
178 cp
->use
= CNTXT_INHERIT
;
179 cp
->label
= cpystr("Default collections are inherited");
181 else if((cp
= new_context(lval
[i
], &prime
)) != NULL
){
182 cp
->var
.v
= fake_nspec
;
187 *clist
= cp
; /* add it to list */
188 clist
= &cp
->next
; /* prepare for next */
192 set_current_val(fake_nspec
, FALSE
, FALSE
);
195 for(cp
= top
; cp
; cp
= cp
->next
)
196 if(!(cp
->use
& CNTXT_INHERIT
)){
201 if(edit_exceptions
&& !some_defined
){
202 q_status_message(SM_ORDER
, 3, 7,
203 _("No exceptions to edit. First collection exception must be set by editing file"));
206 free_contexts(&ps_global
->context_list
);
207 init_folders(ps_global
);
214 /* fix up prev pointers */
215 for(cp
= top
; cp
; cp
= cp
->next
)
219 new_confline(&ctmpa
); /* blank line */
220 ctmpa
->keymenu
= cs
->keymenu
;
221 ctmpa
->help
= cs
->help
.text
;
222 ctmpa
->help_title
= cs
->help
.title
;
223 ctmpa
->tool
= context_config_tool
;
224 ctmpa
->flags
|= (CF_NOSELECT
| CF_B_LINE
);
226 for(cp
= top
; cp
; cp
= cp
->next
){
227 new_confline(&ctmpa
);
229 if(!(cp
->use
& CNTXT_INHERIT
))
230 ctmpa
->value
= cpystr(cp
->nickname
? cp
->nickname
: cp
->context
);
232 ctmpa
->var
= cp
->var
.v
;
233 ctmpa
->keymenu
= cs
->keymenu
;
234 ctmpa
->help
= cs
->help
.text
;
235 ctmpa
->help_title
= cs
->help
.title
;
236 ctmpa
->tool
= context_config_tool
;
237 ctmpa
->flags
|= CF_STARTITEM
;
238 ctmpa
->valoffset
= 4;
241 if(cp
->use
& CNTXT_INHERIT
)
242 ctmpa
->flags
|= CF_INHERIT
| CF_NOSELECT
;
244 if((!first_line
&& !(cp
->use
& CNTXT_INHERIT
)) ||
245 (!(cp
->use
& CNTXT_INHERIT
) &&
247 (cs
->starting_var
== cp
->var
.v
) &&
248 (cs
->starting_varmem
== cp
->var
.i
)))
251 /* Add explanatory text */
252 new_confline(&ctmpa
);
253 ctmpa
->value
= cpystr(cp
->label
? cp
->label
: "* * *");
254 ctmpa
->keymenu
= cs
->keymenu
;
255 ctmpa
->help
= cs
->help
.text
;
256 ctmpa
->help_title
= cs
->help
.title
;
257 ctmpa
->tool
= context_config_tool
;
258 ctmpa
->flags
|= CF_NOSELECT
;
259 ctmpa
->valoffset
= 8;
261 /* Always add blank line, make's shuffling a little easier */
262 new_confline(&ctmpa
);
263 heading
->headingp
= ctmpa
; /* use headingp to mark end */
264 ctmpa
->keymenu
= cs
->keymenu
;
265 ctmpa
->help
= cs
->help
.text
;
266 ctmpa
->help_title
= cs
->help
.title
;
267 ctmpa
->tool
= context_config_tool
;
268 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
269 ctmpa
->valoffset
= 0;
272 cs
->starting_var
= NULL
;
275 memset(&screen
, 0, sizeof(screen
));
276 screen
.ro_warning
= readonly_warning
;
277 ret
= conf_scroll_screen(ps
, &screen
, first_line
, cs
->title
,
278 cs
->print_string
, 0, NULL
);
286 * 15 means the tool wants us to reset and go again. The config var
287 * has been changed. The contexts will be built again from the
288 * config variable and the real contexts will be rebuilt below.
289 * This is easier and safer than having the tools rebuild the context
290 * list and the display correct. It's difficult to do because of all
291 * the inheriting and defaulting going on.
294 if(edit_exceptions
&& !LVAL(fake_fspec
, ew
) && !LVAL(fake_nspec
, ew
)){
295 if(want_to(_("Really delete last exceptional collection"),
296 'n', 'n', h_config_context_del_except
,
297 WT_FLUSH_IN
) != 'y'){
298 free_variable_values(fake_fspec
);
299 free_variable_values(fake_nspec
);
304 /* resolve variable changes */
305 if((lval1
&& !equal_list_arrays(lval1
, LVAL(fake_fspec
, ew
))) ||
306 (fake_fspec
&& !equal_list_arrays(ps
->VAR_FOLDER_SPEC
,
307 LVAL(fake_fspec
, ew
)))){
308 i
= set_variable_list(V_FOLDER_SPEC
,
309 LVAL(fake_fspec
, ew
), TRUE
, ew
);
310 set_current_val(&ps
->vars
[V_FOLDER_SPEC
], TRUE
, FALSE
);
313 q_status_message(SM_ORDER
, 3, 3,
314 _("Trouble saving change, cancelled"));
315 else if(!edit_exceptions
&& lval1
&& !LVAL(fake_fspec
, ew
)){
316 cs
->starting_var
= fake_fspec
;
317 cs
->starting_varmem
= 0;
318 q_status_message(SM_ORDER
, 3, 3,
319 _("Deleted last Folder-Collection, reverting to default"));
321 else if(!edit_exceptions
&& !lval1
&& !LVAL(fake_fspec
, ew
)){
322 cs
->starting_var
= fake_fspec
;
323 cs
->starting_varmem
= 0;
324 q_status_message(SM_ORDER
, 3, 3,
325 _("Deleted default Folder-Collection, reverting back to default"));
329 if((lval2
&& !equal_list_arrays(lval2
, LVAL(fake_nspec
, ew
))) ||
330 (fake_nspec
&& !equal_list_arrays(ps
->VAR_NEWS_SPEC
,
331 LVAL(fake_nspec
, ew
)))){
332 i
= set_variable_list(V_NEWS_SPEC
,
333 LVAL(fake_nspec
, ew
), TRUE
, ew
);
334 set_news_spec_current_val(TRUE
, FALSE
);
337 q_status_message(SM_ORDER
, 3, 3,
338 _("Trouble saving change, cancelled"));
339 else if(!edit_exceptions
&& lval2
&& !LVAL(fake_nspec
, ew
) &&
340 ps
->VAR_NEWS_SPEC
&& ps
->VAR_NEWS_SPEC
[0] &&
341 ps
->VAR_NEWS_SPEC
[0][0]){
342 cs
->starting_var
= fake_nspec
;
343 cs
->starting_varmem
= 0;
344 q_status_message(SM_ORDER
, 3, 3,
345 _("Deleted last News-Collection, reverting to default"));
347 else if(!edit_exceptions
&& !lval2
&& !LVAL(fake_nspec
, ew
) &&
348 ps
->VAR_NEWS_SPEC
&& ps
->VAR_NEWS_SPEC
[0] &&
349 ps
->VAR_NEWS_SPEC
[0][0]){
350 cs
->starting_var
= fake_nspec
;
351 cs
->starting_varmem
= 0;
352 q_status_message(SM_ORDER
, 3, 3,
353 _("Deleted default News-Collection, reverting back to default"));
357 free_variable_values(fake_fspec
);
358 free_variable_values(fake_nspec
);
362 ps
->mangled_screen
= 1;
364 /* make the real context list match the changed config variables */
366 free_contexts(&ps_global
->context_list
);
367 init_folders(ps_global
);
372 /*----------------------------------------------------------------------
373 Function to display/manage collections
377 context_select_screen(struct pine
*ps
, CONT_SCR_S
*cs
, int ro_warn
)
380 CONF_S
*ctmpa
= NULL
, *first_line
= NULL
, *heading
;
381 OPT_SCREEN_S screen
, *saved_screen
;
382 int readonly_warning
= 0;
384 /* restrict to normal config */
388 readonly_warning
= 0;
389 else if(ps
->restricted
)
390 readonly_warning
= 1;
392 PINERC_S
*prc
= NULL
;
405 readonly_warning
= prc
? prc
->readonly
: 1;
406 if(ro_warn
&& prc
&& prc
->quit_to_edit
){
407 quit_to_edit_msg(prc
);
412 readonly_warning
*= ro_warn
;
415 * Loop thru available contexts, setting up for display
416 * (note: if no "cp" we're hosed. should never happen ;)
418 for(cp
= *cs
->contexts
; cp
->prev
; cp
= cp
->prev
)
421 /* delimiter for Mail Collections */
422 new_confline(&ctmpa
); /* blank line */
423 ctmpa
->keymenu
= cs
->keymenu
;
424 ctmpa
->help
= cs
->help
.text
;
425 ctmpa
->help_title
= cs
->help
.title
;
426 ctmpa
->tool
= context_select_tool
;
427 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
430 new_confline(&ctmpa
);
432 ctmpa
->value
= cpystr(cp
->nickname
? cp
->nickname
: cp
->context
);
433 ctmpa
->var
= cp
->var
.v
;
434 ctmpa
->keymenu
= cs
->keymenu
;
435 ctmpa
->help
= cs
->help
.text
;
436 ctmpa
->help_title
= cs
->help
.title
;
437 ctmpa
->tool
= context_select_tool
;
438 ctmpa
->flags
|= CF_STARTITEM
;
439 ctmpa
->valoffset
= 4;
443 if(!first_line
|| cp
== cs
->start
)
446 /* Add explanatory text */
447 new_confline(&ctmpa
);
448 ctmpa
->value
= cpystr(cp
->label
? cp
->label
: "* * *");
449 ctmpa
->keymenu
= cs
->keymenu
;
450 ctmpa
->help
= cs
->help
.text
;
451 ctmpa
->help_title
= cs
->help
.title
;
452 ctmpa
->tool
= context_select_tool
;
453 ctmpa
->flags
|= CF_NOSELECT
;
454 ctmpa
->valoffset
= 8;
456 /* Always add blank line, make's shuffling a little easier */
457 new_confline(&ctmpa
);
458 heading
->headingp
= ctmpa
;
459 ctmpa
->keymenu
= cs
->keymenu
;
460 ctmpa
->help
= cs
->help
.text
;
461 ctmpa
->help_title
= cs
->help
.title
;
462 ctmpa
->tool
= context_select_tool
;
463 ctmpa
->flags
|= CF_NOSELECT
| CF_B_LINE
;
464 ctmpa
->valoffset
= 0;
466 while((cp
= cp
->next
) != NULL
);
469 saved_screen
= opt_screen
;
470 memset(&screen
, 0, sizeof(screen
));
471 screen
.ro_warning
= readonly_warning
;
472 (void) conf_scroll_screen(ps
, &screen
, first_line
, cs
->title
,
473 cs
->print_string
, 0, NULL
);
474 opt_screen
= saved_screen
;
475 ps
->mangled_screen
= 1;
476 return(cs
->selected
);
481 context_config_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
487 if(!fixed_var((*cl
)->var
, "delete", "collection"))
488 retval
= context_config_delete(ps
, cl
);
493 if(!fixed_var((*cl
)->var
, "change", "collection"))
494 retval
= context_config_edit(ps
, cl
);
499 if(!fixed_var((*cl
)->var
, "add to", "collection"))
500 retval
= context_config_add(ps
, cl
);
505 if(!fixed_var((*cl
)->var
, "shuffle", "collection"))
506 retval
= context_config_shuffle(ps
, cl
);
511 retval
= simple_exit_cmd(flags
);
520 ps
->mangled_body
= 1;
527 context_config_add(struct pine
*ps
, CONF_S
**cl
)
530 struct variable
*var
;
534 if((raw_ctxt
= context_edit_screen(ps
, "ADD", NULL
, NULL
, NULL
, NULL
)) != NULL
){
537 * If var is non-NULL we add to the end of that var.
538 * If it is NULL, that means we're adding to the current_val, so
539 * we'll have to soak up the default values from there into our
544 lval
= LVAL((*cl
)->var
, ew
);
547 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
548 "Programmer botch in context_config_add");
552 for(count
= 0; lval
&& lval
[count
]; count
++)
555 if(!ccs_var_insert(ps
, raw_ctxt
, var
, lval
, count
)){
556 fs_give((void **)&raw_ctxt
);
557 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
558 _("Error adding new collection"));
562 fs_give((void **)&raw_ctxt
);
564 (*cl
)->d
.c
.cs
->starting_var
= var
;
565 (*cl
)->d
.c
.cs
->starting_varmem
= count
;
566 q_status_message(SM_ORDER
, 0, 3,
567 _("New collection added. Use \"$\" to adjust order."));
571 ps
->mangled_screen
= 1;
577 context_config_shuffle(struct pine
*ps
, CONF_S
**cl
)
580 int n
= 0, cmd
, i1
, i2
, count
= 0, insert_num
, starting_varmem
;
581 int news_problem
= 0, deefault
= 0;
583 CONTEXT_S
*cur_ctxt
, *other_ctxt
;
584 char *tmp
, **lval
, **lval1
, **lval2
;
585 struct variable
*cur_var
, *other_var
;
587 if(!((*cl
)->d
.c
.ct
&& (*cl
)->var
))
591 if((*cl
)->d
.c
.ct
->prev
&& !((*cl
)->d
.c
.ct
->prev
->use
& CNTXT_INHERIT
)){
593 * Don't allow shuffling news collection up to become
594 * the primary collection. That would happen if prev is primary
595 * and this one is news.
597 if((*cl
)->d
.c
.ct
->prev
->use
& CNTXT_SAVEDFLT
&&
598 (*cl
)->d
.c
.ct
->use
& CNTXT_NEWS
)
604 ekey
[n
++].label
= N_("Up");
610 if((*cl
)->d
.c
.ct
->next
&& !((*cl
)->d
.c
.ct
->next
->use
& CNTXT_INHERIT
)){
612 * Don't allow shuffling down past news collection if this
613 * is primary collection.
615 if((*cl
)->d
.c
.ct
->use
& CNTXT_SAVEDFLT
&&
616 (*cl
)->d
.c
.ct
->next
->use
& CNTXT_NEWS
)
622 ekey
[n
++].label
= N_("Down");
630 snprintf(prompt
, sizeof(prompt
), _("Shuffle selected context %s%s%s? "),
631 (ekey
[0].ch
== 'u') ? _("UP") : "",
632 (n
> 1) ? " or " : "",
633 (ekey
[0].ch
== 'd' || n
> 1) ? _("DOWN") : "");
634 prompt
[sizeof(prompt
)-1] = '\0';
636 cmd
= radio_buttons(prompt
, -FOOTER_ROWS(ps
), ekey
,
637 deefault
, 'x', NO_HELP
, RB_NORM
);
641 cmd_cancelled("Shuffle");
650 * This is complicated by the fact that there are two
651 * vars involved, the folder-collections and the news-collections.
652 * We may have to shuffle across collections.
654 cur_ctxt
= (*cl
)->d
.c
.ct
;
656 other_ctxt
= (*cl
)->d
.c
.ct
->next
;
658 other_ctxt
= (*cl
)->d
.c
.ct
->prev
;
660 cur_var
= cur_ctxt
->var
.v
;
661 other_var
= other_ctxt
->var
.v
;
663 /* swap elements of config var */
664 if(cur_var
== other_var
){
665 i1
= cur_ctxt
->var
.i
;
666 i2
= other_ctxt
->var
.i
;
667 lval
= LVAL(cur_var
, ew
);
674 starting_varmem
= i2
;
677 /* swap into the other_var */
678 i1
= cur_ctxt
->var
.i
;
679 i2
= other_ctxt
->var
.i
;
680 lval1
= LVAL(cur_var
, ew
);
681 lval2
= LVAL(other_var
, ew
);
683 for(count
= 0; lval2
&& lval2
[count
]; count
++)
686 insert_num
= count
? 1 : 0;
688 insert_num
= count
? count
- 1 : count
;
691 starting_varmem
= insert_num
;
692 if(ccs_var_insert(ps
,lval1
[i1
],other_var
,lval2
,insert_num
)){
693 if(!ccs_var_delete(ps
, cur_ctxt
)){
694 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
695 _("Error deleting shuffled context"));
700 q_status_message(SM_ORDER
, 3, 3,
701 _("Trouble shuffling, cancelled"));
706 (*cl
)->d
.c
.cs
->starting_var
= other_var
;
707 (*cl
)->d
.c
.cs
->starting_varmem
= starting_varmem
;
709 q_status_message(SM_ORDER
, 0, 3, _("Collections shuffled"));
714 /* TRANSLATORS: Sorry, can't move news group collections above email collections */
715 q_status_message(SM_ORDER
, 0, 3, _("Sorry, cannot Shuffle news to top"));
717 q_status_message(SM_ORDER
, 0, 3, _("Sorry, nothing to Shuffle"));
724 context_config_edit(struct pine
*ps
, CONF_S
**cl
)
726 char *raw_ctxt
, tpath
[MAILTMPLEN
], *p
, **lval
;
727 struct variable
*var
;
733 /* Undigest the context */
734 strncpy(tpath
, ((*cl
)->d
.c
.ct
->context
[0] == '{'
735 && (p
= strchr((*cl
)->d
.c
.ct
->context
, '}')))
737 : (*cl
)->d
.c
.ct
->context
, sizeof(tpath
)-1);
738 tpath
[sizeof(tpath
)-1] = '\0';
740 if((p
= strstr(tpath
, "%s")) != NULL
)
743 if((raw_ctxt
= context_edit_screen(ps
, "EDIT", (*cl
)->d
.c
.ct
->nickname
,
744 (*cl
)->d
.c
.ct
->server
, tpath
,
746 (*cl
)->d
.c
.ct
->dir
->view
.user
751 lval
= LVAL(var
, ew
);
752 i
= (*cl
)->d
.c
.ct
->var
.i
;
754 if(lval
&& lval
[i
] && !strcmp(lval
[i
], raw_ctxt
))
755 q_status_message(SM_ORDER
, 0, 3, _("No change"));
758 fs_give((void **) &lval
[i
]);
763 q_status_message(SM_ORDER
, 0, 3, _("Collection list entry updated"));
766 (*cl
)->d
.c
.cs
->starting_var
= var
;
767 (*cl
)->d
.c
.cs
->starting_varmem
= i
;
770 fs_give((void **) &raw_ctxt
);
773 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
774 "Programmer botch in context_config_edit");
781 ps
->mangled_screen
= 1;
787 context_config_delete(struct pine
*ps
, CONF_S
**cl
)
789 char tmp
[MAILTMPLEN
];
792 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
793 "Programmer botch in context_config_delete");
797 if((*cl
)->d
.c
.ct
->use
& CNTXT_SAVEDFLT
&&
798 (*cl
)->d
.c
.ct
->next
&&
799 (*cl
)->d
.c
.ct
->next
->use
& CNTXT_NEWS
&&
800 (*cl
)->d
.c
.ct
->var
.v
== (*cl
)->d
.c
.ct
->next
->var
.v
){
801 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
802 _("Sorry, cannot Delete causing news to move to top"));
806 snprintf(tmp
, sizeof(tmp
), _("Delete the collection definition for \"%s\""),
808 tmp
[sizeof(tmp
)-1] = '\0';
809 if(want_to(tmp
, 'n', 'n', NO_HELP
, WT_FLUSH_IN
) == 'y'){
811 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->var
;
812 (*cl
)->d
.c
.cs
->starting_varmem
= (*cl
)->d
.c
.ct
->var
.i
;
813 if((*cl
)->d
.c
.ct
->next
){
814 if((*cl
)->d
.c
.ct
->next
->var
.v
!= (*cl
)->var
){
815 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->d
.c
.ct
->next
->var
.v
;
816 (*cl
)->d
.c
.cs
->starting_varmem
= 0;
819 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->var
;
820 (*cl
)->d
.c
.cs
->starting_varmem
= (*cl
)->d
.c
.ct
->var
.i
;
824 if((*cl
)->d
.c
.ct
->var
.i
> 0){
825 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->var
;
826 (*cl
)->d
.c
.cs
->starting_varmem
= (*cl
)->d
.c
.ct
->var
.i
- 1;
829 if((*cl
)->d
.c
.ct
->prev
){
830 (*cl
)->d
.c
.cs
->starting_var
= (*cl
)->d
.c
.ct
->prev
->var
.v
;
831 (*cl
)->d
.c
.cs
->starting_varmem
= (*cl
)->d
.c
.ct
->prev
->var
.i
;
836 /* Remove from var list */
837 if(!ccs_var_delete(ps
, (*cl
)->d
.c
.ct
)){
838 q_status_message(SM_ORDER
|SM_DING
, 3, 3,
839 _("Error deleting renamed context"));
843 q_status_message(SM_ORDER
, 0, 3, _("Collection deleted"));
848 q_status_message(SM_ORDER
, 0, 3, _("No collections deleted"));
854 ccs_var_delete(struct pine
*ps
, CONTEXT_S
*ctxt
)
857 char **newl
= NULL
, **lval
, **lp
, ***alval
;
860 lval
= LVAL(ctxt
->var
.v
, ew
);
864 for(count
= 0; lval
&& lval
[count
]; count
++)
868 newl
= (char **) fs_get(count
* sizeof(char *));
869 for(i
= 0, lp
= newl
; lval
[i
]; i
++)
871 *lp
++ = cpystr(lval
[i
]);
876 alval
= ALVAL(ctxt
->var
.v
, ew
);
878 free_list_array(alval
);
880 for(i
= 0; newl
[i
] ; i
++) /* count elements */
883 *alval
= (char **) fs_get((i
+1) * sizeof(char *));
885 for(i
= 0; newl
[i
] ; i
++)
886 (*alval
)[i
] = cpystr(newl
[i
]);
892 free_list_array(&newl
);
898 * Insert into "var", which currently has values "oldvarval", the "newline"
899 * at position "insert".
902 ccs_var_insert(struct pine
*ps
, char *newline
, struct variable
*var
, char **oldvarval
, int insert
)
904 int count
, i
, offset
;
905 char **newl
, ***alval
;
907 for(count
= 0; oldvarval
&& oldvarval
[count
]; count
++)
910 if(insert
< 0 || insert
> count
){
911 q_status_message(SM_ORDER
,3,5, "unexpected problem inserting folder");
915 newl
= (char **)fs_get((count
+ 2) * sizeof(char *));
916 newl
[insert
] = cpystr(newline
);
917 newl
[count
+ 1] = NULL
;
918 for(i
= offset
= 0; oldvarval
&& oldvarval
[i
]; i
++){
922 newl
[i
+ offset
] = cpystr(oldvarval
[i
]);
925 alval
= ALVAL(var
, ew
);
927 free_list_array(alval
);
929 for(i
= 0; newl
[i
] ; i
++) /* count elements */
932 *alval
= (char **) fs_get((i
+1) * sizeof(char *));
934 for(i
= 0; newl
[i
] ; i
++)
935 (*alval
)[i
] = cpystr(newl
[i
]);
941 free_list_array(&newl
);
947 context_select_tool(struct pine
*ps
, int cmd
, CONF_S
**cl
, unsigned int flags
)
953 (*cl
)->d
.c
.cs
->selected
= (*cl
)->d
.c
.ct
;
954 retval
= simple_exit_cmd(flags
);
958 retval
= simple_exit_cmd(flags
);
962 retval
= simple_exit_cmd(flags
);
963 ps_global
->next_screen
= main_menu_screen
;
968 && sp_viewing_a_thread(ps_global
->mail_stream
)
969 && unview_thread(ps_global
, ps_global
->mail_stream
, ps_global
->msgmap
)){
970 ps_global
->next_screen
= mail_index_screen
;
971 ps_global
->view_skipped_index
= 0;
972 ps_global
->mangled_screen
= 1;
975 retval
= simple_exit_cmd(flags
);
976 ps_global
->next_screen
= mail_index_screen
;
980 retval
= simple_exit_cmd(flags
);
981 ps_global
->next_screen
= compose_screen
;
985 retval
= simple_exit_cmd(flags
);
986 ps_global
->next_screen
= alt_compose_screen
;
992 CONTEXT_S
*c
= (*cl
)->d
.c
.ct
;
993 char *new_fold
= broach_folder(-FOOTER_ROWS(ps
), 0, ¬realinbox
, &c
);
995 if(new_fold
&& do_broach_folder(new_fold
, c
, NULL
, notrealinbox
? 0L : DB_INBOXWOCNTXT
) > 0){
996 ps_global
->next_screen
= mail_index_screen
;
997 retval
= simple_exit_cmd(flags
);
1000 ps
->mangled_footer
= 1;
1006 retval
= simple_exit_cmd(flags
);
1007 ps_global
->next_screen
= quit_screen
;
1016 ps
->mangled_body
= 1;