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