Merge branch 'ical'
[alpine.git] / alpine / print.c
bloba70d6f25f75ee5fbe7a8c9204d9a2b5a0197d44f
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: print.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2017 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 * ========================================================================
19 #include "headers.h"
20 #include "print.h"
21 #include "confscroll.h"
22 #include "keymenu.h"
23 #include "radio.h"
24 #include "status.h"
25 #include "../pith/state.h"
26 #include "../pith/mailcmd.h"
30 * Internal prototypes
32 void set_def_printer_value(char *);
33 int print_select_tool(struct pine *, int, CONF_S **, unsigned);
34 int print_edit_tool(struct pine *, int, CONF_S **, unsigned);
37 static char **def_printer_line;
38 static char no_ff[] = "-no-formfeed";
41 #ifndef DOS
44 * Information used to paint and maintain a line on the configuration screen
46 /*----------------------------------------------------------------------
47 The printer selection screen
49 Draws the screen and prompts for the printer number and the custom
50 command if so selected.
52 ----*/
53 void
54 select_printer(struct pine *ps, int edit_exceptions)
56 struct variable *vtmp;
57 CONF_S *ctmpa = NULL, *ctmpb = NULL, *heading = NULL,
58 *start_line = NULL;
59 PINERC_S *prc = NULL;
60 int i, saved_printer_cat, readonly_warning = 0, no_ex;
61 SAVED_CONFIG_S *vsave;
62 char *saved_printer, **lval;
63 OPT_SCREEN_S screen;
64 size_t l;
66 if(edit_exceptions){
67 q_status_message(SM_ORDER, 3, 7,
68 _("Exception Setup not implemented for printer"));
69 return;
72 if(fixed_var(&ps_global->vars[V_PRINTER], "change", "printer"))
73 return;
75 ew = edit_exceptions ? ps_global->ew_for_except_vars : Main;
77 no_ex = (ps_global->ew_for_except_vars == Main);
79 if(ps->restricted)
80 readonly_warning = 1;
81 else{
82 switch(ew){
83 case Main:
84 prc = ps->prc;
85 break;
86 case Post:
87 prc = ps->post_prc;
88 break;
89 default:
90 break;
93 readonly_warning = prc ? prc->readonly : 1;
94 if(prc && prc->quit_to_edit){
95 quit_to_edit_msg(prc);
96 return;
100 saved_printer = cpystr(ps->VAR_PRINTER);
101 saved_printer_cat = ps->printer_category;
103 new_confline(&ctmpa);
104 ctmpa->valoffset = 2;
105 ctmpa->keymenu = &printer_select_keymenu;
106 ctmpa->help = NO_HELP;
107 ctmpa->tool = print_select_tool;
108 ctmpa->flags |= CF_NOSELECT;
109 ctmpa->value
110 #ifdef OS2
111 = cpystr("\"Select\" a port or |pipe-command as your default printer.");
112 #else
113 = cpystr(_("You may \"Select\" a print command as your default printer."));
114 #endif
116 new_confline(&ctmpa);
117 ctmpa->valoffset = 2;
118 ctmpa->keymenu = &printer_select_keymenu;
119 ctmpa->help = NO_HELP;
120 ctmpa->tool = print_select_tool;
121 ctmpa->flags |= CF_NOSELECT;
122 ctmpa->value
123 #ifdef OS2
124 = cpystr("You may also add alternative ports or !pipes to the list in the");
125 #else
126 = cpystr(_("You may also add custom print commands to the list in the"));
127 #endif
129 new_confline(&ctmpa);
130 ctmpa->valoffset = 2;
131 ctmpa->keymenu = &printer_select_keymenu;
132 ctmpa->help = NO_HELP;
133 ctmpa->tool = print_select_tool;
134 ctmpa->flags |= CF_NOSELECT;
135 ctmpa->value
136 #ifdef OS2
137 = cpystr("\"Personally selected port or |pipe\" section below.");
138 #else
139 = cpystr(_("\"Personally selected print command\" section below."));
140 #endif
142 new_confline(&ctmpa);
143 ctmpa->valoffset = 2;
144 ctmpa->keymenu = &printer_select_keymenu;
145 ctmpa->help = NO_HELP;
146 ctmpa->tool = print_select_tool;
147 ctmpa->flags |= CF_NOSELECT | CF_B_LINE;
149 new_confline(&ctmpa);
150 ctmpa->valoffset = 4;
151 ctmpa->keymenu = &printer_select_keymenu;
152 ctmpa->help = NO_HELP;
153 ctmpa->tool = print_select_tool;
154 ctmpa->flags |= CF_NOSELECT;
155 def_printer_line = &ctmpa->value;
156 set_def_printer_value(ps->VAR_PRINTER);
158 new_confline(&ctmpa);
159 ctmpa->valoffset = 2;
160 ctmpa->keymenu = &printer_select_keymenu;
161 ctmpa->help = NO_HELP;
162 ctmpa->tool = print_select_tool;
163 ctmpa->flags |= CF_NOSELECT | CF_B_LINE;
165 #ifndef OS2
166 new_confline(&ctmpa);
167 heading = ctmpa;
168 ctmpa->keymenu = &printer_select_keymenu;
169 ctmpa->help = NO_HELP;
170 ctmpa->tool = print_select_tool;
171 ctmpa->varname
172 = cpystr(_(" Printer attached to IBM PC or compatible, Macintosh"));
173 ctmpa->flags |= (CF_NOSELECT | CF_STARTITEM);
174 ctmpa->value = cpystr("");
175 ctmpa->headingp = heading;
177 new_confline(&ctmpa);
178 ctmpa->valoffset = 6;
179 ctmpa->keymenu = &printer_select_keymenu;
180 ctmpa->help = NO_HELP;
181 ctmpa->tool = print_select_tool;
182 ctmpa->flags |= CF_NOSELECT;
183 ctmpa->value
184 = cpystr(_("This may not work with all attached printers, and will depend on the"));
185 ctmpa->headingp = heading;
187 new_confline(&ctmpa);
188 ctmpa->valoffset = 6;
189 ctmpa->keymenu = &printer_select_keymenu;
190 ctmpa->help = NO_HELP;
191 ctmpa->tool = print_select_tool;
192 ctmpa->flags |= CF_NOSELECT;
193 ctmpa->value
194 = cpystr(_("terminal emulation/communications software in use. It is known to work"));
195 ctmpa->headingp = heading;
197 new_confline(&ctmpa);
198 ctmpa->valoffset = 6;
199 ctmpa->keymenu = &printer_select_keymenu;
200 ctmpa->help = NO_HELP;
201 ctmpa->tool = print_select_tool;
202 ctmpa->flags |= CF_NOSELECT;
203 ctmpa->value
204 = cpystr("with Kermit and the latest UW version of NCSA telnet on Macs and PCs,");
205 ctmpa->headingp = heading;
207 new_confline(&ctmpa);
208 ctmpa->valoffset = 6;
209 ctmpa->keymenu = &printer_select_keymenu;
210 ctmpa->help = NO_HELP;
211 ctmpa->tool = print_select_tool;
212 ctmpa->flags |= CF_NOSELECT;
213 ctmpa->value
214 = cpystr("Versaterm Pro on Macs, and WRQ Reflections on PCs.");
215 ctmpa->headingp = heading;
217 new_confline(&ctmpa);
218 start_line = ctmpb = ctmpa; /* default start line */
219 ctmpa->valoffset = 17;
220 ctmpa->keymenu = &printer_select_keymenu;
221 ctmpa->help = h_config_set_att_ansi;
222 ctmpa->tool = print_select_tool;
223 ctmpa->flags |= CF_NOHILITE;
224 ctmpa->varoffset = 8;
225 ctmpa->varname = cpystr("Printer:");
226 ctmpa->value = cpystr(ANSI_PRINTER);
227 ctmpa->varnamep = ctmpb;
228 ctmpa->headingp = heading;
230 new_confline(&ctmpa);
231 ctmpa->valoffset = 17;
232 ctmpa->keymenu = &printer_select_keymenu;
233 ctmpa->help = h_config_set_att_ansi2;
234 ctmpa->tool = print_select_tool;
235 ctmpa->flags |= CF_NOHILITE;
236 ctmpa->varoffset = 8;
237 l = strlen(ANSI_PRINTER)+strlen(no_ff);
238 ctmpa->value = (char *)fs_get((l+1) * sizeof(char));
239 ctmpa->varnamep = ctmpb;
240 ctmpa->headingp = heading;
241 snprintf(ctmpa->value, l+1, "%s%s", ANSI_PRINTER, no_ff);
242 ctmpa->value[l] = '\0';
244 new_confline(&ctmpa);
245 ctmpa->valoffset = 17;
246 ctmpa->keymenu = &printer_select_keymenu;
247 ctmpa->help = h_config_set_att_wyse;
248 ctmpa->tool = print_select_tool;
249 ctmpa->flags |= CF_NOHILITE;
250 ctmpa->varoffset = 8;
251 ctmpa->value = cpystr(WYSE_PRINTER);
252 ctmpa->varnamep = ctmpb;
253 ctmpa->headingp = heading;
255 new_confline(&ctmpa);
256 ctmpa->valoffset = 17;
257 ctmpa->keymenu = &printer_select_keymenu;
258 ctmpa->help = h_config_set_att_wyse2;
259 ctmpa->tool = print_select_tool;
260 ctmpa->flags |= CF_NOHILITE;
261 ctmpa->varoffset = 8;
262 l = strlen(WYSE_PRINTER)+strlen(no_ff);
263 ctmpa->value = (char *)fs_get((l+1) * sizeof(char));
264 ctmpa->varnamep = ctmpb;
265 ctmpa->headingp = heading;
266 snprintf(ctmpa->value, l+1, "%s%s", WYSE_PRINTER, no_ff);
267 ctmpa->value[l] = '\0';
268 #endif
270 new_confline(&ctmpa);
271 ctmpa->valoffset = 0;
272 ctmpa->keymenu = &printer_select_keymenu;
273 ctmpa->help = NO_HELP;
274 ctmpa->tool = print_select_tool;
275 ctmpa->flags |= CF_NOSELECT | CF_B_LINE;
276 ctmpa->var = &ps->vars[V_STANDARD_PRINTER];
279 new_confline(&ctmpa);
280 heading = ctmpa;
281 ctmpa->valoffset = 6;
282 ctmpa->keymenu = &printer_select_keymenu;
283 ctmpa->help = NO_HELP;
284 ctmpa->tool = print_select_tool;
285 ctmpa->varname
286 #ifdef OS2
287 = cpystr(" Standard OS/2 printer port");
288 #else
289 = cpystr(_(" Standard UNIX print command"));
290 #endif
291 ctmpa->value = cpystr("");
292 ctmpa->flags |= (CF_NOSELECT | CF_STARTITEM);
293 ctmpa->headingp = heading;
294 ctmpa->var = &ps->vars[V_STANDARD_PRINTER];
296 new_confline(&ctmpa);
297 ctmpa->valoffset = 6;
298 ctmpa->keymenu = &printer_select_keymenu;
299 ctmpa->help = NO_HELP;
300 ctmpa->tool = print_select_tool;
301 ctmpa->flags |= CF_NOSELECT;
302 ctmpa->value
303 #ifdef OS2
304 = cpystr("Using this option may require you to use the OS/2 \"MODE\" command to");
305 #else
306 = cpystr(_("Using this option may require setting your \"PRINTER\" or \"LPDEST\""));
307 #endif
308 ctmpa->headingp = heading;
309 ctmpa->var = &ps->vars[V_STANDARD_PRINTER];
311 new_confline(&ctmpa);
312 ctmpa->valoffset = 6;
313 ctmpa->keymenu = &printer_select_keymenu;
314 ctmpa->help = NO_HELP;
315 ctmpa->tool = print_select_tool;
316 ctmpa->flags |= CF_NOSELECT;
317 ctmpa->value
318 #ifdef OS2
319 = cpystr("direct printer output to the correct port.");
320 #else
321 = cpystr(_("environment variable using the standard UNIX utilities."));
322 #endif
323 ctmpa->headingp = heading;
324 ctmpa->var = &ps->vars[V_STANDARD_PRINTER];
326 vtmp = &ps->vars[V_STANDARD_PRINTER];
327 for(i = 0; vtmp->current_val.l[i]; i++){
328 new_confline(&ctmpa);
329 ctmpa->valoffset = 22;
330 ctmpa->keymenu = &printer_select_keymenu;
331 ctmpa->help = NO_HELP;
332 ctmpa->help = h_config_set_stand_print;
333 ctmpa->tool = print_select_tool;
334 if(i == 0){
335 ctmpa->varoffset = 8;
336 ctmpa->varname = cpystr(_("Printer List:"));
337 ctmpa->flags |= CF_NOHILITE|CF_PRINTER;
338 #ifdef OS2
339 start_line = ctmpb = ctmpa; /* default start line */
340 #else
341 ctmpb = ctmpa;
342 #endif
345 ctmpa->varnamep = ctmpb;
346 ctmpa->headingp = heading;
347 ctmpa->varmem = i;
348 ctmpa->var = vtmp;
349 ctmpa->value = printer_name(vtmp->current_val.l[i]);
352 new_confline(&ctmpa);
353 ctmpa->valoffset = 0;
354 ctmpa->keymenu = &printer_select_keymenu;
355 ctmpa->help = NO_HELP;
356 ctmpa->tool = print_select_tool;
357 ctmpa->flags |= CF_NOSELECT | CF_B_LINE;
359 new_confline(&ctmpa);
360 heading = ctmpa;
361 ctmpa->valoffset = 0;
362 ctmpa->keymenu = &printer_edit_keymenu;
363 ctmpa->help = NO_HELP;
364 ctmpa->tool = print_edit_tool;
365 ctmpa->varname
366 #ifdef OS2
367 = cpystr(" Personally selected port or |command");
368 #else
369 = cpystr(_(" Personally selected print command"));
370 #endif
371 ctmpa->flags |= (CF_NOSELECT | CF_STARTITEM);
372 ctmpa->value = cpystr("");
373 ctmpa->headingp = heading;
374 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
377 new_confline(&ctmpa);
378 ctmpa->valoffset = 6;
379 ctmpa->keymenu = &printer_edit_keymenu;
380 ctmpa->help = NO_HELP;
381 ctmpa->tool = print_edit_tool;
382 ctmpa->flags |= CF_NOSELECT;
383 ctmpa->value
384 #ifdef OS2
385 = cpystr("The text to be printed will be sent to the printer or command given here.");
386 #else
387 = cpystr(_("The text to be printed will be piped into the command given here. The"));
388 #endif
389 ctmpa->headingp = heading;
390 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
392 new_confline(&ctmpa);
393 ctmpa->valoffset = 6;
394 ctmpa->keymenu = &printer_edit_keymenu;
395 ctmpa->help = NO_HELP;
396 ctmpa->tool = print_edit_tool;
397 ctmpa->flags |= CF_NOSELECT;
398 ctmpa->value
399 #ifdef OS2
400 = cpystr("The printer port or |pipe is in the 2nd column, the printer name is in");
401 #else
402 = cpystr(_("command is in the 2nd column, the printer name is in the first column. Some"));
403 #endif
404 ctmpa->headingp = heading;
405 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
407 new_confline(&ctmpa);
408 ctmpa->valoffset = 6;
409 ctmpa->keymenu = &printer_edit_keymenu;
410 ctmpa->help = NO_HELP;
411 ctmpa->tool = print_edit_tool;
412 ctmpa->flags |= CF_NOSELECT;
413 ctmpa->value
414 #ifdef OS2
415 = cpystr("the first column. Examples: \"LPT1\", \"COM2\", \"|enscript\". A command may");
416 #else
417 = cpystr(_("examples are: \"prt\", \"lpr\", \"lp\", or \"enscript\". The command may be given"));
418 #endif
419 ctmpa->headingp = heading;
420 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
422 new_confline(&ctmpa);
423 ctmpa->valoffset = 6;
424 ctmpa->keymenu = &printer_edit_keymenu;
425 ctmpa->help = NO_HELP;
426 ctmpa->tool = print_edit_tool;
427 ctmpa->flags |= CF_NOSELECT;
428 ctmpa->value
429 #ifdef OS2
430 = cpystr("be given options, for example \"|ascii2ps -p LPT1\" or \"|txt2hplc -2\". Use");
431 #else
432 = cpystr(_("with options, for example \"enscript -2 -r\" or \"lpr -Plpacc170\". The"));
433 #endif
434 ctmpa->headingp = heading;
435 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
437 new_confline(&ctmpa);
438 ctmpa->valoffset = 6;
439 ctmpa->keymenu = &printer_edit_keymenu;
440 ctmpa->help = NO_HELP;
441 ctmpa->tool = print_edit_tool;
442 ctmpa->flags |= CF_NOSELECT;
443 ctmpa->value
444 #ifdef OS2
445 = cpystr("the |command method for printers that require conversion from ASCII.");
446 #else
447 = cpystr(_("commands and options on your system may be different from these examples."));
448 #endif
449 ctmpa->headingp = heading;
450 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
452 vtmp = &ps->vars[V_PERSONAL_PRINT_COMMAND];
453 lval = no_ex ? vtmp->current_val.l : LVAL(vtmp, ew);
454 if(lval){
455 for(i = 0; lval[i]; i++){
456 new_confline(&ctmpa);
457 ctmpa->valoffset = 22;
458 ctmpa->keymenu = &printer_edit_keymenu;
459 ctmpa->help = h_config_set_custom_print;
460 ctmpa->tool = print_edit_tool;
461 if(i == 0){
462 ctmpa->varoffset = 8;
463 ctmpa->varname = cpystr(_("Printer List:"));
464 ctmpa->flags |= CF_NOHILITE|CF_PRINTER;
465 ctmpb = ctmpa;
468 ctmpa->varnamep = ctmpb;
469 ctmpa->headingp = heading;
470 ctmpa->varmem = i;
471 ctmpa->var = vtmp;
472 ctmpa->value = printer_name(lval[i]);
475 else{
476 new_confline(&ctmpa);
477 ctmpa->valoffset = 22;
478 ctmpa->keymenu = &printer_edit_keymenu;
479 ctmpa->help = h_config_set_custom_print;
480 ctmpa->tool = print_edit_tool;
481 ctmpa->flags |= CF_NOHILITE;
482 ctmpa->varoffset = 8;
483 ctmpa->varname = cpystr(_("Printer List:"));
484 ctmpa->varnamep = ctmpa;
485 ctmpa->headingp = heading;
486 ctmpa->varmem = 0;
487 ctmpa->var = vtmp;
488 ctmpa->value = cpystr("");
491 memset(&screen, 0, sizeof(screen));
492 screen.ro_warning = readonly_warning;
493 vsave = save_config_vars(ps, 0);
494 /* TRANSLATORS: SETUP... is a screen title
495 Print something1 using something2.
496 "printer config" is something1 */
497 switch(conf_scroll_screen(ps, &screen, start_line,
498 edit_exceptions ? _("SETUP PRINTER EXCEPTIONS")
499 : _("SETUP PRINTER"),
500 _("printer config"), 0, NULL)){
501 case 0:
502 break;
504 case 1:
505 write_pinerc(ps, ew, WRP_NONE);
506 break;
508 case 10:
509 revert_to_saved_config(ps, vsave, 0);
510 ps->printer_category = saved_printer_cat;
511 set_variable(V_PRINTER, saved_printer, 1, 0, ew);
512 set_variable(V_PERSONAL_PRINT_CATEGORY, comatose(ps->printer_category),
513 1, 0, ew);
514 if(prc)
515 prc->outstanding_pinerc_changes = 0;
517 break;
520 def_printer_line = NULL;
521 free_saved_config(ps, &vsave, 0);
522 fs_give((void **)&saved_printer);
525 #endif /* !DOS */
528 void
529 set_def_printer_value(char *printer)
531 char *p, *nick, *cmd;
532 int set, editing_norm_except_exists;
533 size_t l;
535 if(!def_printer_line)
536 return;
538 editing_norm_except_exists = ((ps_global->ew_for_except_vars != Main) &&
539 (ew == Main));
541 parse_printer(printer, &nick, &cmd, NULL, NULL, NULL, NULL);
542 p = *nick ? nick : cmd;
543 set = *p;
544 if(*def_printer_line)
545 fs_give((void **)def_printer_line);
547 l = strlen(p) + 60;
548 *def_printer_line = fs_get((l+1) * sizeof(char));
549 snprintf(*def_printer_line, l+1, "Default printer %s%s%s%s%s",
550 set ? "set to \"" : "unset", set ? p : "", set ? "\"" : "",
551 (set && editing_norm_except_exists) ? " (in exception config)" : "",
552 set ? "." : "");
553 (*def_printer_line)[l] = '\0';
555 fs_give((void **)&nick);
556 fs_give((void **)&cmd);
561 print_select_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
563 int rc, retval, no_ex, printer_msg = 0;
564 char *p, **lval, *printer_was;
565 struct variable *vtmp;
567 no_ex = (ps_global->ew_for_except_vars == Main);
569 printer_was = ps->VAR_PRINTER ? cpystr(ps->VAR_PRINTER) : NULL;
571 switch(cmd){
572 case MC_EXIT:
573 retval = config_exit_cmd(flags);
574 break;
576 case MC_CHOICE :
577 if(cl && *cl){
578 char aname[100], wname[100];
580 strncpy(aname, ANSI_PRINTER, sizeof(aname)-1);
581 aname[sizeof(aname)-1] = '\0';
582 strncat(aname, no_ff, sizeof(aname)-strlen(aname)-1);
583 strncpy(wname, WYSE_PRINTER, sizeof(wname)-1);
584 wname[sizeof(wname)-1] = '\0';
585 strncat(wname, no_ff, sizeof(wname)-strlen(wname)-1);
586 if((*cl)->var){
587 vtmp = (*cl)->var;
588 lval = (no_ex || !vtmp->is_user) ? vtmp->current_val.l
589 : LVAL(vtmp, ew);
590 rc = set_variable(V_PRINTER, lval ? lval[(*cl)->varmem] : NULL,
591 1, 0, ew);
592 if(rc == 0){
593 if(vtmp == &ps->vars[V_STANDARD_PRINTER])
594 ps->printer_category = 2;
595 else if(vtmp == &ps->vars[V_PERSONAL_PRINT_COMMAND])
596 ps->printer_category = 3;
598 set_variable(V_PERSONAL_PRINT_CATEGORY,
599 comatose(ps->printer_category), 1, 0, ew);
601 printer_msg++;
603 else
604 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
606 retval = 1;
608 else if(!strcmp((*cl)->value,ANSI_PRINTER)){
609 rc = set_variable(V_PRINTER, ANSI_PRINTER, 1, 0, ew);
610 if(rc == 0){
611 ps->printer_category = 1;
612 set_variable(V_PERSONAL_PRINT_CATEGORY,
613 comatose(ps->printer_category), 1, 0, ew);
614 printer_msg++;
616 else
617 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
619 retval = 1;
621 else if(!strcmp((*cl)->value,aname)){
622 rc = set_variable(V_PRINTER, aname, 1, 0, ew);
623 if(rc == 0){
624 ps->printer_category = 1;
625 set_variable(V_PERSONAL_PRINT_CATEGORY,
626 comatose(ps->printer_category), 1, 0, ew);
627 printer_msg++;
629 else
630 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
632 retval = 1;
634 else if(!strcmp((*cl)->value,WYSE_PRINTER)){
635 rc = set_variable(V_PRINTER, WYSE_PRINTER, 1, 0, ew);
636 if(rc == 0){
637 ps->printer_category = 1;
638 set_variable(V_PERSONAL_PRINT_CATEGORY,
639 comatose(ps->printer_category), 1, 0, ew);
640 printer_msg++;
642 else
643 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
645 retval = 1;
647 else if(!strcmp((*cl)->value,wname)){
648 rc = set_variable(V_PRINTER, wname, 1, 0, ew);
649 if(rc == 0){
650 ps->printer_category = 1;
651 set_variable(V_PERSONAL_PRINT_CATEGORY,
652 comatose(ps->printer_category), 1, 0, ew);
653 printer_msg++;
655 else
656 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
658 retval = 1;
660 else
661 retval = 0;
663 else
664 retval = 0;
666 if(retval){
667 ps->mangled_body = 1; /* BUG: redraw it all for now? */
668 set_def_printer_value(ps->VAR_PRINTER);
671 break;
673 default:
674 retval = -1;
675 break;
678 if(printer_msg){
679 p = NULL;
680 if(ps->VAR_PRINTER){
681 char *nick, *q;
683 parse_printer(ps->VAR_PRINTER, &nick, &q,
684 NULL, NULL, NULL, NULL);
685 p = cpystr(*nick ? nick : q);
686 fs_give((void **)&nick);
687 fs_give((void **)&q);
690 q_status_message4(SM_ORDER, 0, 3,
691 "Default printer%s %s%s%s",
692 ((!printer_was && !ps->VAR_PRINTER) ||
693 (printer_was && ps->VAR_PRINTER &&
694 !strcmp(printer_was,ps->VAR_PRINTER)))
695 ? " still" : "",
696 p ? "set to \"" : "unset",
697 p ? p : "", p ? "\"" : "");
699 if(p)
700 fs_give((void **)&p);
703 if(printer_was)
704 fs_give((void **)&printer_was);
706 return(retval);
711 print_edit_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
713 char prompt[81], sval[MAXPATH+1], name[MAXPATH+1];
714 char *nick, *p, *tmp, **newval = NULL, **ltmp = NULL;
715 char **lval, **nelval;
716 int rv = 0, skip_to_next = 0, after = 0, i = 4, j, k = 0;
717 int oeflags, changing_selected = 0, no_ex;
718 HelpType help;
719 ESCKEY_S ekey[6];
721 /* need this to preserve old behavior when no exception config file */
722 no_ex = (ps_global->ew_for_except_vars == Main);
724 if(cmd == MC_CHOICE)
725 return(print_select_tool(ps, cmd, cl, flags));
727 if(!(cl && *cl && (*cl)->var))
728 return(0);
730 nelval = no_ex ? (*cl)->var->current_val.l : LVAL((*cl)->var, ew);
731 lval = LVAL((*cl)->var, ew);
733 switch(cmd){
734 case MC_ADD: /* add to list */
735 sval[0] = '\0';
736 if(!fixed_var((*cl)->var, "add to", NULL)){
738 if(lval && (*cl)->value){
739 strncpy(prompt, _("Enter printer name : "), sizeof(prompt));
740 prompt[sizeof(prompt)-1] = '\0';
742 else if(!lval && nelval){
743 /* Add to list which doesn't exist, but default does exist */
744 ekey[0].ch = 'r';
745 ekey[0].rval = 'r';
746 ekey[0].name = "R";
747 ekey[0].label = N_("Replace");
748 ekey[1].ch = 'a';
749 ekey[1].rval = 'a';
750 ekey[1].name = "A";
751 ekey[1].label = N_("Add To");
752 ekey[2].ch = -1;
753 strncpy(prompt, _("Replace or Add To default value ? "), sizeof(prompt));
754 prompt[sizeof(prompt)-1] = '\0';
755 switch(i = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'a',
756 'x', h_config_replace_add, RB_NORM)){
757 case 'a':
758 /* Make a list of the default commands, leaving room for
759 the command we are about to add below. */
760 for(k = 0; nelval[k]; k++)
763 ltmp = (char **)fs_get((k+2) * sizeof(char *));
765 for(j = 0; j < k; j++)
766 ltmp[j] = cpystr(nelval[j]);
768 ltmp[k + 1] = ltmp[k] = NULL;
770 add_text:
771 strncpy(prompt, _("Enter name of printer to be added : "), sizeof(prompt));
772 prompt[sizeof(prompt)-1] = '\0';
773 break;
775 case 'r':
776 replace_text:
777 strncpy(prompt, _("Enter the name for replacement printer : "), sizeof(prompt));
778 prompt[sizeof(prompt)-1] = '\0';
779 break;
781 case 'x':
782 cmd_cancelled("Add");
783 break;
786 if(i == 'x')
787 break;
789 else{
790 strncpy(prompt, _("Enter name of printer to be added : "), sizeof(prompt));
791 prompt[sizeof(prompt)-1] = '\0';
794 ps->mangled_footer = 1;
795 help = NO_HELP;
797 name[0] = '\0';
798 i = 2;
799 while(i != 0 && i != 1){
800 if(lval && (*cl)->value){
801 ekey[0].ch = ctrl('W');
802 ekey[0].rval = 5;
803 ekey[0].name = "^W";
804 ekey[0].label = after ? N_("InsertBefore") : N_("InsertAfter");
805 ekey[1].ch = -1;
807 else
808 ekey[0].ch = -1;
810 oeflags = OE_APPEND_CURRENT;
811 i = optionally_enter(name, -FOOTER_ROWS(ps), 0, sizeof(name),
812 prompt,
813 (ekey[0].ch != -1) ? ekey : NULL,
814 help, &oeflags);
815 if(i == 0){
816 rv = ps->mangled_body = 1;
817 removing_leading_and_trailing_white_space(name);
819 else if(i == 1){
820 cmd_cancelled("Add");
822 else if(i == 3){
823 help = (help == NO_HELP) ? h_config_insert_after : NO_HELP;
825 else if(i == 4){ /* no redraw, yet */
827 else if(i == 5){ /* change from/to prepend to/from append */
828 after = after ? 0 : 1;
832 if(i == 0)
833 i = 2;
835 #ifdef OS2
836 strncpy(prompt, "Enter port or |command : ", sizeof(prompt));
837 #else
838 strncpy(prompt, _("Enter command for printer : "), sizeof(prompt));
839 #endif
840 prompt[sizeof(prompt)-1] = '\0';
841 while(i != 0 && i != 1){
842 oeflags = OE_APPEND_CURRENT;
843 i = optionally_enter(sval, -FOOTER_ROWS(ps), 0, sizeof(sval),
844 prompt,
845 (ekey[0].ch != -1) ? ekey : NULL,
846 help, &oeflags);
847 if(i == 0){
848 rv = ps->mangled_body = 1;
849 removing_leading_and_trailing_white_space(sval);
850 if(*sval || !lval){
852 for(tmp = sval; *tmp; tmp++)
853 if(*tmp == ',')
854 i++; /* conservative count of ,'s */
856 if(!i){ /* only one item */
857 if (!ltmp){
858 ltmp = (char **)fs_get(2 * sizeof(char *));
859 ltmp[1] = NULL;
860 k = 0;
862 if(*name){
863 size_t l;
865 l = strlen(name) + 4 + strlen(sval);
866 ltmp[k] = (char *) fs_get((l+1) * sizeof(char));
867 snprintf(ltmp[k], l+1, "%s [] %s", name, sval);
868 ltmp[k][l] = '\0';
870 else
871 ltmp[k] = cpystr(sval);
873 else{
875 * Don't allow input of multiple entries at once.
877 q_status_message(SM_ORDER,3,5,
878 _("No commas allowed in command"));
879 i = 2;
880 continue;
883 config_add_list(ps, cl, ltmp, &newval, after);
885 if(after)
886 skip_to_next = 1;
888 fs_give((void **)&ltmp);
889 k = 0;
891 else
892 q_status_message1(SM_ORDER, 0, 3,
893 _("Can't add %s to list"), empty_val);
895 else if(i == 1){
896 cmd_cancelled("Add");
898 else if(i == 3){
899 help = help == NO_HELP ? h_config_print_cmd : NO_HELP;
901 else if(i == 4){ /* no redraw, yet */
903 else if(i == 5){ /* change from/to prepend to/from append */
904 after = after ? 0 : 1;
909 break;
911 case MC_DELETE: /* delete */
912 if((*cl)->var->current_val.l
913 && (*cl)->var->current_val.l[(*cl)->varmem]
914 && !strucmp(ps->VAR_PRINTER,(*cl)->var->current_val.l[(*cl)->varmem]))
915 changing_selected = 1;
917 if(!lval && nelval){
918 char pmt[80];
920 snprintf(pmt, sizeof(pmt), _("Override default with %s"), empty_val2);
921 pmt[sizeof(pmt)-1] = '\0';
922 if(want_to(pmt, 'n', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
923 char **ltmp;
925 sval[0] = '\0';
926 ltmp = (char **)fs_get(2 * sizeof(char *));
927 ltmp[0] = cpystr(sval);
928 ltmp[1] = NULL;
929 config_add_list(ps, cl, ltmp, &newval, 0);
930 fs_give((void **)&ltmp);
931 rv = ps->mangled_body = 1;
934 else if(!lval){
935 q_status_message(SM_ORDER, 0, 3, _("No set value to delete"));
937 else{
938 if((*cl)->var->is_fixed){
939 parse_printer(lval[(*cl)->varmem],
940 &nick, &p, NULL, NULL, NULL, NULL);
941 snprintf(prompt, sizeof(prompt), _("Delete (unused) printer %s "),
942 *nick ? nick : (!*p) ? empty_val2 : p);
943 fs_give((void **)&nick);
944 fs_give((void **)&p);
946 else
947 snprintf(prompt, sizeof(prompt), _("Really delete item %s from printer list "),
948 int2string((*cl)->varmem + 1));
950 prompt[sizeof(prompt)-1] = '\0';
952 ps->mangled_footer = 1;
953 if(want_to(prompt,'n','n',h_config_print_del, WT_FLUSH_IN) == 'y'){
954 rv = ps->mangled_body = 1;
955 fs_give((void **)&lval[(*cl)->varmem]);
956 config_del_list_item(cl, &newval);
958 else
959 q_status_message(SM_ORDER, 0, 3, _("Printer not deleted"));
962 break;
964 case MC_EDIT: /* edit/change list option */
965 if((*cl)->var->current_val.l
966 && (*cl)->var->current_val.l[(*cl)->varmem]
967 && !strucmp(ps->VAR_PRINTER,(*cl)->var->current_val.l[(*cl)->varmem]))
968 changing_selected = 1;
970 if(fixed_var((*cl)->var, NULL, "printer"))
971 break;
972 else if(!lval && nelval)
973 goto replace_text;
974 else if(!lval && !nelval)
975 goto add_text;
976 else{
977 HelpType help;
979 ekey[0].ch = 'n';
980 ekey[0].rval = 'n';
981 ekey[0].name = "N";
982 ekey[0].label = N_("Name");
983 ekey[1].ch = 'c';
984 ekey[1].rval = 'c';
985 ekey[1].name = "C";
986 ekey[1].label = N_("Command");
987 ekey[2].ch = 'o';
988 ekey[2].rval = 'o';
989 ekey[2].name = "O";
990 ekey[2].label = N_("Options");
991 ekey[3].ch = -1;
992 /* TRANSLATORS: this is a question with three choices */
993 strncpy(prompt, _("Change Name or Command or Options ? "), sizeof(prompt));
994 prompt[sizeof(prompt)-1] = '\0';
995 i = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'c', 'x',
996 h_config_print_name_cmd, RB_NORM);
998 if(i == 'x'){
999 cmd_cancelled("Change");
1000 break;
1002 else if(i == 'c'){
1003 char *all_but_cmd;
1005 parse_printer(lval[(*cl)->varmem],
1006 NULL, &p, NULL, NULL, NULL, &all_but_cmd);
1008 strncpy(prompt, _("Change command : "), sizeof(prompt));
1009 prompt[sizeof(prompt)-1] = '\0';
1010 strncpy(sval, p ? p : "", sizeof(sval)-1);
1011 sval[sizeof(sval)-1] = '\0';
1012 fs_give((void **)&p);
1014 ps->mangled_footer = 1;
1015 help = NO_HELP;
1016 while(1){
1017 oeflags = OE_APPEND_CURRENT;
1018 i = optionally_enter(sval, -FOOTER_ROWS(ps), 0,
1019 sizeof(sval), prompt, NULL,
1020 help, &oeflags);
1021 if(i == 0){
1022 removing_leading_and_trailing_white_space(sval);
1023 rv = ps->mangled_body = 1;
1024 if(lval[(*cl)->varmem])
1025 fs_give((void **)&lval[(*cl)->varmem]);
1027 i = 0;
1028 for(tmp = sval; *tmp; tmp++)
1029 if(*tmp == ',')
1030 i++; /* count of ,'s */
1032 if(!i){ /* only one item */
1033 size_t l;
1035 l = strlen(all_but_cmd) + strlen(sval);
1036 lval[(*cl)->varmem] = (char *)fs_get((l+1) * sizeof(char));
1037 snprintf(lval[(*cl)->varmem], l+1, "%s%s", all_but_cmd, sval);
1038 lval[(*cl)->varmem][l] = '\0';
1040 newval = &(*cl)->value;
1042 else{
1044 * Don't allow input of multiple entries at once.
1046 q_status_message(SM_ORDER,3,5,
1047 _("No commas allowed in command"));
1048 continue;
1051 else if(i == 1){
1052 cmd_cancelled("Change");
1054 else if(i == 3){
1055 help = help == NO_HELP ? h_config_change : NO_HELP;
1056 continue;
1058 else if(i == 4){ /* no redraw, yet */
1059 continue;
1062 break;
1065 else if(i == 'n'){
1066 char *all_but_nick;
1068 parse_printer(lval[(*cl)->varmem],
1069 &p, NULL, NULL, NULL, &all_but_nick, NULL);
1071 strncpy(prompt, _("Change name : "), sizeof(prompt));
1072 prompt[sizeof(prompt)-1] = '\0';
1073 strncpy(name, p ? p : "", sizeof(name));
1074 name[sizeof(name)-1] = '\0';
1076 fs_give((void **)&p);
1078 ps->mangled_footer = 1;
1079 help = NO_HELP;
1080 while(1){
1081 oeflags = OE_APPEND_CURRENT;
1082 i = optionally_enter(name, -FOOTER_ROWS(ps), 0,
1083 sizeof(name), prompt, NULL,
1084 help, &oeflags);
1085 if(i == 0){
1086 size_t l;
1088 rv = ps->mangled_body = 1;
1089 removing_leading_and_trailing_white_space(name);
1090 if(lval[(*cl)->varmem])
1091 fs_give((void **)&lval[(*cl)->varmem]);
1093 l = strlen(name) + 1 + ((*all_but_nick == '[') ? 0 : 3) + strlen(all_but_nick);
1094 lval[(*cl)->varmem] = (char *)fs_get((l+1) * sizeof(char));
1095 snprintf(lval[(*cl)->varmem], l+1,
1096 "%s %s%s", name,
1097 (*all_but_nick == '[') ? "" : "[] ",
1098 all_but_nick);
1099 lval[(*cl)->varmem][l] = '\0';
1101 newval = &(*cl)->value;
1103 else if(i == 1){
1104 cmd_cancelled("Change");
1106 else if(i == 3){
1107 help = help == NO_HELP ? h_config_change : NO_HELP;
1108 continue;
1110 else if(i == 4){ /* no redraw, yet */
1111 continue;
1114 break;
1117 fs_give((void **)&all_but_nick);
1119 else if(i == 'o'){
1120 HelpType help;
1122 ekey[0].ch = 'i';
1123 ekey[0].rval = 'i';
1124 ekey[0].name = "I";
1125 ekey[0].label = N_("Init");
1126 ekey[1].ch = 't';
1127 ekey[1].rval = 't';
1128 ekey[1].name = "T";
1129 ekey[1].label = N_("Trailer");
1130 ekey[2].ch = -1;
1131 strncpy(prompt, _("Change Init string or Trailer string ? "), sizeof(prompt));
1132 prompt[sizeof(prompt)-1] = '\0';
1133 j = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'i', 'x',
1134 h_config_print_opt_choice, RB_NORM);
1136 if(j == 'x'){
1137 cmd_cancelled("Change");
1138 break;
1140 else{
1141 char *init, *trailer;
1143 parse_printer(lval[(*cl)->varmem],
1144 &nick, &p, &init, &trailer, NULL, NULL);
1146 if(j == i)
1147 snprintf(prompt, sizeof(prompt), _("Change INIT string : "));
1148 else
1149 snprintf(prompt, sizeof(prompt), _("Change TRAILER string : "));
1151 strncpy(sval, (j == 'i') ? init : trailer, sizeof(sval)-1);
1152 sval[sizeof(sval)-1] = '\0';
1154 tmp = string_to_cstring(sval);
1155 strncpy(sval, tmp, sizeof(sval)-1);
1156 sval[sizeof(sval)-1] = '\0';
1157 fs_give((void **)&tmp);
1159 ps->mangled_footer = 1;
1160 help = NO_HELP;
1161 while(1){
1162 oeflags = OE_APPEND_CURRENT;
1163 i = optionally_enter(sval, -FOOTER_ROWS(ps), 0,
1164 sizeof(sval), prompt, NULL, help, &oeflags);
1165 if(i == 0){
1166 size_t l;
1168 removing_leading_and_trailing_white_space(sval);
1169 rv = 1;
1170 if(lval[(*cl)->varmem])
1171 fs_give((void **)&lval[(*cl)->varmem]);
1172 if(j == 'i'){
1173 init = cstring_to_hexstring(sval);
1174 tmp = cstring_to_hexstring(trailer);
1175 fs_give((void **)&trailer);
1176 trailer = tmp;
1178 else{
1179 trailer = cstring_to_hexstring(sval);
1180 tmp = cstring_to_hexstring(init);
1181 fs_give((void **)&init);
1182 init = tmp;
1185 l = strlen(nick) + 1 + 2 + strlen("INIT=") + strlen(init) + 1 + strlen("TRAILER=") + strlen(trailer)+ 1 + strlen(p);
1186 lval[(*cl)->varmem] = (char *)fs_get((l+1) * sizeof(char));
1187 snprintf(lval[(*cl)->varmem], l+1,
1188 "%s%s%s%s%s%s%s%s%s%s%s",
1189 /* nick */ nick,
1190 /* space */ *nick ? " " : "",
1191 /* [ */ (*nick || *init || *trailer) ? "[" : "",
1192 /* INIT= */ *init ? "INIT=" : "",
1193 /* init */ init,
1194 /* space */ (*init && *trailer) ? " " : "",
1195 /* TRAILER= */ *trailer ? "TRAILER=" : "",
1196 /* trailer */ trailer,
1197 /* ] */ (*nick || *init || *trailer) ? "]" : "",
1198 /* space */ (*nick || *init || *trailer) ? " " : "",
1199 /* command */ p);
1200 lval[(*cl)->varmem][l] = '\0';
1202 newval = &(*cl)->value;
1204 else if(i == 1){
1205 cmd_cancelled("Change");
1207 else if(i == 3){
1208 help=(help == NO_HELP)?h_config_print_init:NO_HELP;
1209 continue;
1211 else if(i == 4){ /* no redraw, yet */
1212 continue;
1215 break;
1218 fs_give((void **)&nick);
1219 fs_give((void **)&p);
1220 fs_give((void **)&init);
1221 fs_give((void **)&trailer);
1226 break;
1228 case MC_EXIT: /* exit */
1229 rv = config_exit_cmd(flags);
1230 break;
1232 default:
1233 rv = -1;
1234 break;
1237 if(skip_to_next)
1238 *cl = next_confline(*cl);
1241 * At this point, if changes occurred, var->user_val.X is set.
1242 * So, fix the current_val, and handle special cases...
1244 if(rv == 1){
1245 set_current_val((*cl)->var, TRUE, FALSE);
1246 fix_side_effects(ps, (*cl)->var, 0);
1248 if(newval){
1249 if(*newval)
1250 fs_give((void **)newval);
1252 if((*cl)->var->current_val.l)
1253 *newval = printer_name((*cl)->var->current_val.l[(*cl)->varmem]);
1254 else
1255 *newval = cpystr("");
1258 if(changing_selected)
1259 print_select_tool(ps, MC_CHOICE, cl, flags);
1262 return(rv);
1267 * Given a single printer string from the config file, returns an allocated
1268 * copy of the friendly printer name, which is
1269 * "Nickname" command
1271 char *
1272 printer_name(char *input)
1274 char *nick, *cmd;
1275 char *ret;
1277 parse_printer(input, &nick, &cmd, NULL, NULL, NULL, NULL);
1278 ret = (char *)fs_get((2+6*22+1+strlen(cmd)) * sizeof(char));
1279 utf8_snprintf(ret, 2+6*22+1+strlen(cmd), "\"%.21w\"%*s%s",
1280 *nick ? nick : "",
1281 22 - MIN(utf8_width(nick), 21),
1283 cmd);
1284 fs_give((void **) &nick);
1285 fs_give((void **) &cmd);
1287 return(ret);