-fpermissive to allow GCC to compile old C++
[oweals/cde.git] / cde / programs / dtmail / dtmail / DmxPrintOptions.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 /* $TOG: DmxPrintOptions.C /main/8 1997/04/30 09:44:12 mgreess $ */
24
25 /*
26  *+SNOTICE
27  *
28  *      RESTRICTED CONFIDENTIAL INFORMATION:
29  *      
30  *      The information in this document is subject to special
31  *      restrictions in a confidential disclosure agreement between
32  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
33  *      document outside HP, IBM, Sun, USL, SCO, or Univel without
34  *      Sun's specific written approval.  This document and all copies
35  *      and derivative works thereof must be returned or destroyed at
36  *      Sun's request.
37  *
38  *      Copyright 1994 Sun Microsystems, Inc.  All rights reserved.
39  *
40  *+ENOTICE
41  */
42 /*
43  *                   Common Desktop Environment
44  *
45  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
46  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
47  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
48  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
49  *   (c) Copyright 1995 Digital Equipment Corp.
50  *   (c) Copyright 1995 Fujitsu Limited
51  *   (c) Copyright 1995 Hitachi, Ltd.
52  *                                                                   
53  *
54  *                     RESTRICTED RIGHTS LEGEND                              
55  *
56  *Use, duplication, or disclosure by the U.S. Government is subject to
57  *restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
58  *Technical Data and Computer Software clause in DFARS 252.227-7013.  Rights
59  *for non-DOD U.S. Government Departments and Agencies are as set forth in
60  *FAR 52.227-19(c)(1,2).
61
62  *Hewlett-Packard Company, 3000 Hanover Street, Palo Alto, CA 94304 U.S.A.
63  *International Business Machines Corp., Route 100, Somers, NY 10589 U.S.A. 
64  *Sun Microsystems, Inc., 2550 Garcia Avenue, Mountain View, CA 94043 U.S.A.
65  *Novell, Inc., 190 River Road, Summit, NJ 07901 U.S.A.
66  *Digital Equipment Corp., 111 Powdermill Road, Maynard, MA 01754, U.S.A.
67  *Fujitsu Limited, 1015, Kamikodanaka Nakahara-Ku, Kawasaki 211, Japan
68  *Hitachi, Ltd., 6, Kanda Surugadai 4-Chome, Chiyoda-ku, Tokyo 101, Japan
69  */
70
71
72 #include <stdio.h>
73 #include <X11/Intrinsic.h>
74 #include <Xm/Xm.h>
75 #include <Xm/DialogS.h>
76 #include <Xm/Form.h>
77 #include <Xm/ToggleB.h>
78 #include <Dt/PrintOptionsP.h>
79
80 #include "Dmx.h"
81 #include "DmxPrintOptions.h"
82 #include "DtMail.hh"
83 #include "DtMailError.hh"
84 #include "dtmailopts.h"
85 #include "IndexedOptionMenuUiItem.hh"
86 #include "MailMsg.h"
87 #include "RoamApp.h"
88 #include "TextFieldUiItem.hh"
89
90 #define DMX_ARRAY_SIZE(ary)     (sizeof((ary))/sizeof((ary)[0]))
91
92 static DmxpoPropKey hdrftr_keys[] =
93 {
94     { (int) DTPRINT_OPTION_HEADER_LEFT,
95       DMX_PROPKEY_HEADER_LEFT,
96       DMX_PROPVAL_SUBJECT_HEADER
97     },
98     { (int) DTPRINT_OPTION_HEADER_RIGHT,
99       DMX_PROPKEY_HEADER_RIGHT,
100       DMX_PROPVAL_EMPTY
101     },
102     { (int) DTPRINT_OPTION_FOOTER_LEFT,
103       DMX_PROPKEY_FOOTER_LEFT,
104       DMX_PROPVAL_USER_NAME
105     },
106     { (int) DTPRINT_OPTION_FOOTER_RIGHT,
107       DMX_PROPKEY_FOOTER_RIGHT,
108       DMX_PROPVAL_PAGE_NUMBER
109     }
110 };
111
112 static DmxpoPropKey margin_keys[] =
113 {
114     { (int) DTPRINT_OPTION_MARGIN_TOP,
115       DMX_PROPKEY_MARGIN_TOP,
116       DMX_PROPVAL_DFLT_MARGIN
117     },
118     { (int) DTPRINT_OPTION_MARGIN_LEFT,
119       DMX_PROPKEY_MARGIN_LEFT,
120       DMX_PROPVAL_DFLT_MARGIN
121     },
122     { (int) DTPRINT_OPTION_MARGIN_BOTTOM,
123       DMX_PROPKEY_MARGIN_BOTTOM,
124       DMX_PROPVAL_DFLT_MARGIN
125     },
126     { (int) DTPRINT_OPTION_MARGIN_RIGHT,
127       DMX_PROPKEY_MARGIN_RIGHT,
128       DMX_PROPVAL_DFLT_MARGIN
129     }
130 };
131
132 static DmxpoPropValue hdrftr_values[] =
133 {
134     { (int) DMX_NONE_STRING,
135       DMX_PROPVAL_EMPTY,
136       22, 1, "Empty"
137     },
138     { (int) DMX_CC_HEADER_STRING,
139       DMX_PROPVAL_CC_HEADER,
140       22, 2, "CC Header"
141     },
142     { (int) DMX_DATE_HEADER_STRING,
143       DMX_PROPVAL_DATE_HEADER,
144       22, 3, "Date Header"
145     },
146     { (int) DMX_FROM_HEADER_STRING,
147       DMX_PROPVAL_FROM_HEADER,
148       22, 4, "From Header"
149     },
150     { (int) DMX_SUBJECT_HEADER_STRING,
151       DMX_PROPVAL_SUBJECT_HEADER,
152       22, 5, "Subject Header"
153     },
154     { (int) DMX_TO_HEADER_STRING,
155       DMX_PROPVAL_TO_HEADER,
156       22, 6, "To Header"
157     },
158     { (int) DMX_PAGE_NUMBER_STRING,
159       DMX_PROPVAL_PAGE_NUMBER,
160       22, 7, "Page Number"
161     },
162     { (int) DMX_USER_NAME_STRING,
163       DMX_PROPVAL_USER_NAME,
164       22, 8, "User Name"
165     }
166 };
167                                     
168 static DmxpoPropValue prthdr_values[] =
169 {
170     { (int) DMX_PRINT_HEADERS_NONE,
171       DMX_PROPVAL_NONE,
172       23, 1, "None" },
173     { (int) DMX_PRINT_HEADERS_STANDARD,
174       DMX_PROPVAL_STANDARD,
175       23, 2, "Standard" },
176     { (int) DMX_PRINT_HEADERS_ABBREV,
177       DMX_PROPVAL_ABBREVIATED,
178       23, 3, "Abbreviated" },
179     { (int) DMX_PRINT_HEADERS_ALL,
180       DMX_PROPVAL_ALL,
181       23, 4, "All" }
182 };
183                                     
184 static DmxpoPropValue msgsep_values[] =
185 {
186     { (int) DMX_SEPARATOR_NEW_LINE,
187       DMX_PROPVAL_NEW_LINE,
188       24, 1, "New Line" },
189     { (int) DMX_SEPARATOR_BLANK_LINE,
190       DMX_PROPVAL_BLANK_LINE,
191       24, 2, "Blank Line" },
192     { (int) DMX_SEPARATOR_CHARACTER_LINE,
193       DMX_PROPVAL_CHARACTER_LINE,
194       24, 3, "Character Line" },
195     { (int) DMX_SEPARATOR_PAGE_BREAK,
196       DMX_PROPVAL_PAGE_BREAK,
197       24, 4, "New Page" }
198 };
199                                     
200
201
202 DmxPrintOptions::DmxPrintOptions (
203                                 Widget parent
204                                 ) : UIComponent( "PrintOptions" )
205 {
206     IndexedOptionMenu   *iom = (IndexedOptionMenu *) NULL;
207     PropUiItem          *pui = (PropUiItem  *) NULL;
208     Widget              *menu_buttons, w;
209     int                 nitems;
210     char                **strings;
211     void                **data;
212     XmString            xms;
213
214     _iom_array = new DtVirtArray<IndexedOptionMenu *>(10);
215     _propui_array = new DtVirtArray<PropUiItem *>(10);
216     _propui_array_iterator = 0;
217     _parent = parent;
218
219     //
220     //  Create form to hold the printing options
221     //
222     _form = XtVaCreateWidget(
223                                 "PrintingOptionsPane",
224                                 xmFormWidgetClass,
225                                 _parent,
226                                 XmNbottomAttachment, XmATTACH_FORM,
227                                 XmNrightAttachment, XmATTACH_FORM,
228                                 XmNleftAttachment, XmATTACH_FORM,
229                                 XmNtopAttachment, XmATTACH_FORM,
230                                 XmNresizePolicy, XmRESIZE_ANY,
231                                 NULL
232                                 );
233     if (_form == (Widget) NULL) return;
234     _w = _form;
235     installDestroyHandler();
236
237     //
238     //  Create GUI for the Header/Footer options
239     //
240     nitems = DMX_ARRAY_SIZE(hdrftr_values);;
241     strings = (char **) XtMalloc( nitems * sizeof(char*) );
242     data = (void **) XtMalloc( nitems * sizeof(void*) );
243     for (int i=0; i<nitems; i++)
244     {
245         data[i] = (void*) hdrftr_values[i].prop_string;
246         strings[i] = GETMSG(
247                         DT_catd, 
248                         hdrftr_values[i].set_id, 
249                         hdrftr_values[i].msg_id,
250                         hdrftr_values[i].dflt_string
251                         );
252     }
253
254     _hdrftr_frame = _DtPrintCreateHdrFtrFrame( _form, nitems, strings, data);
255     XtVaSetValues(
256                 _hdrftr_frame,
257                 XmNtopAttachment, XmATTACH_FORM,
258                 XmNleftAttachment, XmATTACH_FORM,
259                 NULL
260                 );
261     XtManageChild(_hdrftr_frame);
262
263     //
264     //  Create PropUiItem's for the Header/Footer options
265     //
266     menu_buttons = NULL;
267     _DtPrintHdrFtrFrameMenuWidgets( _hdrftr_frame, NULL, NULL, &menu_buttons);
268     for (int j=0, nhdrftrs=DMX_ARRAY_SIZE(hdrftr_keys); j<nhdrftrs; j++)
269     {
270         w = _DtPrintHdrFtrFrameEnumToWidget(
271                                 _hdrftr_frame,
272                                 (_DtPrintHdrFtrEnum) hdrftr_keys[j].which
273                                 );
274         iom =
275           new IndexedOptionMenu(w, nitems, (char**)strings, data, menu_buttons);
276         iom->manage();
277         _iom_array->append(iom);
278
279         pui = (PropUiItem *) new IndexedOptionMenuUiItem(
280                                                         iom,
281                                                         _FROM_MAILRC,
282                                                         hdrftr_keys[j].key
283                                                         );
284         _propui_array->append(pui);
285     }
286     XtFree((char*) menu_buttons);
287     XtFree((char*) data);
288     XtFree((char*) strings);
289
290
291     //
292     //  Create GUI for the Margin options
293     //
294     _margin_frame = _DtPrintCreateMarginFrame(_form);
295     XtVaSetValues(
296                 _margin_frame,
297                 XmNtopAttachment, XmATTACH_WIDGET,
298                 XmNtopWidget, _hdrftr_frame,
299                 XmNleftAttachment, XmATTACH_FORM,
300                 NULL
301                 );
302     XtManageChild(_margin_frame);
303
304     //
305     //  Create PropUiItem's for the Margin options
306     //
307     nitems = DMX_ARRAY_SIZE(margin_keys);
308     for (j=0; j<nitems; j++)
309     {
310         w = _DtPrintMarginFrameEnumToWidget(
311                                 _margin_frame,
312                                 (_DtPrintMarginEnum) margin_keys[j].which
313                                 );
314         pui = (PropUiItem *) new TextFieldUiItem(
315                                         w,
316                                         _FROM_MAILRC,
317                                         margin_keys[j].key,
318                                         DmxPrintOptions::isValidMarginSpec,
319                                         (void*) margin_keys[j].which);
320         _propui_array->append(pui);
321     }
322
323
324     //
325     //  Create GUI for the Printed Headers option
326     //
327     nitems = DMX_ARRAY_SIZE(prthdr_values);;
328     strings = (char **) XtMalloc( nitems * sizeof(char*) );
329     data = (void **) XtMalloc( nitems * sizeof(void*) );
330     for (i=0; i<nitems; i++)
331     {
332         data[i] = (void*) prthdr_values[i].prop_string;
333         strings[i] = GETMSG(
334                         DT_catd, 
335                         prthdr_values[i].set_id, 
336                         prthdr_values[i].msg_id,
337                         prthdr_values[i].dflt_string
338                         );
339     }
340
341     iom = new IndexedOptionMenu(_form, nitems, (char**) strings, data);
342     xms = XmStringCreateLocalized(
343                 GETMSG(DT_catd, 25, 1, "Printed Message Headers:  ")
344                 );
345     XtVaSetValues(
346                 iom->baseWidget(),
347                 XmNlabelString, xms,
348                 XmNtopAttachment, XmATTACH_WIDGET,
349                 XmNtopWidget, _margin_frame,
350                 XmNrightAttachment, XmATTACH_FORM,
351                 XmNleftAttachment, XmATTACH_FORM,
352                 NULL
353                 );
354     iom->manage();
355     _prthdr_iom = iom;
356     _iom_array->append(iom);
357
358     XmStringFree(xms);
359     XtFree((char*) strings);
360     XtFree((char*) data);
361
362     //
363     //  Create PropUiItem for the Printed Headers option
364     //
365     pui = (PropUiItem *) new IndexedOptionMenuUiItem(
366                                                 iom,
367                                                 _FROM_MAILRC,
368                                                 DMX_PROPKEY_PRINT_HEADERS
369                                                 );
370     _propui_array->append(pui);
371
372
373     //
374     //  Create GUI for the Message Separator option
375     //
376     nitems = DMX_ARRAY_SIZE(msgsep_values);;
377     strings = (char **) XtMalloc( nitems * sizeof(char*) );
378     data = (void **) XtMalloc( nitems * sizeof(void*) );
379     for (i=0; i<nitems; i++)
380     {
381         data[i] = (void*) msgsep_values[i].prop_string;
382         strings[i] = GETMSG(
383                         DT_catd, 
384                         msgsep_values[i].set_id, 
385                         msgsep_values[i].msg_id,
386                         msgsep_values[i].dflt_string
387                         );
388     }
389
390     iom = new IndexedOptionMenu(_form, nitems, (char**) strings, data);
391     xms = XmStringCreateLocalized(
392                 GETMSG( DT_catd, 25, 2, "Separate Multiple Messages With:  ")
393                 );
394     XtVaSetValues(
395                 iom->baseWidget(),
396                 XmNlabelString, xms,
397                 XmNtopAttachment, XmATTACH_WIDGET,
398                 XmNtopWidget, _prthdr_iom->baseWidget(),
399                 XmNrightAttachment, XmATTACH_FORM,
400                 XmNleftAttachment, XmATTACH_FORM,
401                 XmNbottomAttachment, XmATTACH_FORM,
402                 NULL
403                 );
404     iom->manage();
405     _iom_array->append(iom);
406     _msgsep_iom = iom;
407
408     XmStringFree(xms);
409     XtFree((char*) strings);
410     XtFree((char*) data);
411
412     //
413     //  Create PropUiItem for the Message Separator option
414     //
415     pui = (PropUiItem *) new IndexedOptionMenuUiItem(
416                                                 iom,
417                                                 _FROM_MAILRC,
418                                                 DMX_PROPKEY_MESSAGE_SEPARATOR);
419     _propui_array->append(pui);
420
421     //XtRealizeWidget(_w);
422     //XtManageChild(_w);
423 }
424
425
426 DmxPrintOptions::~DmxPrintOptions (void)
427 {
428     int i;
429     PropUiItem          *pui;;
430     IndexedOptionMenu   *iom;
431
432     if (_propui_array)
433       for (i=0; i<_propui_array->length(); i++)
434       {
435           pui = (*_propui_array)[i];
436           delete pui;
437       }
438
439     if (_iom_array)
440       for (i=0; i<_iom_array->length(); i++)
441       {
442           iom = (*_iom_array)[i];
443           delete iom;
444       }
445
446     if (_w)
447       XtDestroyWidget(_w);
448 }
449
450 PropUiItem *
451 DmxPrintOptions::getFirstProp(void)
452 {
453     _propui_array_iterator = 0;
454     return getNextProp();
455 }
456
457 PropUiItem *
458 DmxPrintOptions::getNextProp(void)
459 {
460     PropUiItem  *pui = (PropUiItem  *) NULL;
461
462     if (_propui_array_iterator < _propui_array->length())
463     {
464         pui = (*_propui_array)[_propui_array_iterator];
465         _propui_array_iterator++;
466     }
467     return pui;
468 }
469
470 int
471 DmxPrintOptions::getNumProps(void)
472 {
473     return _propui_array->length();
474 }
475
476 const char *
477 DmxPrintOptions::getSeparatorString(void)
478 {
479     DtMail::Session     *d_session = NULL;
480     DtMail::MailRc      *m_rc = NULL;
481     DtMailEnv           error;
482     const char          *string = NULL;
483     char                *dflt = "-";
484
485     d_session = theRoamApp.session()->session();
486     m_rc = d_session->mailRc(error);
487
488     m_rc->getValue(error, DMX_PROPKEY_SEPARATOR_STRING, &string);
489     if (string == NULL || error.isSet())
490       return strdup(dflt);
491
492     return string;
493 }
494
495 DmxStringTypeEnum
496 DmxPrintOptions::getHdrFtrSpec(_DtPrintHdrFtrEnum which)
497 {
498     DtMail::Session     *d_session = NULL;
499     DtMail::MailRc      *m_rc = NULL;
500     DtMailEnv           error;
501     DmxpoPropKey        *key;
502     const char          *string = NULL;
503     DmxpoPropValue      *value = NULL;
504     DmxStringTypeEnum   rtn = DMX_NONE_STRING;
505
506     d_session = theRoamApp.session()->session();
507     m_rc = d_session->mailRc(error);
508
509     key = DmxPrintOptions::enumToPropKey(
510                                 which,
511                                 DMX_ARRAY_SIZE(hdrftr_keys),
512                                 hdrftr_keys
513                                 );
514
515     if (key != NULL)
516     {
517         m_rc->getValue(error, key->key , &string);
518         if (string == NULL || error.isSet())
519           string = strdup(key->dflt_prop_string);
520     }
521     else
522       return rtn;
523
524     value = stringToPropValue(
525                         string,
526                         DMX_ARRAY_SIZE(hdrftr_values),
527                         hdrftr_values);
528     if (value != NULL)
529       rtn = (DmxStringTypeEnum) value->which;
530
531     if (NULL != string)
532       free((void*) string);
533
534     return rtn;
535 }
536
537 const char *
538 DmxPrintOptions::getMarginSpec(_DtPrintMarginEnum which)
539 {
540     DtMail::Session     *d_session = NULL;
541     DtMail::MailRc      *m_rc = NULL;
542     DtMailEnv           error;
543     DmxpoPropKey        *key;
544     const char          *string = NULL;
545
546     d_session = theRoamApp.session()->session();
547     m_rc = d_session->mailRc(error);
548
549     key = DmxPrintOptions::enumToPropKey(
550                                 which,
551                                 DMX_ARRAY_SIZE(margin_keys),
552                                 margin_keys
553                                 );
554
555     if (key == NULL)
556       return DMX_PROPVAL_DFLT_MARGIN;
557
558     m_rc->getValue(error, key->key , &string);
559     if (string == NULL || error.isSet())
560       string = strdup(key->dflt_prop_string);
561
562     return string;
563 }
564
565 DmxMsgSeparatorEnum
566 DmxPrintOptions::getMessageSeparator(void)
567 {
568     DtMail::Session     *d_session = NULL;
569     DtMail::MailRc      *m_rc = NULL;
570     DtMailEnv           error;
571     const char          *string = NULL;
572     DmxpoPropValue      *value = NULL;
573     DmxMsgSeparatorEnum rtn = DMX_SEPARATOR_PAGE_BREAK;
574
575     d_session = theRoamApp.session()->session();
576     m_rc = d_session->mailRc(error);
577
578     m_rc->getValue(error, DMX_PROPKEY_MESSAGE_SEPARATOR , &string);
579     if (string == NULL || error.isSet())
580       return rtn;
581
582     value = stringToPropValue(
583                         string,
584                         DMX_ARRAY_SIZE(msgsep_values),
585                         msgsep_values);
586     if (value != NULL)
587       rtn = (DmxMsgSeparatorEnum) value->which;
588
589     if (NULL != string)
590       free((void*) string);
591
592     return rtn;
593 }
594
595 DmxPrintHeadersEnum
596 DmxPrintOptions::getPrintedHeaders(void)
597 {
598     DtMail::Session     *d_session = NULL;
599     DtMail::MailRc      *m_rc = NULL;
600     DtMailEnv           error;
601     const char          *string = NULL;
602     DmxpoPropValue      *value = NULL;
603     DmxPrintHeadersEnum rtn = DMX_PRINT_HEADERS_STANDARD;
604
605     d_session = theRoamApp.session()->session();
606     m_rc = d_session->mailRc(error);
607
608     m_rc->getValue(error, DMX_PROPKEY_PRINT_HEADERS , &string);
609     if (string == NULL || error.isSet())
610       return rtn;
611
612     value = stringToPropValue(
613                         string,
614                         DMX_ARRAY_SIZE(prthdr_values),
615                         prthdr_values);
616     if (value != NULL)
617       rtn = (DmxPrintHeadersEnum) value->which;
618
619     if (NULL != string)
620       free((void*) string);
621
622     return rtn;
623 }
624
625 DmxpoPropKey *
626 DmxPrintOptions::enumToPropKey(int which, int nkeys, DmxpoPropKey *keys)
627 {
628     for (int i=0; i<nkeys; i++)
629       if (keys[i].which == which)
630         return &(keys[i]);
631     
632     return NULL;
633 }
634
635 PropUiItem *
636 DmxPrintOptions::propKeyToPropItem(char *key)
637 {
638     for (int i=0; i<_propui_array->length(); i++)
639     {
640         PropUiItem      *pui;
641         char            *puikey;
642
643         pui = (*_propui_array)[i];
644         puikey = pui->getKey();
645         if (strcmp(puikey, key) == 0)
646           return pui;
647     }
648     
649     return NULL;
650 }
651
652 DmxpoPropValue *
653 DmxPrintOptions::stringToPropValue(
654                                 const char *string,
655                                 int nvalues,
656                                 DmxpoPropValue *values
657                                 )
658 {
659     for (int i=0; i<nvalues; i++)
660       if (strcmp(values[i].prop_string, string) == 0)
661         return &(values[i]);
662     
663     return NULL;
664 }
665
666 char *
667 DmxPrintOptions::isValidMarginSpec(PropUiItem* pui, void* data)
668 {
669     char        *i18nMsg;
670     char        *errMsg = NULL;
671     char        *marginSpec = NULL;
672     XtEnum      parseError;
673     Widget      text;
674     _DtPrintMarginEnum which = (_DtPrintMarginEnum) data;
675
676     text = pui->getWidget();
677     if (text)
678       marginSpec = _DtPrintGetMarginSpec(text);
679
680     parseError = FALSE;
681     if (marginSpec == NULL || strcmp("", marginSpec) == 0)
682       parseError = TRUE;
683     else 
684       (void) XmConvertStringToUnits(
685                                 XtScreenOfObject(text),
686                                 marginSpec,
687                                 XmVERTICAL,
688                                 XmPIXELS,
689                                 &parseError);
690  
691     if (! parseError) return NULL;
692  
693     switch (which)
694     {
695       case DTPRINT_OPTION_MARGIN_TOP:
696         i18nMsg =
697           GETMSG(DT_catd, 26, 1, "Top Margin specifier is invalid:  ");
698         break;
699       case DTPRINT_OPTION_MARGIN_RIGHT:
700         i18nMsg =
701           GETMSG(DT_catd, 26, 2, "Right Margin specifier is invalid:  ");
702         break;
703       case DTPRINT_OPTION_MARGIN_BOTTOM:
704         i18nMsg =
705           GETMSG(DT_catd, 26, 3, "Bottom Margin specifier is invalid:  ");
706         break;
707       case DTPRINT_OPTION_MARGIN_LEFT:
708         i18nMsg =
709           GETMSG(DT_catd, 26, 4, "Left Margin specifier is invalid:  ");
710         break;
711     }
712     errMsg = (char*) XtMalloc(strlen(i18nMsg) + strlen(marginSpec) + 1);
713     sprintf(errMsg, "%s%s", i18nMsg, marginSpec);
714     
715     return errMsg;
716 }