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