dtwm: basic multihead(xinerama only) support
[oweals/cde.git] / cde / programs / dtpad / printSetup.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: printSetup.c /main/14 1996/10/25 13:37:55 mgreess $ */
24 /**********************************<+>*************************************
25 ***************************************************************************
26 **
27 **  File:        printSetup.c
28 **
29 **  Project:     HP DT dtpad, a memo maker type editor based on the
30 **               Dt Editor widget.
31 **
32 **  Description:  Routines which manipulate the print setup dialog
33 **
34 **************************************************************************
35 **********************************<+>*************************************/
36 /*
37  *                   Common Desktop Environment
38  *
39  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
40  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
41  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
42  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
43  *   (c) Copyright 1995 Digital Equipment Corp.
44  *   (c) Copyright 1995 Fujitsu Limited
45  *   (c) Copyright 1995 Hitachi, Ltd.
46  *
47  *
48  *                     RESTRICTED RIGHTS LEGEND
49  *
50  *Use, duplication, or disclosure by the U.S. Government is subject to
51  *restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
52  *Technical Data and Computer Software clause in DFARS 252.227-7013.  Rights
53  *for non-DOD U.S. Government Departments and Agencies are as set forth in
54  *FAR 52.227-19(c)(1,2).
55
56  *Hewlett-Packard Company, 3000 Hanover Street, Palo Alto, CA 94304 U.S.A.
57  *International Business Machines Corp., Route 100, Somers, NY 10589 U.S.A.
58  *Sun Microsystems, Inc., 2550 Garcia Avenue, Mountain View, CA 94043 U.S.A.
59  *Novell, Inc., 190 River Road, Summit, NJ 07901 U.S.A.
60  *Digital Equipment Corp., 111 Powdermill Road, Maynard, MA 01754, U.S.A.
61  *Fujitsu Limited, 1015, Kamikodanaka Nakahara-Ku, Kawasaki 211, Japan
62  *Hitachi, Ltd., 6, Kanda Surugadai 4-Chome, Chiyoda-ku, Tokyo 101, Japan
63  */
64
65 #define REUSE_PRINT_SETUP_DIALOGS
66
67 #include <stdio.h>
68 #include <sys/param.h>
69
70 #include <X11/Intrinsic.h>
71 #include <Xm/DialogS.h>
72 #include <Xm/Form.h>
73 #include <Xm/MwmUtil.h>
74 #include <Xm/ToggleB.h>
75 #include <Dt/DtPStrings.h>
76 #include <Dt/HelpDialog.h>
77 #include <Dt/Print.h>
78 #include <Dt/Session.h>
79
80 #include "dtpad.h"
81
82 static char *_psGetResourceFileName(
83                 PrintSetup *pSetup);
84 static void _psSetupToSource(
85                 PrintSetup *pSetup);
86 static void _psSourceToSetup(
87                 PrintSetup *pSetup,
88                 Boolean wordWrap);
89 static void _psSetupToUi(
90                 PrintSetup *pSetup);
91 static void _psUiToSetup(
92                 PrintSetup *pSetup);
93 static Boolean _psUiSpecsAreValid(
94                 PrintSetup *pSetup);
95 static void _psAttachPrintSetupDialog(
96                 PrintSetup *pSetup,
97                 Editor *pPad);
98 static Widget _psCreatePrintSetupDialog(
99                 Widget parent,
100                 Editor *pPad);
101 static void _psPrintSetupCancelCB(
102                 Widget dtprintSetup,
103                 XtPointer client_data,
104                 XtPointer call_data);
105 static void _psPrintSetupDestroyCB(
106                 Widget dtprintSetup,
107                 XtPointer client_data,
108                 XtPointer call_data);
109 static void _psPrintSetupPrintCB(
110                 Widget dtprintSetup,
111                 XtPointer client_data,
112                 XtPointer call_data);
113 static void _psReleasePrintSetupDialog(
114                 PrintSetup *pSetup);
115
116 #define PS_ARRAY_SIZE(ary)      (sizeof((ary))/sizeof((ary)[0]))
117
118 #define PS_HOME_ENV_VARIABLE                    "HOME"
119 #define PS_DEFAULT_RESOURCE_FILE                "dtpadrc"
120
121 #define PS_RESOURCE_HDRFTR_FORMAT_STRING        "Dtpad.%s:  %d\n"
122 #define PS_RESOURCE_MARGIN_FORMAT_STRING        "Dtpad.%s:  %s\n"
123
124 #define PS_RESOURCE_NAME_HEADER_LEFT            "headerLeftEnum"
125 #define PS_RESOURCE_NAME_HEADER_RIGHT           "headerRightEnum"
126 #define PS_RESOURCE_NAME_FOOTER_LEFT            "footerLeftEnum"
127 #define PS_RESOURCE_NAME_FOOTER_RIGHT           "footerRightEnum"
128
129 #define PS_RESOURCE_NAME_MARGIN_TOP             "marginTopSpec"
130 #define PS_RESOURCE_NAME_MARGIN_RIGHT           "marginRightSpec"
131 #define PS_RESOURCE_NAME_MARGIN_BOTTOM          "marginBottomSpec"
132 #define PS_RESOURCE_NAME_MARGIN_LEFT            "marginLeftSpec"
133
134 #define PS_RESOURCE_VALUE_NONE                  "Empty"
135 #define PS_RESOURCE_VALUE_DATE                  "Date"
136 #define PS_RESOURCE_VALUE_DOCNAME               "DocName"
137 #define PS_RESOURCE_VALUE_PAGE_NUMBER           "PageNumber"
138 #define PS_RESOURCE_VALUE_USER_NAME             "UserName"
139
140 #define PS_RESOURCE_VALUE_DFLT_MARGIN           "1.0 in"
141
142 typedef struct resource_value
143 {
144         PrintStringTypeEnum     which;
145         char                    *resource_string;
146         int                     set_id;
147         int                     msg_id;
148         char                    *dflt_string;
149 } ResourceValue;
150
151 static ResourceValue _psHdrFtrValues[] =
152 {
153     { PRINT_NONE_STRING_TYPE_ENUM,
154       PS_RESOURCE_VALUE_NONE,
155       15, 1, "None"
156     },
157     { PRINT_DATE_STRING_TYPE_ENUM,
158       PS_RESOURCE_VALUE_DATE,
159       15, 2, "Date"
160     },
161     { PRINT_DOCNAME_STRING_TYPE_ENUM,
162       PS_RESOURCE_VALUE_DOCNAME,
163       15, 3, "Document Name"
164     },
165     { PRINT_PAGE_NUMBER_STRING_TYPE_ENUM,
166       PS_RESOURCE_VALUE_PAGE_NUMBER,
167       15, 4, "Page Number"
168     },
169     { PRINT_USER_NAME_STRING_TYPE_ENUM,
170       PS_RESOURCE_VALUE_USER_NAME,
171       15, 5, "User Name"
172     }
173 };
174                                     
175
176 static Widget           _psDefaultPrintSetupDialog = (Widget) NULL;
177 static char             *_psDefaultMargin = PS_RESOURCE_VALUE_DFLT_MARGIN;
178
179 static XtResource _psResources[] = {
180   {PS_RESOURCE_NAME_FOOTER_LEFT, "FooterLeftEnum", XmRInt, sizeof(int),
181       XtOffset(PrintOptions*, footerLeft),
182       XmRImmediate, (XtPointer) PRINT_NONE_STRING_TYPE_ENUM,
183   },
184   {PS_RESOURCE_NAME_FOOTER_RIGHT, "FooterRightEnum", XmRInt, sizeof(int),
185       XtOffset(PrintOptions*, footerRight),
186       XmRImmediate, (XtPointer) PRINT_PAGE_NUMBER_STRING_TYPE_ENUM,
187   },
188   {PS_RESOURCE_NAME_HEADER_LEFT, "HeaderLeftEnum", XmRInt, sizeof(int),
189       XtOffset(PrintOptions*, headerLeft),
190       XmRImmediate, (XtPointer) PRINT_NONE_STRING_TYPE_ENUM,
191   },
192   {PS_RESOURCE_NAME_HEADER_RIGHT, "HeaderRightEnum", XmRInt, sizeof(int),
193       XtOffset(PrintOptions*, headerRight),
194       XmRImmediate, (XtPointer) PRINT_DOCNAME_STRING_TYPE_ENUM,
195   },
196   {PS_RESOURCE_NAME_MARGIN_BOTTOM, "MarginBottomSpec", XmRString, sizeof(String),
197       XtOffset(PrintOptions*, marginBottom),
198       XmRString, (XtPointer) PS_RESOURCE_VALUE_DFLT_MARGIN,
199   },
200   {PS_RESOURCE_NAME_MARGIN_LEFT, "MarginLeftSpec", XmRString, sizeof(String),
201       XtOffset(PrintOptions*, marginLeft),
202       XmRString, (XtPointer) PS_RESOURCE_VALUE_DFLT_MARGIN,
203   },
204   {PS_RESOURCE_NAME_MARGIN_RIGHT, "MarginRightSpec", XmRString, sizeof(String),
205       XtOffset(PrintOptions*, marginRight),
206       XmRString, (XtPointer) PS_RESOURCE_VALUE_DFLT_MARGIN,
207   },
208   {PS_RESOURCE_NAME_MARGIN_TOP, "MarginTopSpec", XmRString, sizeof(String),
209       XtOffset(PrintOptions*, marginTop),
210       XmRString, (XtPointer) PS_RESOURCE_VALUE_DFLT_MARGIN,
211   }
212 };
213
214
215 /************************************************************************
216  * PrintSetupCreate
217  *     Class constructor.
218  *     Adds dtpad specific items to the passed print setup box.
219  *     The document file name is presented in the bottom work area.
220  ************************************************************************/
221 PrintSetup *
222 PrintSetupCreate(
223                 Widget  parent,
224                 char    *docName,
225                 Boolean wordWrap,
226                 Editor  *pPad,
227                 XtCallbackProc cancelCB, XtPointer cancelClosure,
228                 XtCallbackProc closeDisplayCB, XtPointer closeDisplayClosure,
229                 XtCallbackProc printCB, XtPointer printClosure,
230                 XtCallbackProc setupCB, XtPointer setupClosure
231                 )
232 {
233     Widget      w;
234     XmString    xms;
235     unsigned char is_set;
236     PrintSetup  *pSetup;
237     Widget      *menu_buttons;
238     int         nitems;
239     char        **strings;
240     void        **data;
241     int         i;
242
243     pSetup = (PrintSetup *) XtMalloc( sizeof(PrintSetup) );
244     pSetup->parent = parent;
245     pSetup->docName = strdup(docName);
246     pSetup->cancelCB = cancelCB;
247     pSetup->closeDisplayCB = closeDisplayCB;
248     pSetup->printCB = printCB;
249     pSetup->setupCB = setupCB;
250     pSetup->cancelClosure = cancelClosure;
251     pSetup->closeDisplayClosure = closeDisplayClosure;
252     pSetup->printClosure = printClosure;
253     pSetup->setupClosure = setupClosure;
254     pSetup->pPad = pPad;
255
256     pSetup->dtprintSetup = (Widget) NULL;
257     pSetup->widgets = (psWidgets *) NULL;
258
259     /*
260      * Get the current default values for the app-specific printing options.
261      */
262     _psSourceToSetup(pSetup, wordWrap);
263
264     /*
265      * Get a print setup dialog.
266      */
267     _psAttachPrintSetupDialog(pSetup, pPad);
268
269     return pSetup;
270 }
271
272 /************************************************************************
273  * PrintSetupDestroy
274  *     Class destructor.
275  ************************************************************************/
276 void
277 PrintSetupDestroy(PrintSetup *pSetup)
278 {
279     if (pSetup == NULL) return;
280
281     if (pSetup->docName)
282       free(pSetup->docName);
283     if (pSetup->dtprintSetup);
284       _psReleasePrintSetupDialog(pSetup);
285     XtFree((char*) pSetup);
286 }
287
288 /************************************************************************
289  * PrintSetupDisplay
290  *     Displays the specified print setup GUI.
291  ************************************************************************/
292 void
293 PrintSetupDisplay(PrintSetup *pSetup)
294 {
295     if (pSetup == NULL) return;
296
297     /*
298      * Initialize the print setup Ui.
299      */
300     _psSetupToUi(pSetup);
301
302     XtManageChild(pSetup->dtprintSetup);
303     XtMapWidget(pSetup->dtprintSetup);
304 }
305
306 /************************************************************************
307  * PrintSetupHide
308  *     Hides the specified print setup GUI.
309  ************************************************************************/
310 void
311 PrintSetupHide(PrintSetup *pSetup)
312 {
313     if (pSetup == NULL) return;
314     if (pSetup->dtprintSetup == NULL) return;
315     XtUnmanageChild(pSetup->dtprintSetup);
316     XtUnmapWidget(pSetup->dtprintSetup);
317 }
318
319
320 /************************************************************************
321  * PrintSetupGetHdrFtrSpec
322  *     Returns the current value of the specified header/footer print option.
323  ************************************************************************/
324 PrintStringTypeEnum
325 PrintSetupGetHdrFtrSpec(PrintSetup *pSetup, _DtPrintHdrFtrEnum which)
326 {
327     PrintStringTypeEnum rtn;
328
329     if (pSetup == NULL) return PRINT_NONE_STRING_TYPE_ENUM;
330     switch (which)
331     {
332         case DTPRINT_OPTION_HEADER_LEFT:
333             rtn = pSetup->options.headerLeft;
334             break;
335         case DTPRINT_OPTION_HEADER_RIGHT:
336             rtn = pSetup->options.headerRight;
337             break;
338         case DTPRINT_OPTION_FOOTER_LEFT:
339             rtn = pSetup->options.footerLeft;
340             break;
341         case DTPRINT_OPTION_FOOTER_RIGHT:
342         default:
343             rtn = pSetup->options.footerRight;
344             break;
345     }
346     return rtn;
347 }
348
349 /************************************************************************
350  * PrintSetupGetMarginSpec
351  *     Returns the current value of the specified margin print option.
352  ************************************************************************/
353 char *
354 PrintSetupGetMarginSpec(PrintSetup *pSetup, _DtPrintMarginEnum which)
355 {
356     char        *rtn;
357
358     if (pSetup == NULL) return _psDefaultMargin;
359     switch (which)
360     {
361         case DTPRINT_OPTION_MARGIN_TOP:
362             rtn = pSetup->options.marginTop;
363             break;
364         case DTPRINT_OPTION_MARGIN_RIGHT:
365             rtn = pSetup->options.marginRight;
366             break;
367         case DTPRINT_OPTION_MARGIN_BOTTOM:
368             rtn = pSetup->options.marginBottom;
369             break;
370         case DTPRINT_OPTION_MARGIN_LEFT:
371         default:
372             rtn = pSetup->options.marginLeft;
373             break;
374     }
375     return rtn;
376 }
377
378 /************************************************************************
379  * PrintSetupGetDefaultPrintData
380  *     Returns the current value of the print data in the pData variable.
381  ************************************************************************/
382 Boolean
383 PrintSetupGetDefaultPrintData(PrintSetup *pSetup, DtPrintSetupData *pData)
384 {
385     if (pSetup == NULL || pData == NULL) return FALSE;
386     return (DtPRINT_SUCCESS == DtPrintFillSetupData(
387                                                 pSetup->dtprintSetup,
388                                                 pData));
389 }
390
391 /************************************************************************
392  * PrintSetupUseWordWrap
393  *     Returns the current value of word wrap print option.
394  ************************************************************************/
395 Boolean
396 PrintSetupUseWordWrap(PrintSetup *pSetup)
397 {
398     if (pSetup == NULL) return TRUE;
399     return pSetup->options.wordWrap;
400 }
401
402
403
404 /*******************************************************************************
405  *******************************************************************************
406  *
407  *  Static Functions
408  *
409  *******************************************************************************
410  ******************************************************************************/
411
412 /************************************************************************
413  * _psGetResourceFileName
414  ************************************************************************/
415 static char*
416 _psGetResourceFileName(PrintSetup *pSetup)
417 {
418 #define BUFFER_SIZE 256
419     extern Widget topLevelWithWmCommand;
420     static char buffer[BUFFER_SIZE];
421     static char *dtpadrc = NULL;
422     char        *savePath, *saveFile;
423
424 #ifdef hpV4
425     return XtNewString("/tmp/dtpadrc");
426 #else
427     if (dtpadrc != NULL) return XtNewString(dtpadrc);
428
429     savePath = NULL;
430     saveFile = PS_DEFAULT_RESOURCE_FILE;
431     if (! DtSessionSavePath(topLevelWithWmCommand, &savePath, &saveFile))
432     {
433         sprintf(
434                 buffer, "%s/%s/%s",
435                 getenv(PS_HOME_ENV_VARIABLE),
436                 DtPERSONAL_TMP_DIRECTORY,
437                 PS_DEFAULT_RESOURCE_FILE);
438         savePath = buffer;
439     }
440     dtpadrc = XtNewString(savePath);
441
442     return XtNewString(dtpadrc);
443 #endif
444 }
445
446 /************************************************************************
447  * _psSourceToSetup
448  ************************************************************************/
449 static void
450 _psSourceToSetup(PrintSetup *pSetup, Boolean wordWrap)
451 {
452     XrmDatabase         database;
453     char                *dtpadrc;
454     PrintOptions        pOption;
455
456     if (pSetup == NULL) return;
457
458     dtpadrc = _psGetResourceFileName(pSetup);
459     database = XtDatabase(XtDisplay(pSetup->parent));
460     XrmCombineFileDatabase(dtpadrc, &database, TRUE);
461     XtFree(dtpadrc);
462
463     /* Get the application resources */
464     XtGetApplicationResources(
465                         pSetup->parent, &pOption,
466                         _psResources, XtNumber(_psResources),
467                         NULL, 0);
468
469     pSetup->options.footerLeft = pOption.footerLeft;
470     pSetup->options.footerRight = pOption.footerRight;
471     pSetup->options.headerLeft = pOption.headerLeft;
472     pSetup->options.headerRight = pOption.headerRight;
473     pSetup->options.marginBottom = XtNewString(pOption.marginBottom);
474     pSetup->options.marginLeft = XtNewString(pOption.marginLeft);
475     pSetup->options.marginRight = XtNewString(pOption.marginRight);
476     pSetup->options.marginTop = XtNewString(pOption.marginTop);
477     pSetup->options.wordWrap = wordWrap;
478 }
479
480 /************************************************************************
481  * _psSetupToSource
482  ************************************************************************/
483 static void
484 _psSetupToSource(PrintSetup *pSetup)
485 {
486     PrintOptions        *pOption;
487     FILE                *fp;
488     char                *dtpadrc;
489
490     if (pSetup == NULL) return;
491     pOption = &pSetup->options;
492
493     dtpadrc = _psGetResourceFileName(pSetup);
494     fp = fopen(dtpadrc, "wb");
495     if (fp == NULL)
496     {
497         /* TBD:  Error message. */
498         fprintf(
499                 stderr,
500                 "_psSetupToSource:  Cannot open resource file '%s'\n",
501                 dtpadrc);
502         return;
503     }
504     XtFree(dtpadrc);
505
506     fprintf(
507         fp,
508         PS_RESOURCE_HDRFTR_FORMAT_STRING,
509         PS_RESOURCE_NAME_HEADER_LEFT,
510         pOption->headerLeft
511         );
512
513     fprintf(
514         fp,
515         PS_RESOURCE_HDRFTR_FORMAT_STRING,
516         PS_RESOURCE_NAME_HEADER_RIGHT,
517         pOption->headerRight
518         );
519
520     fprintf(
521         fp,
522         PS_RESOURCE_HDRFTR_FORMAT_STRING,
523         PS_RESOURCE_NAME_FOOTER_LEFT,
524         pOption->footerLeft
525         );
526
527     fprintf(
528         fp,
529         PS_RESOURCE_HDRFTR_FORMAT_STRING,
530         PS_RESOURCE_NAME_FOOTER_RIGHT,
531         pOption->footerRight
532         );
533
534     fprintf(
535         fp,
536         PS_RESOURCE_MARGIN_FORMAT_STRING,
537         PS_RESOURCE_NAME_MARGIN_TOP,
538         pOption->marginTop
539         );
540
541     fprintf(
542         fp,
543         PS_RESOURCE_MARGIN_FORMAT_STRING,
544         PS_RESOURCE_NAME_MARGIN_RIGHT,
545         pOption->marginRight
546         );
547
548     fprintf(
549         fp,
550         PS_RESOURCE_MARGIN_FORMAT_STRING,
551         PS_RESOURCE_NAME_MARGIN_BOTTOM,
552         pOption->marginBottom
553         );
554
555     fprintf(
556         fp,
557         PS_RESOURCE_MARGIN_FORMAT_STRING,
558         PS_RESOURCE_NAME_MARGIN_LEFT,
559         pOption->marginLeft
560         );
561     
562     fclose(fp);
563 }
564
565 /************************************************************************
566  * _psSetupToUi
567  ************************************************************************/
568 static void
569 _psSetupToUi(PrintSetup *pSetup)
570 {
571     unsigned char       isSet;
572     Widget              frame, w;
573     PrintOptions        *pOption;
574
575     if (pSetup == NULL ||
576         pSetup->dtprintSetup == NULL ||
577         pSetup->widgets == NULL)
578       return;
579     pOption = &pSetup->options;
580
581     isSet = (pOption->wordWrap) ? XmSET : XmUNSET;
582     XtVaSetValues(pSetup->widgets->wordWrapTB, XmNset, isSet, NULL);
583
584     frame = pSetup->widgets->hdrftrFrame;
585     w = _DtPrintHdrFtrFrameEnumToWidget(frame, DTPRINT_OPTION_HEADER_LEFT);
586     _DtPrintSetHdrFtrByData(w, (void*) pOption->headerLeft);
587
588     w = _DtPrintHdrFtrFrameEnumToWidget(frame, DTPRINT_OPTION_HEADER_RIGHT);
589     _DtPrintSetHdrFtrByData(w, (void*) pOption->headerRight);
590
591     w = _DtPrintHdrFtrFrameEnumToWidget(frame, DTPRINT_OPTION_FOOTER_LEFT);
592     _DtPrintSetHdrFtrByData(w, (void*) pOption->footerLeft);
593
594     w = _DtPrintHdrFtrFrameEnumToWidget(frame, DTPRINT_OPTION_FOOTER_RIGHT);
595     _DtPrintSetHdrFtrByData(w, (void*) pOption->footerRight);
596
597     frame = pSetup->widgets->marginFrame;
598     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_TOP);
599     _DtPrintSetMarginSpec(w, pOption->marginTop);
600
601     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_RIGHT);
602     _DtPrintSetMarginSpec(w, pOption->marginRight);
603
604     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_BOTTOM);
605     _DtPrintSetMarginSpec(w, pOption->marginBottom);
606
607     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_LEFT);
608     _DtPrintSetMarginSpec(w, pOption->marginLeft);
609 }
610
611 /************************************************************************
612  * _psUiToSetup
613  ************************************************************************/
614 static void
615 _psUiToSetup(PrintSetup *pSetup)
616 {
617     XtArgVal            isSet;
618     Widget              frame, w;
619     PrintOptions        *pOption;
620     char                *marginSpec;
621     Boolean             error = FALSE;
622
623     if (pSetup == NULL ||
624         pSetup->dtprintSetup == NULL ||
625         pSetup->widgets == NULL)
626       return;
627     pOption = &pSetup->options;
628
629     XtVaGetValues(pSetup->widgets->wordWrapTB, XmNset, &isSet, NULL);
630     pOption->wordWrap = (isSet == XmUNSET) ? FALSE : TRUE;
631
632     frame = pSetup->widgets->hdrftrFrame;
633
634     w = _DtPrintHdrFtrFrameEnumToWidget(frame, DTPRINT_OPTION_HEADER_LEFT);
635     pOption->headerLeft = (PrintStringTypeEnum) _DtPrintGetHdrFtrData(w);
636
637     w = _DtPrintHdrFtrFrameEnumToWidget(frame, DTPRINT_OPTION_HEADER_RIGHT);
638     pOption->headerRight = (PrintStringTypeEnum) _DtPrintGetHdrFtrData(w);
639
640     w = _DtPrintHdrFtrFrameEnumToWidget(frame, DTPRINT_OPTION_FOOTER_LEFT);
641     pOption->footerLeft = (PrintStringTypeEnum) _DtPrintGetHdrFtrData(w);
642
643     w = _DtPrintHdrFtrFrameEnumToWidget(frame, DTPRINT_OPTION_FOOTER_RIGHT);
644     pOption->footerRight = (PrintStringTypeEnum) _DtPrintGetHdrFtrData(w);
645
646     frame = pSetup->widgets->marginFrame;
647
648     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_TOP);
649     marginSpec = _DtPrintGetMarginSpec(w);
650     if (pOption->marginTop != NULL)
651       XtFree(pOption->marginTop);
652     if (marginSpec == NULL || strcmp("", marginSpec) == 0)
653       pOption->marginTop = XtNewString(_psDefaultMargin);
654     else
655       pOption->marginTop = marginSpec;
656
657     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_RIGHT);
658     marginSpec = _DtPrintGetMarginSpec(w);
659     if (pOption->marginRight != NULL)
660       XtFree(pOption->marginRight);
661     if (marginSpec == NULL || strcmp("", marginSpec) == 0)
662       pOption->marginRight = XtNewString(_psDefaultMargin);
663     else
664       pOption->marginRight = marginSpec;
665
666     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_BOTTOM);
667     marginSpec = _DtPrintGetMarginSpec(w);
668     if (pOption->marginBottom != NULL)
669       XtFree(pOption->marginBottom);
670     if (marginSpec == NULL || strcmp("", marginSpec) == 0)
671       pOption->marginBottom = XtNewString(_psDefaultMargin);
672     else
673       pOption->marginBottom = marginSpec;
674
675     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_LEFT);
676     marginSpec = _DtPrintGetMarginSpec(w);
677     if (pOption->marginLeft != NULL)
678       XtFree(pOption->marginLeft);
679     if (marginSpec == NULL || strcmp("", marginSpec) == 0)
680       pOption->marginLeft = XtNewString(_psDefaultMargin);
681     else
682       pOption->marginLeft = marginSpec;
683 }
684
685 /************************************************************************
686  * _psUiSpecsAreValid
687  ************************************************************************/
688 static Boolean
689 _psUiSpecsAreValid(PrintSetup *pSetup)
690 {
691     unsigned char       isSet;
692     Widget              frame, w;
693     PrintOptions        *pOption;
694     char                *marginSpec;
695
696     if (pSetup == NULL ||
697         pSetup->dtprintSetup == NULL ||
698         pSetup->widgets == NULL)
699       return 0;
700     pOption = &pSetup->options;
701
702     frame = pSetup->widgets->marginFrame;
703
704     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_TOP);
705     marginSpec = _DtPrintGetMarginSpec(w);
706     if (marginSpec != NULL && strcmp("", marginSpec) != 0)
707     {
708         XtEnum  parseError = FALSE;
709
710         (void) XmConvertStringToUnits(
711                                 XtScreenOfObject(pSetup->parent),
712                                 marginSpec,
713                                 XmVERTICAL,
714                                 XmPIXELS,
715                                 &parseError);
716
717         if (parseError)
718         {
719             char        *i18nMsg;
720             char        *errMsg;
721             
722             i18nMsg = GETMESSAGE(15, 6, "Top Margin specifier is invalid:  ");
723             errMsg = (char*) XtMalloc(strlen(i18nMsg) + strlen(marginSpec) + 1);
724             sprintf(errMsg, "%s%s", i18nMsg, marginSpec);
725             Warning(pSetup->pPad, (char *) errMsg, XmDIALOG_WARNING);
726             XtFree(errMsg);
727             return FALSE;
728         }
729     }
730
731     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_RIGHT);
732     marginSpec = _DtPrintGetMarginSpec(w);
733     if (marginSpec != NULL && strcmp("", marginSpec) != 0)
734     {
735         XtEnum  parseError = FALSE;
736
737         (void) XmConvertStringToUnits(
738                                 XtScreenOfObject(pSetup->parent),
739                                 marginSpec,
740                                 XmHORIZONTAL,
741                                 XmPIXELS,
742                                 &parseError);
743
744         if (parseError)
745         {
746             char        *i18nMsg;
747             char        *errMsg;
748             
749             i18nMsg =
750               GETMESSAGE(15, 7, "Right Margin specifier is invalid:  ");
751             errMsg = (char*) XtMalloc(strlen(i18nMsg) + strlen(marginSpec) + 1);
752             sprintf(errMsg, "%s%s", i18nMsg, marginSpec);
753             Warning(pSetup->pPad, (char *) errMsg, XmDIALOG_WARNING);
754             XtFree(errMsg);
755             return FALSE;
756         }
757     }
758
759     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_BOTTOM);
760     marginSpec = _DtPrintGetMarginSpec(w);
761     if (marginSpec != NULL && strcmp("", marginSpec) != 0)
762     {
763         XtEnum  parseError = FALSE;
764
765         (void) XmConvertStringToUnits(
766                                 XtScreenOfObject(pSetup->parent),
767                                 marginSpec,
768                                 XmVERTICAL,
769                                 XmPIXELS,
770                                 &parseError);
771
772         if (parseError)
773         {
774             char        *i18nMsg;
775             char        *errMsg;
776             
777             i18nMsg =
778               GETMESSAGE(15, 8, "Bottom Margin specifier is invalid:  ");
779             errMsg = (char*) XtMalloc(strlen(i18nMsg) + strlen(marginSpec) + 1);
780             sprintf(errMsg, "%s%s", i18nMsg, marginSpec);
781             Warning(pSetup->pPad, (char *) errMsg, XmDIALOG_WARNING);
782             XtFree(errMsg);
783             return FALSE;
784         }
785     }
786
787     w = _DtPrintMarginFrameEnumToWidget(frame, DTPRINT_OPTION_MARGIN_LEFT);
788     marginSpec = _DtPrintGetMarginSpec(w);
789     if (marginSpec != NULL && strcmp("", marginSpec) != 0)
790     {
791         XtEnum  parseError = FALSE;
792
793         (void) XmConvertStringToUnits(
794                                 XtScreenOfObject(pSetup->parent),
795                                 marginSpec,
796                                 XmHORIZONTAL,
797                                 XmPIXELS,
798                                 &parseError);
799
800         if (parseError)
801         {
802             char        *i18nMsg;
803             char        *errMsg;
804             
805             i18nMsg = GETMESSAGE(15, 9, "Left Margin specifier is invalid:  ");
806             errMsg = (char*) XtMalloc(strlen(i18nMsg) + strlen(marginSpec) + 1);
807             sprintf(errMsg, "%s%s", i18nMsg, marginSpec);
808             Warning(pSetup->pPad, (char *) errMsg, XmDIALOG_WARNING);
809             XtFree(errMsg);
810             return FALSE;
811         }
812     }
813
814     return TRUE;
815 }
816
817
818 /*
819  * _psAttachPrintSetupDialog
820  *      Creates the widgets for the Setup Dialog.
821  */
822 static void
823 _psAttachPrintSetupDialog(PrintSetup *pSetup, Editor *pPad)
824 {
825     char        *title, *titlePrefix, *titleParent;
826     XmString    xms;
827     Widget      dialog;
828     unsigned char is_set;
829
830 #ifdef REUSE_PRINT_SETUP_DIALOGS
831     if (_psDefaultPrintSetupDialog != NULL)
832     {
833         /*
834          * Attempt to reuse the last print setup and print display connection.
835          */
836         pSetup->dtprintSetup = _psDefaultPrintSetupDialog;
837         _psDefaultPrintSetupDialog = NULL;
838     }
839     else
840 #endif
841     {
842         char    *dirname;
843
844         pSetup->dtprintSetup = _psCreatePrintSetupDialog(pSetup->parent, pPad);
845         dirname = getenv("HOME");
846         if (dirname)
847         {
848             char        path[MAXPATHLEN+1];
849             char        *filename;
850
851             filename = strrchr(pSetup->docName, '/');
852             if (NULL == filename)
853               filename = pSetup->docName;
854             else
855               filename++;
856             sprintf(path, "%s/%s.ps", dirname, filename);
857             XtVaSetValues(pSetup->dtprintSetup, DtNfileName, path, NULL);
858         }
859     }
860
861     /*
862      * Copy the information about the widgets into the setup.
863      */
864     XtVaGetValues(pSetup->dtprintSetup, XmNuserData, &pSetup->widgets, NULL);
865
866     /*
867      * Add the setup-specific callbacks.
868      */
869     XtAddCallback(
870                 pSetup->dtprintSetup,
871                 DtNcancelCallback,
872                 _psPrintSetupCancelCB,
873                 (XtPointer) pSetup);
874     XtAddCallback(
875                 pSetup->dtprintSetup,
876                 DtNclosePrintDisplayCallback,
877                 pSetup->closeDisplayCB,
878                 (XtPointer) pSetup->closeDisplayClosure);
879     XtAddCallback(
880                 pSetup->dtprintSetup,
881                 DtNprintCallback,
882                 _psPrintSetupPrintCB,
883                 (XtPointer) pSetup);
884     XtAddCallback(
885                 pSetup->dtprintSetup,
886                 DtNsetupCallback,
887                 pSetup->setupCB,
888                 (XtPointer) pSetup->setupClosure);
889
890     xms = XmStringCreateLocalized(pSetup->docName);
891     XtVaSetValues(pSetup->widgets->docNameLabel, XmNlabelString, xms, NULL);
892     XmStringFree(xms);
893
894     dialog = XtParent(pSetup->widgets->dtprintSetup);
895     if (NULL != dialog && XtIsShell(dialog))
896     {
897         titleParent = (char*) GETMESSAGE(7, 2, "Text Editor - ");
898         titlePrefix = (char*) GETMESSAGE(14, 23, "Print Setup - ");
899         title =
900           (char*) XtMalloc(strlen(titleParent) + strlen(titlePrefix) + strlen(pSetup->docName) + 1);
901         sprintf(title, "%s%s%s", titleParent, titlePrefix, pSetup->docName);
902         XtVaSetValues(dialog, XmNtitle, title, NULL);
903         XtFree(title);
904     }
905     else
906     {
907         fprintf(stderr, "Print Setup box is not parented to a shell\n");
908     }
909
910     is_set = (pSetup->options.wordWrap) ? XmSET : XmUNSET;
911     XtVaSetValues(pSetup->widgets->wordWrapTB, XmNset, is_set, NULL);
912 }
913
914
915 /*
916  * _psCreatePrintSetupDialog
917  *      Creates the widgets for the Setup Dialog.
918  */
919 static Widget
920 _psCreatePrintSetupDialog(Widget parent, Editor *pPad)
921 {
922     Arg         args[2];
923     int         nargs;
924     psWidgets   *widgets;
925     Widget      w;
926     XmString    xms;
927     unsigned char is_set;
928     int         nitems;
929     char        **strings;
930     void        **data;
931     int         i;
932
933     /*
934      * Create the widgets for the Setup Dialog.
935      */
936     widgets = (psWidgets *) XtMalloc(sizeof(psWidgets));
937
938     /*
939      * Create the DtPrintSetupDialog and specify that the application
940      * specific area be located below the generic area.
941      */
942     nargs=0;
943     XtSetArg(args[nargs], XmNautoUnmanage, FALSE); nargs++;
944     widgets->dtprintSetup =
945       DtCreatePrintSetupDialog(parent, "DtPrintSetup", args, nargs);
946
947     XtVaSetValues(
948         widgets->dtprintSetup,
949         DtNworkAreaLocation, DtWORK_AREA_BOTTOM,
950         XmNuserData, widgets,
951         NULL);
952
953     XtAddCallback(
954                 widgets->dtprintSetup,
955                 XmNhelpCallback,
956                 HelpPrintSetupDialogCB,
957                 (XtPointer) pPad);
958
959     XtAddCallback(
960                 widgets->dtprintSetup,
961                 XmNdestroyCallback,
962                 _psPrintSetupDestroyCB,
963                 (XtPointer) widgets);
964     /*
965      * Create the dtpad-specific setup dialog in the bottom work area
966      */
967     widgets->form = XtVaCreateManagedWidget(
968                                 "SetupForm",
969                                 xmFormWidgetClass,
970                                 widgets->dtprintSetup,
971                                 NULL);
972                  
973     XtAddCallback(
974                 widgets->form,
975                 XmNhelpCallback,
976                 HelpPrintSetupAppSpecificCB,
977                 (XtPointer) pPad);
978
979     /*
980      * Create the document name title label
981      */
982     xms = XmStringCreateLocalized( GETMESSAGE(14, 12, "Document Name: ") );
983     widgets->docLabel = XtVaCreateManagedWidget(
984                                 "DocumentLable",
985                                 xmLabelGadgetClass,
986                                 widgets->form,
987                                 XmNleftAttachment, XmATTACH_FORM,
988                                 XmNtopAttachment, XmATTACH_FORM,
989                                 XmNlabelString, xms,
990                                 NULL);
991     XmStringFree(xms);
992
993     /*
994      * Create the document name label
995      */
996     widgets->docNameLabel = XtVaCreateManagedWidget(
997                                 "DocumentName",
998                                 xmLabelGadgetClass,
999                                 widgets->form,
1000                                 XmNleftAttachment, XmATTACH_WIDGET,
1001                                 XmNleftWidget, widgets->docLabel,
1002 #if 0
1003                                 XmNrightAttachment, XmATTACH_FORM,
1004 #endif
1005                                 XmNtopAttachment, XmATTACH_FORM,
1006                                 NULL);
1007
1008     xms = XmStringCreateLocalized(GETMESSAGE(14, 13, "Wrap To Fit"));
1009     widgets->wordWrapTB = XtVaCreateManagedWidget(
1010                                 "WrapToFit",
1011                                 xmToggleButtonWidgetClass,
1012                                 widgets->form,
1013                                 XmNalignment, XmALIGNMENT_BEGINNING,
1014                                 XmNlabelString, xms,
1015                                 XmNleftAttachment, XmATTACH_FORM,
1016                                 XmNrightAttachment, XmATTACH_FORM,
1017                                 XmNtopAttachment, XmATTACH_WIDGET,
1018                                 XmNtopWidget, widgets->docLabel,
1019                                 NULL);
1020     XmStringFree(xms);
1021
1022     /*
1023      *  Create GUI for the Header/Footer options
1024      */
1025     nitems = PS_ARRAY_SIZE(_psHdrFtrValues);
1026     strings = (char **) XtMalloc( nitems * sizeof(char*) );
1027     data = (void **) XtMalloc( nitems * sizeof(void*) );
1028     for (i=0; i<nitems; i++)
1029     {
1030         data[i] = (void*) _psHdrFtrValues[i].which;
1031         strings[i] = GETMESSAGE(
1032                         _psHdrFtrValues[i].set_id, 
1033                         _psHdrFtrValues[i].msg_id,
1034                         _psHdrFtrValues[i].dflt_string
1035                         );
1036     }
1037
1038 #if 0
1039     /*
1040      *  Create GUI for the Header/Footer options
1041      */
1042     widgets->hdrftrFrame =
1043       _DtPrintCreateHdrFtrFrame(widgets->form, nitems, strings, data);
1044     XtVaSetValues(
1045                 widgets->hdrftrFrame,
1046                 XmNtopAttachment, XmATTACH_WIDGET,
1047                 XmNtopWidget, widgets->wordWrapTB,
1048                 XmNleftAttachment, XmATTACH_FORM,
1049                 NULL);
1050     XtManageChild(widgets->hdrftrFrame);
1051
1052     /*
1053      *  Create GUI for the Margin options
1054      */
1055     widgets->marginFrame = _DtPrintCreateMarginFrame(widgets->form);
1056     XtVaSetValues(
1057                 widgets->marginFrame,
1058                 XmNtopAttachment, XmATTACH_WIDGET,
1059                 XmNtopWidget, widgets->hdrftrFrame,
1060                 XmNleftAttachment, XmATTACH_FORM,
1061                 NULL);
1062     XtManageChild(widgets->marginFrame);
1063 #else
1064     /*
1065      *  Create GUI for the Margin options
1066      */
1067     widgets->marginFrame = _DtPrintCreateMarginFrame(widgets->form);
1068     XtVaSetValues(
1069                 widgets->marginFrame,
1070                 XmNtopAttachment, XmATTACH_WIDGET,
1071                 XmNtopWidget, widgets->wordWrapTB,
1072                 XmNleftAttachment, XmATTACH_FORM,
1073                 NULL);
1074     XtManageChild(widgets->marginFrame);
1075
1076     /*
1077      *  Create GUI for the Header/Footer options
1078      */
1079     widgets->hdrftrFrame =
1080       _DtPrintCreateHdrFtrFrame(widgets->form, nitems, strings, data);
1081     XtVaSetValues(
1082                 widgets->hdrftrFrame,
1083                 XmNtopAttachment, XmATTACH_WIDGET,
1084                 XmNtopWidget, widgets->wordWrapTB,
1085                 XmNtopWidget, widgets->marginFrame,
1086                 XmNleftAttachment, XmATTACH_FORM,
1087                 NULL);
1088     XtManageChild(widgets->hdrftrFrame);
1089 #endif
1090
1091     XtAddCallback(
1092                 widgets->hdrftrFrame,
1093                 XmNhelpCallback,
1094                 HelpPrintSetupPageHeadersFootersCB,
1095                 (XtPointer) pPad);
1096
1097     XtAddCallback(
1098                 widgets->marginFrame,
1099                 XmNhelpCallback,
1100                 HelpPrintSetupPageMargins,
1101                 (XtPointer) pPad);
1102
1103     XtRealizeWidget(widgets->dtprintSetup);
1104     return widgets->dtprintSetup;
1105 }
1106
1107
1108 /*
1109  * _psReleasePrintSetupDialog
1110  *      Removes setup-specific callbacks.
1111  */
1112 static void
1113 _psReleasePrintSetupDialog(PrintSetup *pSetup)
1114 {
1115     /*
1116      * Remove the setup-specific callbacks.
1117      */
1118     XtRemoveCallback(
1119                 pSetup->dtprintSetup,
1120                 DtNcancelCallback,
1121                 _psPrintSetupCancelCB,
1122                 (XtPointer) pSetup);
1123     XtRemoveCallback(
1124                 pSetup->dtprintSetup,
1125                 DtNclosePrintDisplayCallback,
1126                 pSetup->closeDisplayCB,
1127                 (XtPointer) pSetup->closeDisplayClosure);
1128     XtRemoveCallback(
1129                 pSetup->dtprintSetup,
1130                 DtNprintCallback,
1131                 _psPrintSetupPrintCB,
1132                 (XtPointer) pSetup);
1133     XtRemoveCallback(
1134                 pSetup->dtprintSetup,
1135                 DtNsetupCallback,
1136                 pSetup->setupCB,
1137                 (XtPointer) pSetup->setupClosure);
1138
1139 #ifdef REUSE_PRINT_SETUP_DIALOGS
1140     if (_psDefaultPrintSetupDialog != NULL)
1141     {
1142         /*
1143          * Attempt to reuse the last print setup and print display connection.
1144          */
1145         XtDestroyWidget(_psDefaultPrintSetupDialog);
1146         _psDefaultPrintSetupDialog = NULL;
1147     }
1148     _psDefaultPrintSetupDialog = pSetup->dtprintSetup;
1149 #else
1150     XtDestroyWidget(pSetup->dtprintSetup);
1151 #endif
1152 }
1153
1154
1155 /*
1156  * _psPrintSetupCancelCB
1157  */
1158 static void
1159 _psPrintSetupCancelCB(
1160                 Widget dtprintSetup,
1161                 XtPointer client_data,
1162                 XtPointer call_data)
1163 {
1164     PrintSetup *pSetup = (PrintSetup*) client_data;
1165
1166     PrintSetupHide(pSetup);
1167     pSetup->cancelCB(dtprintSetup, pSetup->cancelClosure, call_data);
1168 }
1169
1170
1171 /*
1172  * _psPrintSetupDestroyCB
1173  */
1174 static void
1175 _psPrintSetupDestroyCB(
1176                 Widget dtprintSetup,
1177                 XtPointer client_data,
1178                 XtPointer call_data)
1179 {
1180     psWidgets   *widgets;
1181
1182     XtVaGetValues(dtprintSetup, XmNuserData, &widgets, NULL);
1183     XtFree((XtPointer) widgets);
1184 }
1185
1186
1187 /*
1188  * _psPrintSetupPrintCB
1189  */
1190 static void
1191 _psPrintSetupPrintCB(
1192                 Widget dtprintSetup,
1193                 XtPointer client_data,
1194                 XtPointer call_data)
1195 {
1196     PrintSetup  *pSetup = (PrintSetup*) client_data;
1197     Boolean     error = FALSE;
1198
1199     if (! _psUiSpecsAreValid(pSetup)) return;
1200
1201     PrintSetupHide(pSetup);
1202     _psUiToSetup(pSetup);
1203     _psSetupToSource(pSetup);
1204     pSetup->printCB(dtprintSetup, pSetup->printClosure, call_data);
1205 }