* New version 2.26
[alpine.git] / alpine / print.c
blob61885c8559620033dab89ca1cc4ed845dbefb76c
1 /*
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 * ========================================================================
15 #include "headers.h"
16 #include "print.h"
17 #include "confscroll.h"
18 #include "keymenu.h"
19 #include "radio.h"
20 #include "status.h"
21 #include "../pith/state.h"
22 #include "../pith/mailcmd.h"
26 * Internal prototypes
28 void set_def_printer_value(char *);
29 int print_select_tool(struct pine *, int, CONF_S **, unsigned);
30 int print_edit_tool(struct pine *, int, CONF_S **, unsigned);
33 static char **def_printer_line;
34 static char no_ff[] = "-no-formfeed";
37 #ifndef DOS
40 * Information used to paint and maintain a line on the configuration screen
42 /*----------------------------------------------------------------------
43 The printer selection screen
45 Draws the screen and prompts for the printer number and the custom
46 command if so selected.
48 ----*/
49 void
50 select_printer(struct pine *ps, int edit_exceptions)
52 struct variable *vtmp;
53 CONF_S *ctmpa = NULL, *ctmpb = NULL, *heading = NULL,
54 *start_line = NULL;
55 PINERC_S *prc = NULL;
56 int i, saved_printer_cat, readonly_warning = 0, no_ex;
57 SAVED_CONFIG_S *vsave;
58 char *saved_printer, **lval;
59 OPT_SCREEN_S screen;
60 size_t l;
62 if(edit_exceptions){
63 q_status_message(SM_ORDER, 3, 7,
64 _("Exception Setup not implemented for printer"));
65 return;
68 if(fixed_var(&ps_global->vars[V_PRINTER], "change", "printer"))
69 return;
71 ew = edit_exceptions ? ps_global->ew_for_except_vars : Main;
73 no_ex = (ps_global->ew_for_except_vars == Main);
75 if(ps->restricted)
76 readonly_warning = 1;
77 else{
78 switch(ew){
79 case Main:
80 prc = ps->prc;
81 break;
82 case Post:
83 prc = ps->post_prc;
84 break;
85 default:
86 break;
89 readonly_warning = prc ? prc->readonly : 1;
90 if(prc && prc->quit_to_edit){
91 quit_to_edit_msg(prc);
92 return;
96 saved_printer = cpystr(ps->VAR_PRINTER);
97 saved_printer_cat = ps->printer_category;
99 new_confline(&ctmpa);
100 ctmpa->valoffset = 2;
101 ctmpa->keymenu = &printer_select_keymenu;
102 ctmpa->help = NO_HELP;
103 ctmpa->tool = print_select_tool;
104 ctmpa->flags |= CF_NOSELECT;
105 ctmpa->value
106 #ifdef OS2
107 = cpystr("\"Select\" a port or |pipe-command as your default printer.");
108 #else
109 = cpystr(_("You may \"Select\" a print command as your default printer."));
110 #endif
112 new_confline(&ctmpa);
113 ctmpa->valoffset = 2;
114 ctmpa->keymenu = &printer_select_keymenu;
115 ctmpa->help = NO_HELP;
116 ctmpa->tool = print_select_tool;
117 ctmpa->flags |= CF_NOSELECT;
118 ctmpa->value
119 #ifdef OS2
120 = cpystr("You may also add alternative ports or !pipes to the list in the");
121 #else
122 = cpystr(_("You may also add custom print commands to the list in the"));
123 #endif
125 new_confline(&ctmpa);
126 ctmpa->valoffset = 2;
127 ctmpa->keymenu = &printer_select_keymenu;
128 ctmpa->help = NO_HELP;
129 ctmpa->tool = print_select_tool;
130 ctmpa->flags |= CF_NOSELECT;
131 ctmpa->value
132 #ifdef OS2
133 = cpystr("\"Personally selected port or |pipe\" section below.");
134 #else
135 = cpystr(_("\"Personally selected print command\" section below."));
136 #endif
138 new_confline(&ctmpa);
139 ctmpa->valoffset = 2;
140 ctmpa->keymenu = &printer_select_keymenu;
141 ctmpa->help = NO_HELP;
142 ctmpa->tool = print_select_tool;
143 ctmpa->flags |= CF_NOSELECT | CF_B_LINE;
145 new_confline(&ctmpa);
146 ctmpa->valoffset = 4;
147 ctmpa->keymenu = &printer_select_keymenu;
148 ctmpa->help = NO_HELP;
149 ctmpa->tool = print_select_tool;
150 ctmpa->flags |= CF_NOSELECT;
151 def_printer_line = &ctmpa->value;
152 set_def_printer_value(ps->VAR_PRINTER);
154 new_confline(&ctmpa);
155 ctmpa->valoffset = 2;
156 ctmpa->keymenu = &printer_select_keymenu;
157 ctmpa->help = NO_HELP;
158 ctmpa->tool = print_select_tool;
159 ctmpa->flags |= CF_NOSELECT | CF_B_LINE;
161 #ifndef OS2
162 new_confline(&ctmpa);
163 heading = ctmpa;
164 ctmpa->keymenu = &printer_select_keymenu;
165 ctmpa->help = NO_HELP;
166 ctmpa->tool = print_select_tool;
167 ctmpa->varname
168 = cpystr(_(" Printer attached to IBM PC or compatible, Macintosh"));
169 ctmpa->flags |= (CF_NOSELECT | CF_STARTITEM);
170 ctmpa->value = cpystr("");
171 ctmpa->headingp = heading;
173 new_confline(&ctmpa);
174 ctmpa->valoffset = 6;
175 ctmpa->keymenu = &printer_select_keymenu;
176 ctmpa->help = NO_HELP;
177 ctmpa->tool = print_select_tool;
178 ctmpa->flags |= CF_NOSELECT;
179 ctmpa->value
180 = cpystr(_("This may not work with all attached printers, and will depend on the"));
181 ctmpa->headingp = heading;
183 new_confline(&ctmpa);
184 ctmpa->valoffset = 6;
185 ctmpa->keymenu = &printer_select_keymenu;
186 ctmpa->help = NO_HELP;
187 ctmpa->tool = print_select_tool;
188 ctmpa->flags |= CF_NOSELECT;
189 ctmpa->value
190 = cpystr(_("terminal emulation/communications software in use. It is known to work"));
191 ctmpa->headingp = heading;
193 new_confline(&ctmpa);
194 ctmpa->valoffset = 6;
195 ctmpa->keymenu = &printer_select_keymenu;
196 ctmpa->help = NO_HELP;
197 ctmpa->tool = print_select_tool;
198 ctmpa->flags |= CF_NOSELECT;
199 ctmpa->value
200 = cpystr("with Kermit and the latest UW version of NCSA telnet on Macs and PCs,");
201 ctmpa->headingp = heading;
203 new_confline(&ctmpa);
204 ctmpa->valoffset = 6;
205 ctmpa->keymenu = &printer_select_keymenu;
206 ctmpa->help = NO_HELP;
207 ctmpa->tool = print_select_tool;
208 ctmpa->flags |= CF_NOSELECT;
209 ctmpa->value
210 = cpystr("Versaterm Pro on Macs, and WRQ Reflections on PCs.");
211 ctmpa->headingp = heading;
213 new_confline(&ctmpa);
214 start_line = ctmpb = ctmpa; /* default start line */
215 ctmpa->valoffset = 17;
216 ctmpa->keymenu = &printer_select_keymenu;
217 ctmpa->help = h_config_set_att_ansi;
218 ctmpa->tool = print_select_tool;
219 ctmpa->flags |= CF_NOHILITE;
220 ctmpa->varoffset = 8;
221 ctmpa->varname = cpystr("Printer:");
222 ctmpa->value = cpystr(ANSI_PRINTER);
223 ctmpa->varnamep = ctmpb;
224 ctmpa->headingp = heading;
226 new_confline(&ctmpa);
227 ctmpa->valoffset = 17;
228 ctmpa->keymenu = &printer_select_keymenu;
229 ctmpa->help = h_config_set_att_ansi2;
230 ctmpa->tool = print_select_tool;
231 ctmpa->flags |= CF_NOHILITE;
232 ctmpa->varoffset = 8;
233 l = strlen(ANSI_PRINTER)+strlen(no_ff);
234 ctmpa->value = (char *)fs_get((l+1) * sizeof(char));
235 ctmpa->varnamep = ctmpb;
236 ctmpa->headingp = heading;
237 snprintf(ctmpa->value, l+1, "%s%s", ANSI_PRINTER, no_ff);
238 ctmpa->value[l] = '\0';
240 new_confline(&ctmpa);
241 ctmpa->valoffset = 17;
242 ctmpa->keymenu = &printer_select_keymenu;
243 ctmpa->help = h_config_set_att_wyse;
244 ctmpa->tool = print_select_tool;
245 ctmpa->flags |= CF_NOHILITE;
246 ctmpa->varoffset = 8;
247 ctmpa->value = cpystr(WYSE_PRINTER);
248 ctmpa->varnamep = ctmpb;
249 ctmpa->headingp = heading;
251 new_confline(&ctmpa);
252 ctmpa->valoffset = 17;
253 ctmpa->keymenu = &printer_select_keymenu;
254 ctmpa->help = h_config_set_att_wyse2;
255 ctmpa->tool = print_select_tool;
256 ctmpa->flags |= CF_NOHILITE;
257 ctmpa->varoffset = 8;
258 l = strlen(WYSE_PRINTER)+strlen(no_ff);
259 ctmpa->value = (char *)fs_get((l+1) * sizeof(char));
260 ctmpa->varnamep = ctmpb;
261 ctmpa->headingp = heading;
262 snprintf(ctmpa->value, l+1, "%s%s", WYSE_PRINTER, no_ff);
263 ctmpa->value[l] = '\0';
264 #endif
266 new_confline(&ctmpa);
267 ctmpa->valoffset = 0;
268 ctmpa->keymenu = &printer_select_keymenu;
269 ctmpa->help = NO_HELP;
270 ctmpa->tool = print_select_tool;
271 ctmpa->flags |= CF_NOSELECT | CF_B_LINE;
272 ctmpa->var = &ps->vars[V_STANDARD_PRINTER];
275 new_confline(&ctmpa);
276 heading = ctmpa;
277 ctmpa->valoffset = 6;
278 ctmpa->keymenu = &printer_select_keymenu;
279 ctmpa->help = NO_HELP;
280 ctmpa->tool = print_select_tool;
281 ctmpa->varname
282 #ifdef OS2
283 = cpystr(" Standard OS/2 printer port");
284 #else
285 = cpystr(_(" Standard UNIX print command"));
286 #endif
287 ctmpa->value = cpystr("");
288 ctmpa->flags |= (CF_NOSELECT | CF_STARTITEM);
289 ctmpa->headingp = heading;
290 ctmpa->var = &ps->vars[V_STANDARD_PRINTER];
292 new_confline(&ctmpa);
293 ctmpa->valoffset = 6;
294 ctmpa->keymenu = &printer_select_keymenu;
295 ctmpa->help = NO_HELP;
296 ctmpa->tool = print_select_tool;
297 ctmpa->flags |= CF_NOSELECT;
298 ctmpa->value
299 #ifdef OS2
300 = cpystr("Using this option may require you to use the OS/2 \"MODE\" command to");
301 #else
302 = cpystr(_("Using this option may require setting your \"PRINTER\" or \"LPDEST\""));
303 #endif
304 ctmpa->headingp = heading;
305 ctmpa->var = &ps->vars[V_STANDARD_PRINTER];
307 new_confline(&ctmpa);
308 ctmpa->valoffset = 6;
309 ctmpa->keymenu = &printer_select_keymenu;
310 ctmpa->help = NO_HELP;
311 ctmpa->tool = print_select_tool;
312 ctmpa->flags |= CF_NOSELECT;
313 ctmpa->value
314 #ifdef OS2
315 = cpystr("direct printer output to the correct port.");
316 #else
317 = cpystr(_("environment variable using the standard UNIX utilities."));
318 #endif
319 ctmpa->headingp = heading;
320 ctmpa->var = &ps->vars[V_STANDARD_PRINTER];
322 vtmp = &ps->vars[V_STANDARD_PRINTER];
323 for(i = 0; vtmp->current_val.l[i]; i++){
324 new_confline(&ctmpa);
325 ctmpa->valoffset = 22;
326 ctmpa->keymenu = &printer_select_keymenu;
327 ctmpa->help = NO_HELP;
328 ctmpa->help = h_config_set_stand_print;
329 ctmpa->tool = print_select_tool;
330 if(i == 0){
331 ctmpa->varoffset = 8;
332 ctmpa->varname = cpystr(_("Printer List:"));
333 ctmpa->flags |= CF_NOHILITE|CF_PRINTER;
334 #ifdef OS2
335 start_line = ctmpb = ctmpa; /* default start line */
336 #else
337 ctmpb = ctmpa;
338 #endif
341 ctmpa->varnamep = ctmpb;
342 ctmpa->headingp = heading;
343 ctmpa->varmem = i;
344 ctmpa->var = vtmp;
345 ctmpa->value = printer_name(vtmp->current_val.l[i]);
348 new_confline(&ctmpa);
349 ctmpa->valoffset = 0;
350 ctmpa->keymenu = &printer_select_keymenu;
351 ctmpa->help = NO_HELP;
352 ctmpa->tool = print_select_tool;
353 ctmpa->flags |= CF_NOSELECT | CF_B_LINE;
355 new_confline(&ctmpa);
356 heading = ctmpa;
357 ctmpa->valoffset = 0;
358 ctmpa->keymenu = &printer_edit_keymenu;
359 ctmpa->help = NO_HELP;
360 ctmpa->tool = print_edit_tool;
361 ctmpa->varname
362 #ifdef OS2
363 = cpystr(" Personally selected port or |command");
364 #else
365 = cpystr(_(" Personally selected print command"));
366 #endif
367 ctmpa->flags |= (CF_NOSELECT | CF_STARTITEM);
368 ctmpa->value = cpystr("");
369 ctmpa->headingp = heading;
370 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
373 new_confline(&ctmpa);
374 ctmpa->valoffset = 6;
375 ctmpa->keymenu = &printer_edit_keymenu;
376 ctmpa->help = NO_HELP;
377 ctmpa->tool = print_edit_tool;
378 ctmpa->flags |= CF_NOSELECT;
379 ctmpa->value
380 #ifdef OS2
381 = cpystr("The text to be printed will be sent to the printer or command given here.");
382 #else
383 = cpystr(_("The text to be printed will be piped into the command given here. The"));
384 #endif
385 ctmpa->headingp = heading;
386 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
388 new_confline(&ctmpa);
389 ctmpa->valoffset = 6;
390 ctmpa->keymenu = &printer_edit_keymenu;
391 ctmpa->help = NO_HELP;
392 ctmpa->tool = print_edit_tool;
393 ctmpa->flags |= CF_NOSELECT;
394 ctmpa->value
395 #ifdef OS2
396 = cpystr("The printer port or |pipe is in the 2nd column, the printer name is in");
397 #else
398 = cpystr(_("command is in the 2nd column, the printer name is in the first column. Some"));
399 #endif
400 ctmpa->headingp = heading;
401 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
403 new_confline(&ctmpa);
404 ctmpa->valoffset = 6;
405 ctmpa->keymenu = &printer_edit_keymenu;
406 ctmpa->help = NO_HELP;
407 ctmpa->tool = print_edit_tool;
408 ctmpa->flags |= CF_NOSELECT;
409 ctmpa->value
410 #ifdef OS2
411 = cpystr("the first column. Examples: \"LPT1\", \"COM2\", \"|enscript\". A command may");
412 #else
413 = cpystr(_("examples are: \"prt\", \"lpr\", \"lp\", or \"enscript\". The command may be given"));
414 #endif
415 ctmpa->headingp = heading;
416 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
418 new_confline(&ctmpa);
419 ctmpa->valoffset = 6;
420 ctmpa->keymenu = &printer_edit_keymenu;
421 ctmpa->help = NO_HELP;
422 ctmpa->tool = print_edit_tool;
423 ctmpa->flags |= CF_NOSELECT;
424 ctmpa->value
425 #ifdef OS2
426 = cpystr("be given options, for example \"|ascii2ps -p LPT1\" or \"|txt2hplc -2\". Use");
427 #else
428 = cpystr(_("with options, for example \"enscript -2 -r\" or \"lpr -Plpacc170\". The"));
429 #endif
430 ctmpa->headingp = heading;
431 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
433 new_confline(&ctmpa);
434 ctmpa->valoffset = 6;
435 ctmpa->keymenu = &printer_edit_keymenu;
436 ctmpa->help = NO_HELP;
437 ctmpa->tool = print_edit_tool;
438 ctmpa->flags |= CF_NOSELECT;
439 ctmpa->value
440 #ifdef OS2
441 = cpystr("the |command method for printers that require conversion from ASCII.");
442 #else
443 = cpystr(_("commands and options on your system may be different from these examples."));
444 #endif
445 ctmpa->headingp = heading;
446 ctmpa->var = &ps->vars[V_PERSONAL_PRINT_COMMAND];
448 vtmp = &ps->vars[V_PERSONAL_PRINT_COMMAND];
449 lval = no_ex ? vtmp->current_val.l : LVAL(vtmp, ew);
450 if(lval){
451 for(i = 0; lval[i]; i++){
452 new_confline(&ctmpa);
453 ctmpa->valoffset = 22;
454 ctmpa->keymenu = &printer_edit_keymenu;
455 ctmpa->help = h_config_set_custom_print;
456 ctmpa->tool = print_edit_tool;
457 if(i == 0){
458 ctmpa->varoffset = 8;
459 ctmpa->varname = cpystr(_("Printer List:"));
460 ctmpa->flags |= CF_NOHILITE|CF_PRINTER;
461 ctmpb = ctmpa;
464 ctmpa->varnamep = ctmpb;
465 ctmpa->headingp = heading;
466 ctmpa->varmem = i;
467 ctmpa->var = vtmp;
468 ctmpa->value = printer_name(lval[i]);
471 else{
472 new_confline(&ctmpa);
473 ctmpa->valoffset = 22;
474 ctmpa->keymenu = &printer_edit_keymenu;
475 ctmpa->help = h_config_set_custom_print;
476 ctmpa->tool = print_edit_tool;
477 ctmpa->flags |= CF_NOHILITE;
478 ctmpa->varoffset = 8;
479 ctmpa->varname = cpystr(_("Printer List:"));
480 ctmpa->varnamep = ctmpa;
481 ctmpa->headingp = heading;
482 ctmpa->varmem = 0;
483 ctmpa->var = vtmp;
484 ctmpa->value = cpystr("");
487 memset(&screen, 0, sizeof(screen));
488 screen.ro_warning = readonly_warning;
489 vsave = save_config_vars(ps, 0);
490 /* TRANSLATORS: SETUP... is a screen title
491 Print something1 using something2.
492 "printer config" is something1 */
493 switch(conf_scroll_screen(ps, &screen, start_line,
494 edit_exceptions ? _("SETUP PRINTER EXCEPTIONS")
495 : _("SETUP PRINTER"),
496 _("printer config"), 0, NULL)){
497 case 0:
498 break;
500 case 1:
501 write_pinerc(ps, ew, WRP_NONE);
502 break;
504 case 10:
505 revert_to_saved_config(ps, vsave, 0);
506 ps->printer_category = saved_printer_cat;
507 set_variable(V_PRINTER, saved_printer, 1, 0, ew);
508 set_variable(V_PERSONAL_PRINT_CATEGORY, comatose(ps->printer_category),
509 1, 0, ew);
510 if(prc)
511 prc->outstanding_pinerc_changes = 0;
513 break;
516 def_printer_line = NULL;
517 free_saved_config(ps, &vsave, 0);
518 fs_give((void **)&saved_printer);
521 #endif /* !DOS */
524 void
525 set_def_printer_value(char *printer)
527 char *p, *nick, *cmd;
528 int set, editing_norm_except_exists;
529 size_t l;
531 if(!def_printer_line)
532 return;
534 editing_norm_except_exists = ((ps_global->ew_for_except_vars != Main) &&
535 (ew == Main));
537 parse_printer(printer, &nick, &cmd, NULL, NULL, NULL, NULL);
538 p = *nick ? nick : cmd;
539 set = *p;
540 if(*def_printer_line)
541 fs_give((void **)def_printer_line);
543 l = strlen(p) + 60;
544 *def_printer_line = fs_get((l+1) * sizeof(char));
545 snprintf(*def_printer_line, l+1, "Default printer %s%s%s%s%s",
546 set ? "set to \"" : "unset", set ? p : "", set ? "\"" : "",
547 (set && editing_norm_except_exists) ? " (in exception config)" : "",
548 set ? "." : "");
549 (*def_printer_line)[l] = '\0';
551 fs_give((void **)&nick);
552 fs_give((void **)&cmd);
557 print_select_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
559 int rc, retval, no_ex, printer_msg = 0;
560 char *p, **lval, *printer_was;
561 struct variable *vtmp;
563 no_ex = (ps_global->ew_for_except_vars == Main);
565 printer_was = ps->VAR_PRINTER ? cpystr(ps->VAR_PRINTER) : NULL;
567 switch(cmd){
568 case MC_EXIT:
569 retval = config_exit_cmd(flags);
570 break;
572 case MC_CHOICE :
573 if(cl && *cl){
574 char aname[100], wname[100];
576 strncpy(aname, ANSI_PRINTER, sizeof(aname)-1);
577 aname[sizeof(aname)-1] = '\0';
578 strncat(aname, no_ff, sizeof(aname)-strlen(aname)-1);
579 strncpy(wname, WYSE_PRINTER, sizeof(wname)-1);
580 wname[sizeof(wname)-1] = '\0';
581 strncat(wname, no_ff, sizeof(wname)-strlen(wname)-1);
582 if((*cl)->var){
583 vtmp = (*cl)->var;
584 lval = (no_ex || !vtmp->is_user) ? vtmp->current_val.l
585 : LVAL(vtmp, ew);
586 rc = set_variable(V_PRINTER, lval ? lval[(*cl)->varmem] : NULL,
587 1, 0, ew);
588 if(rc == 0){
589 if(vtmp == &ps->vars[V_STANDARD_PRINTER])
590 ps->printer_category = 2;
591 else if(vtmp == &ps->vars[V_PERSONAL_PRINT_COMMAND])
592 ps->printer_category = 3;
594 set_variable(V_PERSONAL_PRINT_CATEGORY,
595 comatose(ps->printer_category), 1, 0, ew);
597 printer_msg++;
599 else
600 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
602 retval = 1;
604 else if(!strcmp((*cl)->value,ANSI_PRINTER)){
605 rc = set_variable(V_PRINTER, ANSI_PRINTER, 1, 0, ew);
606 if(rc == 0){
607 ps->printer_category = 1;
608 set_variable(V_PERSONAL_PRINT_CATEGORY,
609 comatose(ps->printer_category), 1, 0, ew);
610 printer_msg++;
612 else
613 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
615 retval = 1;
617 else if(!strcmp((*cl)->value,aname)){
618 rc = set_variable(V_PRINTER, aname, 1, 0, ew);
619 if(rc == 0){
620 ps->printer_category = 1;
621 set_variable(V_PERSONAL_PRINT_CATEGORY,
622 comatose(ps->printer_category), 1, 0, ew);
623 printer_msg++;
625 else
626 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
628 retval = 1;
630 else if(!strcmp((*cl)->value,WYSE_PRINTER)){
631 rc = set_variable(V_PRINTER, WYSE_PRINTER, 1, 0, ew);
632 if(rc == 0){
633 ps->printer_category = 1;
634 set_variable(V_PERSONAL_PRINT_CATEGORY,
635 comatose(ps->printer_category), 1, 0, ew);
636 printer_msg++;
638 else
639 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
641 retval = 1;
643 else if(!strcmp((*cl)->value,wname)){
644 rc = set_variable(V_PRINTER, wname, 1, 0, ew);
645 if(rc == 0){
646 ps->printer_category = 1;
647 set_variable(V_PERSONAL_PRINT_CATEGORY,
648 comatose(ps->printer_category), 1, 0, ew);
649 printer_msg++;
651 else
652 q_status_message(SM_ORDER,3,5, _("Trouble setting default printer"));
654 retval = 1;
656 else
657 retval = 0;
659 else
660 retval = 0;
662 if(retval){
663 ps->mangled_body = 1; /* BUG: redraw it all for now? */
664 set_def_printer_value(ps->VAR_PRINTER);
667 break;
669 default:
670 retval = -1;
671 break;
674 if(printer_msg){
675 p = NULL;
676 if(ps->VAR_PRINTER){
677 char *nick, *q;
679 parse_printer(ps->VAR_PRINTER, &nick, &q,
680 NULL, NULL, NULL, NULL);
681 p = cpystr(*nick ? nick : q);
682 fs_give((void **)&nick);
683 fs_give((void **)&q);
686 q_status_message4(SM_ORDER, 0, 3,
687 "Default printer%s %s%s%s",
688 ((!printer_was && !ps->VAR_PRINTER) ||
689 (printer_was && ps->VAR_PRINTER &&
690 !strcmp(printer_was,ps->VAR_PRINTER)))
691 ? " still" : "",
692 p ? "set to \"" : "unset",
693 p ? p : "", p ? "\"" : "");
695 if(p)
696 fs_give((void **)&p);
699 if(printer_was)
700 fs_give((void **)&printer_was);
702 return(retval);
707 print_edit_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
709 char prompt[81], sval[MAXPATH+1], name[MAXPATH+1];
710 char *nick, *p, *tmp, **newval = NULL, **ltmp = NULL;
711 char **lval, **nelval;
712 int rv = 0, skip_to_next = 0, after = 0, i = 4, j, k = 0;
713 int oeflags, changing_selected = 0, no_ex;
714 HelpType help;
715 ESCKEY_S ekey[6];
717 /* need this to preserve old behavior when no exception config file */
718 no_ex = (ps_global->ew_for_except_vars == Main);
720 if(cmd == MC_CHOICE)
721 return(print_select_tool(ps, cmd, cl, flags));
723 if(!(cl && *cl && (*cl)->var))
724 return(0);
726 nelval = no_ex ? (*cl)->var->current_val.l : LVAL((*cl)->var, ew);
727 lval = LVAL((*cl)->var, ew);
729 switch(cmd){
730 case MC_ADD: /* add to list */
731 sval[0] = '\0';
732 if(!fixed_var((*cl)->var, "add to", NULL)){
734 if(lval && (*cl)->value){
735 strncpy(prompt, _("Enter printer name : "), sizeof(prompt));
736 prompt[sizeof(prompt)-1] = '\0';
738 else if(!lval && nelval){
739 /* Add to list which doesn't exist, but default does exist */
740 ekey[0].ch = 'r';
741 ekey[0].rval = 'r';
742 ekey[0].name = "R";
743 ekey[0].label = N_("Replace");
744 ekey[1].ch = 'a';
745 ekey[1].rval = 'a';
746 ekey[1].name = "A";
747 ekey[1].label = N_("Add To");
748 ekey[2].ch = -1;
749 strncpy(prompt, _("Replace or Add To default value ? "), sizeof(prompt));
750 prompt[sizeof(prompt)-1] = '\0';
751 switch(i = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'a',
752 'x', h_config_replace_add, RB_NORM)){
753 case 'a':
754 /* Make a list of the default commands, leaving room for
755 the command we are about to add below. */
756 for(k = 0; nelval[k]; k++)
759 ltmp = (char **)fs_get((k+2) * sizeof(char *));
761 for(j = 0; j < k; j++)
762 ltmp[j] = cpystr(nelval[j]);
764 ltmp[k + 1] = ltmp[k] = NULL;
766 add_text:
767 strncpy(prompt, _("Enter name of printer to be added : "), sizeof(prompt));
768 prompt[sizeof(prompt)-1] = '\0';
769 break;
771 case 'r':
772 replace_text:
773 strncpy(prompt, _("Enter the name for replacement printer : "), sizeof(prompt));
774 prompt[sizeof(prompt)-1] = '\0';
775 break;
777 case 'x':
778 cmd_cancelled("Add");
779 break;
782 if(i == 'x')
783 break;
785 else{
786 strncpy(prompt, _("Enter name of printer to be added : "), sizeof(prompt));
787 prompt[sizeof(prompt)-1] = '\0';
790 ps->mangled_footer = 1;
791 help = NO_HELP;
793 name[0] = '\0';
794 i = 2;
795 while(i != 0 && i != 1){
796 if(lval && (*cl)->value){
797 ekey[0].ch = ctrl('W');
798 ekey[0].rval = 5;
799 ekey[0].name = "^W";
800 ekey[0].label = after ? N_("InsertBefore") : N_("InsertAfter");
801 ekey[1].ch = -1;
803 else
804 ekey[0].ch = -1;
806 oeflags = OE_APPEND_CURRENT;
807 i = optionally_enter(name, -FOOTER_ROWS(ps), 0, sizeof(name),
808 prompt,
809 (ekey[0].ch != -1) ? ekey : NULL,
810 help, &oeflags);
811 if(i == 0){
812 rv = ps->mangled_body = 1;
813 removing_leading_and_trailing_white_space(name);
815 else if(i == 1){
816 cmd_cancelled("Add");
818 else if(i == 3){
819 help = (help == NO_HELP) ? h_config_insert_after : NO_HELP;
821 else if(i == 4){ /* no redraw, yet */
823 else if(i == 5){ /* change from/to prepend to/from append */
824 after = after ? 0 : 1;
828 if(i == 0)
829 i = 2;
831 #ifdef OS2
832 strncpy(prompt, "Enter port or |command : ", sizeof(prompt));
833 #else
834 strncpy(prompt, _("Enter command for printer : "), sizeof(prompt));
835 #endif
836 prompt[sizeof(prompt)-1] = '\0';
837 while(i != 0 && i != 1){
838 oeflags = OE_APPEND_CURRENT;
839 i = optionally_enter(sval, -FOOTER_ROWS(ps), 0, sizeof(sval),
840 prompt,
841 (ekey[0].ch != -1) ? ekey : NULL,
842 help, &oeflags);
843 if(i == 0){
844 rv = ps->mangled_body = 1;
845 removing_leading_and_trailing_white_space(sval);
846 if(*sval || !lval){
848 for(tmp = sval; *tmp; tmp++)
849 if(*tmp == ',')
850 i++; /* conservative count of ,'s */
852 if(!i){ /* only one item */
853 if (!ltmp){
854 ltmp = (char **)fs_get(2 * sizeof(char *));
855 ltmp[1] = NULL;
856 k = 0;
858 if(*name){
859 size_t l;
861 l = strlen(name) + 4 + strlen(sval);
862 ltmp[k] = (char *) fs_get((l+1) * sizeof(char));
863 snprintf(ltmp[k], l+1, "%s [] %s", name, sval);
864 ltmp[k][l] = '\0';
866 else
867 ltmp[k] = cpystr(sval);
869 else{
871 * Don't allow input of multiple entries at once.
873 q_status_message(SM_ORDER,3,5,
874 _("No commas allowed in command"));
875 i = 2;
876 continue;
879 config_add_list(ps, cl, ltmp, &newval, after);
881 if(after)
882 skip_to_next = 1;
884 fs_give((void **)&ltmp);
885 k = 0;
887 else
888 q_status_message1(SM_ORDER, 0, 3,
889 _("Can't add %s to list"), empty_val);
891 else if(i == 1){
892 cmd_cancelled("Add");
894 else if(i == 3){
895 help = help == NO_HELP ? h_config_print_cmd : NO_HELP;
897 else if(i == 4){ /* no redraw, yet */
899 else if(i == 5){ /* change from/to prepend to/from append */
900 after = after ? 0 : 1;
905 break;
907 case MC_DELETE: /* delete */
908 if((*cl)->var->current_val.l
909 && (*cl)->var->current_val.l[(*cl)->varmem]
910 && !strucmp(ps->VAR_PRINTER,(*cl)->var->current_val.l[(*cl)->varmem]))
911 changing_selected = 1;
913 if(!lval && nelval){
914 char pmt[80];
916 snprintf(pmt, sizeof(pmt), _("Override default with %s"), empty_val2);
917 pmt[sizeof(pmt)-1] = '\0';
918 if(want_to(pmt, 'n', 'n', NO_HELP, WT_FLUSH_IN) == 'y'){
919 char **ltmp;
921 sval[0] = '\0';
922 ltmp = (char **)fs_get(2 * sizeof(char *));
923 ltmp[0] = cpystr(sval);
924 ltmp[1] = NULL;
925 config_add_list(ps, cl, ltmp, &newval, 0);
926 fs_give((void **)&ltmp);
927 rv = ps->mangled_body = 1;
930 else if(!lval){
931 q_status_message(SM_ORDER, 0, 3, _("No set value to delete"));
933 else{
934 if((*cl)->var->is_fixed){
935 parse_printer(lval[(*cl)->varmem],
936 &nick, &p, NULL, NULL, NULL, NULL);
937 snprintf(prompt, sizeof(prompt), _("Delete (unused) printer %s "),
938 *nick ? nick : (!*p) ? empty_val2 : p);
939 fs_give((void **)&nick);
940 fs_give((void **)&p);
942 else
943 snprintf(prompt, sizeof(prompt), _("Really delete item %s from printer list "),
944 int2string((*cl)->varmem + 1));
946 prompt[sizeof(prompt)-1] = '\0';
948 ps->mangled_footer = 1;
949 if(want_to(prompt,'n','n',h_config_print_del, WT_FLUSH_IN) == 'y'){
950 rv = ps->mangled_body = 1;
951 fs_give((void **)&lval[(*cl)->varmem]);
952 config_del_list_item(cl, &newval);
954 else
955 q_status_message(SM_ORDER, 0, 3, _("Printer not deleted"));
958 break;
960 case MC_EDIT: /* edit/change list option */
961 if((*cl)->var->current_val.l
962 && (*cl)->var->current_val.l[(*cl)->varmem]
963 && !strucmp(ps->VAR_PRINTER,(*cl)->var->current_val.l[(*cl)->varmem]))
964 changing_selected = 1;
966 if(fixed_var((*cl)->var, NULL, "printer"))
967 break;
968 else if(!lval && nelval)
969 goto replace_text;
970 else if(!lval && !nelval)
971 goto add_text;
972 else{
973 HelpType help;
975 ekey[0].ch = 'n';
976 ekey[0].rval = 'n';
977 ekey[0].name = "N";
978 ekey[0].label = N_("Name");
979 ekey[1].ch = 'c';
980 ekey[1].rval = 'c';
981 ekey[1].name = "C";
982 ekey[1].label = N_("Command");
983 ekey[2].ch = 'o';
984 ekey[2].rval = 'o';
985 ekey[2].name = "O";
986 ekey[2].label = N_("Options");
987 ekey[3].ch = -1;
988 /* TRANSLATORS: this is a question with three choices */
989 strncpy(prompt, _("Change Name or Command or Options ? "), sizeof(prompt));
990 prompt[sizeof(prompt)-1] = '\0';
991 i = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'c', 'x',
992 h_config_print_name_cmd, RB_NORM);
994 if(i == 'x'){
995 cmd_cancelled("Change");
996 break;
998 else if(i == 'c'){
999 char *all_but_cmd;
1001 parse_printer(lval[(*cl)->varmem],
1002 NULL, &p, NULL, NULL, NULL, &all_but_cmd);
1004 strncpy(prompt, _("Change command : "), sizeof(prompt));
1005 prompt[sizeof(prompt)-1] = '\0';
1006 strncpy(sval, p ? p : "", sizeof(sval)-1);
1007 sval[sizeof(sval)-1] = '\0';
1008 fs_give((void **)&p);
1010 ps->mangled_footer = 1;
1011 help = NO_HELP;
1012 while(1){
1013 oeflags = OE_APPEND_CURRENT;
1014 i = optionally_enter(sval, -FOOTER_ROWS(ps), 0,
1015 sizeof(sval), prompt, NULL,
1016 help, &oeflags);
1017 if(i == 0){
1018 removing_leading_and_trailing_white_space(sval);
1019 rv = ps->mangled_body = 1;
1020 if(lval[(*cl)->varmem])
1021 fs_give((void **)&lval[(*cl)->varmem]);
1023 i = 0;
1024 for(tmp = sval; *tmp; tmp++)
1025 if(*tmp == ',')
1026 i++; /* count of ,'s */
1028 if(!i){ /* only one item */
1029 size_t l;
1031 l = strlen(all_but_cmd) + strlen(sval);
1032 lval[(*cl)->varmem] = (char *)fs_get((l+1) * sizeof(char));
1033 snprintf(lval[(*cl)->varmem], l+1, "%s%s", all_but_cmd, sval);
1034 lval[(*cl)->varmem][l] = '\0';
1036 newval = &(*cl)->value;
1038 else{
1040 * Don't allow input of multiple entries at once.
1042 q_status_message(SM_ORDER,3,5,
1043 _("No commas allowed in command"));
1044 continue;
1047 else if(i == 1){
1048 cmd_cancelled("Change");
1050 else if(i == 3){
1051 help = help == NO_HELP ? h_config_change : NO_HELP;
1052 continue;
1054 else if(i == 4){ /* no redraw, yet */
1055 continue;
1058 break;
1061 else if(i == 'n'){
1062 char *all_but_nick;
1064 parse_printer(lval[(*cl)->varmem],
1065 &p, NULL, NULL, NULL, &all_but_nick, NULL);
1067 strncpy(prompt, _("Change name : "), sizeof(prompt));
1068 prompt[sizeof(prompt)-1] = '\0';
1069 strncpy(name, p ? p : "", sizeof(name));
1070 name[sizeof(name)-1] = '\0';
1072 fs_give((void **)&p);
1074 ps->mangled_footer = 1;
1075 help = NO_HELP;
1076 while(1){
1077 oeflags = OE_APPEND_CURRENT;
1078 i = optionally_enter(name, -FOOTER_ROWS(ps), 0,
1079 sizeof(name), prompt, NULL,
1080 help, &oeflags);
1081 if(i == 0){
1082 size_t l;
1084 rv = ps->mangled_body = 1;
1085 removing_leading_and_trailing_white_space(name);
1086 if(lval[(*cl)->varmem])
1087 fs_give((void **)&lval[(*cl)->varmem]);
1089 l = strlen(name) + 1 + ((*all_but_nick == '[') ? 0 : 3) + strlen(all_but_nick);
1090 lval[(*cl)->varmem] = (char *)fs_get((l+1) * sizeof(char));
1091 snprintf(lval[(*cl)->varmem], l+1,
1092 "%s %s%s", name,
1093 (*all_but_nick == '[') ? "" : "[] ",
1094 all_but_nick);
1095 lval[(*cl)->varmem][l] = '\0';
1097 newval = &(*cl)->value;
1099 else if(i == 1){
1100 cmd_cancelled("Change");
1102 else if(i == 3){
1103 help = help == NO_HELP ? h_config_change : NO_HELP;
1104 continue;
1106 else if(i == 4){ /* no redraw, yet */
1107 continue;
1110 break;
1113 fs_give((void **)&all_but_nick);
1115 else if(i == 'o'){
1116 HelpType help;
1118 ekey[0].ch = 'i';
1119 ekey[0].rval = 'i';
1120 ekey[0].name = "I";
1121 ekey[0].label = N_("Init");
1122 ekey[1].ch = 't';
1123 ekey[1].rval = 't';
1124 ekey[1].name = "T";
1125 ekey[1].label = N_("Trailer");
1126 ekey[2].ch = -1;
1127 strncpy(prompt, _("Change Init string or Trailer string ? "), sizeof(prompt));
1128 prompt[sizeof(prompt)-1] = '\0';
1129 j = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey, 'i', 'x',
1130 h_config_print_opt_choice, RB_NORM);
1132 if(j == 'x'){
1133 cmd_cancelled("Change");
1134 break;
1136 else{
1137 char *init, *trailer;
1139 parse_printer(lval[(*cl)->varmem],
1140 &nick, &p, &init, &trailer, NULL, NULL);
1142 if(j == i)
1143 snprintf(prompt, sizeof(prompt), _("Change INIT string : "));
1144 else
1145 snprintf(prompt, sizeof(prompt), _("Change TRAILER string : "));
1147 strncpy(sval, (j == 'i') ? init : trailer, sizeof(sval)-1);
1148 sval[sizeof(sval)-1] = '\0';
1150 tmp = string_to_cstring(sval);
1151 strncpy(sval, tmp, sizeof(sval)-1);
1152 sval[sizeof(sval)-1] = '\0';
1153 fs_give((void **)&tmp);
1155 ps->mangled_footer = 1;
1156 help = NO_HELP;
1157 while(1){
1158 oeflags = OE_APPEND_CURRENT;
1159 i = optionally_enter(sval, -FOOTER_ROWS(ps), 0,
1160 sizeof(sval), prompt, NULL, help, &oeflags);
1161 if(i == 0){
1162 size_t l;
1164 removing_leading_and_trailing_white_space(sval);
1165 rv = 1;
1166 if(lval[(*cl)->varmem])
1167 fs_give((void **)&lval[(*cl)->varmem]);
1168 if(j == 'i'){
1169 init = cstring_to_hexstring(sval);
1170 tmp = cstring_to_hexstring(trailer);
1171 fs_give((void **)&trailer);
1172 trailer = tmp;
1174 else{
1175 trailer = cstring_to_hexstring(sval);
1176 tmp = cstring_to_hexstring(init);
1177 fs_give((void **)&init);
1178 init = tmp;
1181 l = strlen(nick) + 1 + 2 + strlen("INIT=") + strlen(init) + 1 + strlen("TRAILER=") + strlen(trailer)+ 1 + strlen(p);
1182 lval[(*cl)->varmem] = (char *)fs_get((l+1) * sizeof(char));
1183 snprintf(lval[(*cl)->varmem], l+1,
1184 "%s%s%s%s%s%s%s%s%s%s%s",
1185 /* nick */ nick,
1186 /* space */ *nick ? " " : "",
1187 /* [ */ (*nick || *init || *trailer) ? "[" : "",
1188 /* INIT= */ *init ? "INIT=" : "",
1189 /* init */ init,
1190 /* space */ (*init && *trailer) ? " " : "",
1191 /* TRAILER= */ *trailer ? "TRAILER=" : "",
1192 /* trailer */ trailer,
1193 /* ] */ (*nick || *init || *trailer) ? "]" : "",
1194 /* space */ (*nick || *init || *trailer) ? " " : "",
1195 /* command */ p);
1196 lval[(*cl)->varmem][l] = '\0';
1198 newval = &(*cl)->value;
1200 else if(i == 1){
1201 cmd_cancelled("Change");
1203 else if(i == 3){
1204 help=(help == NO_HELP)?h_config_print_init:NO_HELP;
1205 continue;
1207 else if(i == 4){ /* no redraw, yet */
1208 continue;
1211 break;
1214 fs_give((void **)&nick);
1215 fs_give((void **)&p);
1216 fs_give((void **)&init);
1217 fs_give((void **)&trailer);
1222 break;
1224 case MC_EXIT: /* exit */
1225 rv = config_exit_cmd(flags);
1226 break;
1228 default:
1229 rv = -1;
1230 break;
1233 if(skip_to_next)
1234 *cl = next_confline(*cl);
1237 * At this point, if changes occurred, var->user_val.X is set.
1238 * So, fix the current_val, and handle special cases...
1240 if(rv == 1){
1241 set_current_val((*cl)->var, TRUE, FALSE);
1242 fix_side_effects(ps, (*cl)->var, 0);
1244 if(newval){
1245 if(*newval)
1246 fs_give((void **)newval);
1248 if((*cl)->var->current_val.l)
1249 *newval = printer_name((*cl)->var->current_val.l[(*cl)->varmem]);
1250 else
1251 *newval = cpystr("");
1254 if(changing_selected)
1255 print_select_tool(ps, MC_CHOICE, cl, flags);
1258 return(rv);
1263 * Given a single printer string from the config file, returns an allocated
1264 * copy of the friendly printer name, which is
1265 * "Nickname" command
1267 char *
1268 printer_name(char *input)
1270 char *nick, *cmd;
1271 char *ret;
1273 parse_printer(input, &nick, &cmd, NULL, NULL, NULL, NULL);
1274 ret = (char *)fs_get((2+6*22+1+strlen(cmd)) * sizeof(char));
1275 utf8_snprintf(ret, 2+6*22+1+strlen(cmd), "\"%.21w\"%*s%s",
1276 *nick ? nick : "",
1277 22 - MIN(utf8_width(nick), 21),
1279 cmd);
1280 fs_give((void **) &nick);
1281 fs_give((void **) &cmd);
1283 return(ret);