2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $TOG: printOutput.c /main/6 1997/07/07 15:06:25 mgreess $ */
24 /**********************************<+>*************************************
25 ***************************************************************************
27 ** File: printOption.c
29 ** Project: HP DT dtpad, a memo maker type editor based on the
32 ** Description: Routines which manipulate the print setup dialog
34 **************************************************************************
35 **********************************<+>*************************************/
37 * Common Desktop Environment
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.
48 * RESTRICTED RIGHTS LEGEND
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).
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
70 #include <X11/Intrinsic.h>
72 #include <Xm/DialogS.h>
77 #include <Dt/Editor.h>
82 #define WRITE_ACCESS 2
84 static void _poSetInnerPageDimensions(
91 static int _poDoGetLinesPerPage(PrintOutput*);
92 static int _poGetTopPosition(PrintOutput *pOutput);
93 static DtEditorErrorCode
94 _poGetFileContents(char **contents, char *file);
95 static DtEditorErrorCode
96 _poStripEmbeddedNulls(char *strbuf, int *len);
97 extern DtEditorErrorCode
98 _poEditorValidateFileAccess(char *file, int accessType);
101 * Used to initialize the top, right, bottom, and left margins
102 * between the outside edge of the page (_form) and the inner
103 * page that is written on.
105 const char *const _poDefaultMargin = ".5in";
107 /************************************************************************
109 * Creates and initialiazes a new PrintOutput output including the
111 ************************************************************************/
113 PrintOutputCreate(Widget shell)
117 PrintOutput *pOutput;
119 pOutput = (PrintOutput *) XtMalloc(sizeof(PrintOutput));
120 pOutput->pShell = shell;
122 pOutput->currentLine = 0;
123 pOutput->linesPerPage = 0;
125 w = XtVaCreateWidget("Page",
128 XmNresizePolicy, XmRESIZE_NONE,
132 w = XtVaCreateWidget("InnerPage",
135 XmNresizePolicy, XmRESIZE_NONE,
137 pOutput->innerPage = w;
139 w = XtVaCreateManagedWidget("HeaderLeft",
142 XmNalignment, XmALIGNMENT_BEGINNING,
143 XmNleftAttachment, XmATTACH_FORM,
144 XmNtopAttachment, XmATTACH_FORM,
146 pOutput->headerLeft = w;
148 w = XtVaCreateManagedWidget("HeaderRight",
151 XmNalignment, XmALIGNMENT_END,
152 XmNrightAttachment, XmATTACH_FORM,
153 XmNleftAttachment, XmATTACH_WIDGET,
154 XmNleftWidget, pOutput->headerLeft,
155 XmNtopAttachment, XmATTACH_FORM,
157 pOutput->headerRight = w;
159 w = XtVaCreateManagedWidget("Editor",
166 DtNscrollVertical, FALSE,
167 DtNscrollHorizontal, FALSE,
168 DtNshowStatusLine, FALSE,
170 XmNeditMode, XmMULTI_LINE_EDIT,
171 XmNleftAttachment, XmATTACH_FORM,
172 XmNrightAttachment, XmATTACH_FORM,
173 XmNtopAttachment, XmATTACH_WIDGET,
174 XmNtopWidget, pOutput->headerLeft,
178 w = XtVaCreateManagedWidget("FooterLeft",
181 XmNalignment, XmALIGNMENT_BEGINNING,
182 XmNleftAttachment, XmATTACH_FORM,
183 XmNbottomAttachment, XmATTACH_FORM,
185 pOutput->footerLeft = w;
187 w = XtVaCreateManagedWidget("FooterRight",
190 XmNalignment, XmALIGNMENT_END,
191 XmNleftAttachment, XmATTACH_WIDGET,
192 XmNleftWidget, pOutput->footerLeft,
193 XmNrightAttachment, XmATTACH_FORM,
194 XmNbottomAttachment, XmATTACH_FORM,
196 pOutput->footerRight = w;
200 XmNbottomAttachment, XmATTACH_WIDGET,
201 XmNbottomWidget, pOutput->footerLeft,
204 XtManageChild(pOutput->innerPage);
205 XtManageChild(pOutput->page);
207 PrintOutputSetPageMargins(
214 assert(parseError == 0);
219 /************************************************************************
222 ************************************************************************/
224 PrintOutputDestroy(PrintOutput *pOutput)
226 if (pOutput == NULL) return;
227 XtDestroyWidget(pOutput->page);
228 XtFree((char*) pOutput);
231 /************************************************************************
232 * PrintOutputHideFooter
233 * PrintOutputShowFooter
234 * PrintOutputHideHeader
235 * PrintOutputShowHeader
236 * Unmanages/Manages the footer/header widgets
237 ************************************************************************/
239 PrintOutputHideFooters(PrintOutput *pOutput)
241 XtUnmanageChild(pOutput->footerLeft);
242 XtUnmanageChild(pOutput->footerRight);
243 XtVaSetValues(pOutput->editor, XmNbottomAttachment, XmATTACH_FORM, NULL);
247 PrintOutputShowFooters(PrintOutput *pOutput)
249 XtManageChild(pOutput->footerLeft);
250 XtManageChild(pOutput->footerRight);
253 XmNbottomAttachment, XmATTACH_WIDGET,
254 XmNbottomWidget, pOutput->footerLeft,
259 PrintOutputHideHeaders(PrintOutput *pOutput)
261 XtUnmanageChild(pOutput->headerLeft);
262 XtUnmanageChild(pOutput->headerRight);
263 XtVaSetValues(pOutput->editor, XmNtopAttachment, XmATTACH_FORM, NULL);
267 PrintOutputShowHeaders(PrintOutput *pOutput)
269 XtManageChild(pOutput->headerLeft);
270 XtManageChild(pOutput->headerRight);
273 XmNtopAttachment, XmATTACH_WIDGET,
274 XmNtopWidget, pOutput->headerLeft,
278 /************************************************************************
279 * PrintOutputSetHdrFtrString
280 * Set the contents of the specifies header/footer
281 ************************************************************************/
283 PrintOutputSetHdrFtrString(
284 PrintOutput *pOutput,
285 _DtPrintHdrFtrEnum which,
292 if (contents == (char *) NULL)
297 case DTPRINT_OPTION_HEADER_LEFT:
298 w = pOutput->headerLeft;
300 case DTPRINT_OPTION_HEADER_RIGHT:
301 w = pOutput->headerRight;
303 case DTPRINT_OPTION_FOOTER_LEFT:
304 w = pOutput->footerLeft;
306 case DTPRINT_OPTION_FOOTER_RIGHT:
307 w = pOutput->footerRight;
313 xms = XmStringCreateLocalized(contents);
314 XtVaSetValues(w, XmNlabelString, xms, NULL);
318 /************************************************************************
319 * PrintOutputSetHdrFtrStrings
320 * Set the contents of all the header/footers
321 ************************************************************************/
323 PrintOutputSetHdrFtrStrings(
324 PrintOutput *pOutput,
335 xms = XmStringCreateLocalized(hdrLeft);
336 XtVaSetValues(pOutput->headerLeft, XmNlabelString, xms, NULL);
342 xms = XmStringCreateLocalized(hdrRight);
343 XtVaSetValues(pOutput->headerRight, XmNlabelString, xms, NULL);
349 xms = XmStringCreateLocalized(ftrLeft);
350 XtVaSetValues(pOutput->footerLeft, XmNlabelString, xms, NULL);
356 xms = XmStringCreateLocalized(ftrRight);
357 XtVaSetValues(pOutput->footerRight, XmNlabelString, xms, NULL);
362 /************************************************************************
363 * PrintOutputSetPageMargin
364 * Set the contents of the specified page margin
365 ************************************************************************/
367 PrintOutputSetPageMargin(
368 PrintOutput *pOutput,
369 _DtPrintMarginEnum which,
375 XtEnum xtParseError = FALSE;
376 char *marginString = XtNewString(margin);
383 case DTPRINT_OPTION_MARGIN_TOP:
384 pixels = XmConvertStringToUnits(
385 XtScreenOfObject(pOutput->pShell),
390 if (!xtParseError && pixels > 0)
391 pOutput->marginTop = pixels;
393 case DTPRINT_OPTION_MARGIN_RIGHT:
394 pixels = XmConvertStringToUnits(
395 XtScreenOfObject(pOutput->pShell),
400 if (!xtParseError && pixels > 0)
401 pOutput->marginRight = pixels;
403 case DTPRINT_OPTION_MARGIN_BOTTOM:
404 pixels = XmConvertStringToUnits(
405 XtScreenOfObject(pOutput->pShell),
410 if (!xtParseError && pixels > 0)
411 pOutput->marginBottom = pixels;
413 case DTPRINT_OPTION_MARGIN_LEFT:
414 pixels = XmConvertStringToUnits(
415 XtScreenOfObject(pOutput->pShell),
420 if (!xtParseError && pixels > 0)
421 pOutput->marginLeft = pixels;
428 _poSetInnerPageDimensions(
431 pOutput->marginRight,
432 pOutput->marginBottom,
433 pOutput->marginLeft);
437 XtFree(marginString);
440 /************************************************************************
441 * PrintOutputSetPageMargins
442 * Set the contents of all the page margins
443 ************************************************************************/
445 PrintOutputSetPageMargins(
446 PrintOutput *pOutput,
455 XtEnum xtParseError = FALSE;
460 margin = XtNewString(top);
461 pixels = XmConvertStringToUnits(
462 XtScreenOfObject(pOutput->pShell),
468 if (!xtParseError && pixels > 0)
470 pOutput->marginTop = pixels;
478 margin = XtNewString(right);
479 pixels = XmConvertStringToUnits(
480 XtScreenOfObject(pOutput->pShell),
486 if (!xtParseError && pixels > 0)
488 pOutput->marginRight = pixels;
496 margin = XtNewString(bottom);
497 pixels = XmConvertStringToUnits(
498 XtScreenOfObject(pOutput->pShell),
504 if (!xtParseError && pixels > 0)
506 pOutput->marginBottom = pixels;
514 margin = XtNewString(left);
515 pixels = XmConvertStringToUnits(
516 XtScreenOfObject(pOutput->pShell),
522 if (!xtParseError && pixels > 0)
524 pOutput->marginLeft = pixels;
532 _poSetInnerPageDimensions(
535 pOutput->marginRight,
536 pOutput->marginBottom,
537 pOutput->marginLeft);
541 /************************************************************************
542 * PrintOutputSetWordWrap
543 * Set the wrap to fit value in the editor
544 ************************************************************************/
546 PrintOutputSetWordWrap(PrintOutput *pOutput, Boolean onoff)
549 XtVaSetValues(pOutput->editor, DtNwordWrap, onoff, NULL);
551 XtVaSetValues(pOutput->editor, XmNwordWrap, onoff, NULL);
555 /************************************************************************
556 * PrintOutputGetLinesPerPage
557 * Returns the number of lines per page.
558 ************************************************************************/
560 PrintOutputGetLinesPerPage(PrintOutput *pOutput)
562 return ((int) pOutput->linesPerPage);
565 /************************************************************************
566 * PrintOutputGetNumLines
567 * Returns the number of lines of test in the editor.
568 ************************************************************************/
570 PrintOutputGetNumLines(PrintOutput *pOutput)
577 saveTop = pOutput->currentLine;
578 PrintOutputFirstPage(pOutput);
579 while (PrintOutputPageDown(pOutput))
580 total += pOutput->linesPerPage;
582 DtEditorGoToLine(pOutput->editor, saveTop);
583 pOutput->currentLine = saveTop;
585 XtVaGetValues(pOutput->editor, XmNtotalLines, &p, NULL);
591 /************************************************************************
593 ************************************************************************/
595 PrintOutputPageUp(PrintOutput *pOutput)
597 XmTextPosition top_before, top_after;
603 pOutput->currentLine - pOutput->linesPerPage
605 pOutput->currentLine -= pOutput->linesPerPage;
606 if (pOutput->currentLine < 1)
608 pOutput->currentLine = 1;
612 top_before = (XmTextPosition) _poGetTopPosition(pOutput);
613 XmTextScroll(pOutput->editor, -1 * pOutput->linesPerPage);
614 top_after = (XmTextPosition) _poGetTopPosition(pOutput);
615 retval = (top_before > top_after) ? TRUE : FALSE;
621 /************************************************************************
622 * PrintOutputPageDown
623 ************************************************************************/
625 PrintOutputPageDown(PrintOutput *pOutput)
627 XmTextPosition top_before, top_after;
629 top_before = (XmTextPosition) _poGetTopPosition(pOutput);
634 pOutput->currentLine + pOutput->linesPerPage
636 pOutput->currentLine += pOutput->linesPerPage;
638 XmTextScroll(pOutput->editor, pOutput->linesPerPage);
641 top_after = (XmTextPosition) _poGetTopPosition(pOutput);
642 return (top_before < top_after) ? TRUE : FALSE;
645 /************************************************************************
646 * PrintOutputFirstPage
647 ************************************************************************/
649 PrintOutputFirstPage(PrintOutput *pOutput)
652 XtVaSetValues(pOutput->editor, DtNtopCharacter, (XmTextPosition) 0, NULL);
653 pOutput->currentLine = 1;
655 XmTextSetTopCharacter(pOutput->editor, (XmTextPosition) 0);
659 /************************************************************************
660 * PrintOutputLoadFile
661 ************************************************************************/
663 PrintOutputLoadFile( PrintOutput *pOutput, char *file)
665 char *contents = NULL;
666 DtEditorErrorCode errorCode;
669 errorCode = DtEditorSetContentsFromFile(pOutput->editor, file);
671 errorCode = _poGetFileContents(&contents, file);
672 if (contents != NULL)
674 XmTextSetString(pOutput->editor, contents);
682 /************************************************************************
683 ************************************************************************
685 * Private class methods
687 * _poDoGetLinesPerPage - Returns number of rows in the editor.
688 * _poSetInnerPageDimensions- Sets the XmN x,y,width,height of InnerPage.
689 * _poGetTopPosition - Returns the position of the 1st visible char.
690 * _poGetFileContents - Returns the contents of the specified file.
691 * _poStripEmbeddedNulls - Removes any embedded NULLs (\0) in a
692 * string of length 'length'. The removal
693 * occurs in place, with 'length' set to the
694 * new, stripped length. The resulting string
695 * is terminated with a trailing NULL.
697 ************************************************************************
698 ************************************************************************/
701 _poDoGetLinesPerPage(PrintOutput *pOutput)
705 XtVaGetValues(pOutput->editor, XmNrows, &lpp, NULL);
711 _poSetInnerPageDimensions(
712 PrintOutput *pOutput,
719 XtArgVal outer_height0, outer_width0, footer_height0, header_height0;
720 Dimension inner_height, inner_width, inner_x, inner_y,
721 outer_height, outer_width,
722 editor_height, footer_height, header_height;
724 XtVaGetValues(pOutput->page,
725 XmNheight, &outer_height0,
726 XmNwidth, &outer_width0,
729 XtVaGetValues(pOutput->headerLeft,
730 XmNheight, &header_height0,
733 XtVaGetValues(pOutput->footerLeft,
734 XmNheight, &footer_height0,
737 outer_height = (Dimension)outer_height0;
738 outer_width = (Dimension)outer_width0;
739 header_height = (Dimension)header_height0;
740 footer_height = (Dimension)footer_height0;
744 inner_height = (outer_height > (Dimension) (top + bottom)) ?
745 (outer_height - (top + bottom)) :
747 inner_width = (outer_width > (Dimension) (left + right)) ?
748 (outer_width - (left + right)) :
751 (inner_height > (Dimension) (header_height + footer_height)) ?
752 (inner_height - (header_height + footer_height)) :
755 XtVaSetValues(pOutput->editor, XmNheight, editor_height, NULL);
757 XtVaSetValues(pOutput->innerPage,
758 XmNleftAttachment, XmATTACH_NONE,
759 XmNtopAttachment, XmATTACH_NONE,
762 XmNheight, inner_height,
763 XmNwidth, inner_width,
766 pOutput->linesPerPage = _poDoGetLinesPerPage(pOutput);
773 _poGetTopPosition(PrintOutput *pOutput)
775 XmTextPosition top = (XmTextPosition) 0;
778 XtVaGetValues(pOutput->editor, DtNtopCharacter, &top, NULL);
780 top = XmTextGetTopCharacter(pOutput->editor);
785 static DtEditorErrorCode
786 _poGetFileContents(char **contents, char *file)
788 DtEditorErrorCode error = DtEDITOR_NO_ERRORS;
794 if (file == NULL || *file == '\0') return
797 * Open the file for reading.
799 error = _poEditorValidateFileAccess(file, READ_ACCESS);
800 if (error != DtEDITOR_NO_ERRORS) return error;
802 if( (fp = fopen(file, "r")) == NULL )
803 return DtEDITOR_UNREADABLE_FILE;
805 stat(file, &statbuf);
806 nbytes = statbuf.st_size;
809 * Read the file contents (with room for null) & convert to a
810 * string. We want to use a string because the
811 * DtEditorSetContents/Append/Insert/... functions create another
812 * copy of the data before actually putting it into the widget.
814 buf = (char *) malloc(nbytes + 1);
816 return DtEDITOR_INSUFFICIENT_MEMORY;
818 nbytes = fread(buf, sizeof(char), nbytes, fp);
822 * Strip out any embedded NULLs because the text widget will only
823 * accept data up to the first NULL.
825 error = _poStripEmbeddedNulls(buf, &nbytes);
834 static DtEditorErrorCode
835 _poStripEmbeddedNulls(char *strbuf, int *len)
837 DtEditorErrorCode retval = DtEDITOR_NO_ERRORS;
839 if (strlen(strbuf) != *len)
843 retval = DtEDITOR_NULLS_REMOVED;
846 * The file contains NULL characters, so we strip them out and
847 * report that we have done so.
849 while((firstNull = strlen(strbuf)) != *len)
851 int lastNull = firstNull;
853 while((lastNull+1) < *len && strbuf[lastNull+1] == (char)'\0')
856 memcpy(&strbuf[firstNull], &strbuf[lastNull+1], *len-lastNull);
857 *len -= 1 + lastNull - firstNull;
864 extern DtEditorErrorCode
865 _poEditorValidateFileAccess( char *file, int accessType )
868 unsigned short tmpMode;
870 if (file && *file ) return DtEDITOR_INVALID_FILENAME;
872 if (access(file, F_OK) != 0) return DtEDITOR_NONEXISTENT_FILE;
874 if( stat(file, &statbuf) != 0 ) return DtEDITOR_NO_FILE_ACCESS;
876 if( (statbuf.st_mode & S_IFMT) == S_IFDIR ) return DtEDITOR_DIRECTORY;
878 if( (statbuf.st_mode & S_IFMT) == S_IFCHR ) return DtEDITOR_CHAR_SPECIAL_FILE;
880 if((statbuf.st_mode & S_IFMT) == S_IFBLK) return DtEDITOR_BLOCK_MODE_FILE;
885 if (access(file, R_OK) != 0) return DtEDITOR_UNREADABLE_FILE;
888 if (access(file, W_OK) != 0) return DtEDITOR_UNWRITABLE_FILE;
892 } /* end stat suceeded */
894 return DtEDITOR_NO_ERRORS;