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 == NULL);
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)
576 saveTop = pOutput->currentLine;
577 PrintOutputFirstPage(pOutput);
578 while (PrintOutputPageDown(pOutput))
579 total += pOutput->linesPerPage;
581 DtEditorGoToLine(pOutput->editor, saveTop);
582 pOutput->currentLine = saveTop;
584 XtVaGetValues(pOutput->editor, XmNtotalLines, &total, NULL);
589 /************************************************************************
591 ************************************************************************/
593 PrintOutputPageUp(PrintOutput *pOutput)
595 XmTextPosition top_before, top_after;
601 pOutput->currentLine - pOutput->linesPerPage
603 pOutput->currentLine -= pOutput->linesPerPage;
604 if (pOutput->currentLine < 1)
606 pOutput->currentLine = 1;
610 top_before = (XmTextPosition) _poGetTopPosition(pOutput);
611 XmTextScroll(pOutput->editor, -1 * pOutput->linesPerPage);
612 top_after = (XmTextPosition) _poGetTopPosition(pOutput);
613 retval = (top_before > top_after) ? TRUE : FALSE;
619 /************************************************************************
620 * PrintOutputPageDown
621 ************************************************************************/
623 PrintOutputPageDown(PrintOutput *pOutput)
625 XmTextPosition top_before, top_after;
627 top_before = (XmTextPosition) _poGetTopPosition(pOutput);
632 pOutput->currentLine + pOutput->linesPerPage
634 pOutput->currentLine += pOutput->linesPerPage;
636 XmTextScroll(pOutput->editor, pOutput->linesPerPage);
639 top_after = (XmTextPosition) _poGetTopPosition(pOutput);
640 return (top_before < top_after) ? TRUE : FALSE;
643 /************************************************************************
644 * PrintOutputFirstPage
645 ************************************************************************/
647 PrintOutputFirstPage(PrintOutput *pOutput)
650 XtVaSetValues(pOutput->editor, DtNtopCharacter, (XmTextPosition) 0, NULL);
651 pOutput->currentLine = 1;
653 XmTextSetTopCharacter(pOutput->editor, (XmTextPosition) 0);
657 /************************************************************************
658 * PrintOutputLoadFile
659 ************************************************************************/
661 PrintOutputLoadFile( PrintOutput *pOutput, char *file)
663 char *contents = NULL;
664 DtEditorErrorCode errorCode;
667 errorCode = DtEditorSetContentsFromFile(pOutput->editor, file);
669 errorCode = _poGetFileContents(&contents, file);
670 if (contents != NULL)
672 XmTextSetString(pOutput->editor, contents);
680 /************************************************************************
681 ************************************************************************
683 * Private class methods
685 * _poDoGetLinesPerPage - Returns number of rows in the editor.
686 * _poSetInnerPageDimensions- Sets the XmN x,y,width,height of InnerPage.
687 * _poGetTopPosition - Returns the position of the 1st visible char.
688 * _poGetFileContents - Returns the contents of the specified file.
689 * _poStripEmbeddedNulls - Removes any embedded NULLs (\0) in a
690 * string of length 'length'. The removal
691 * occurs in place, with 'length' set to the
692 * new, stripped length. The resulting string
693 * is terminated with a trailing NULL.
695 ************************************************************************
696 ************************************************************************/
699 _poDoGetLinesPerPage(PrintOutput *pOutput)
703 XtVaGetValues(pOutput->editor, XmNrows, &lpp, NULL);
709 _poSetInnerPageDimensions(
710 PrintOutput *pOutput,
717 Dimension inner_height, inner_width, inner_x, inner_y,
718 outer_height, outer_width,
719 editor_height, footer_height, header_height;
721 XtVaGetValues(pOutput->page,
722 XmNheight, &outer_height,
723 XmNwidth, &outer_width,
726 XtVaGetValues(pOutput->headerLeft,
727 XmNheight, &header_height,
730 XtVaGetValues(pOutput->footerLeft,
731 XmNheight, &footer_height,
736 inner_height = (outer_height > (Dimension) (top + bottom)) ?
737 (outer_height - (top + bottom)) :
739 inner_width = (outer_width > (Dimension) (left + right)) ?
740 (outer_width - (left + right)) :
743 (inner_height > (Dimension) (header_height + footer_height)) ?
744 (inner_height - (header_height + footer_height)) :
747 XtVaSetValues(pOutput->editor, XmNheight, editor_height, NULL);
749 XtVaSetValues(pOutput->innerPage,
750 XmNleftAttachment, XmATTACH_NONE,
751 XmNtopAttachment, XmATTACH_NONE,
754 XmNheight, inner_height,
755 XmNwidth, inner_width,
758 pOutput->linesPerPage = _poDoGetLinesPerPage(pOutput);
765 _poGetTopPosition(PrintOutput *pOutput)
767 XmTextPosition top = (XmTextPosition) 0;
770 XtVaGetValues(pOutput->editor, DtNtopCharacter, &top, NULL);
772 top = XmTextGetTopCharacter(pOutput->editor);
777 static DtEditorErrorCode
778 _poGetFileContents(char **contents, char *file)
780 DtEditorErrorCode error = DtEDITOR_NO_ERRORS;
786 if (file == NULL || *file == NULL) return
789 * Open the file for reading.
791 error = _poEditorValidateFileAccess(file, READ_ACCESS);
792 if (error != DtEDITOR_NO_ERRORS) return error;
794 if( (fp = fopen(file, "r")) == NULL )
795 return DtEDITOR_UNREADABLE_FILE;
797 stat(file, &statbuf);
798 nbytes = statbuf.st_size;
801 * Read the file contents (with room for null) & convert to a
802 * string. We want to use a string because the
803 * DtEditorSetContents/Append/Insert/... functions create another
804 * copy of the data before actually putting it into the widget.
806 buf = (char *) malloc(nbytes + 1);
808 return DtEDITOR_INSUFFICIENT_MEMORY;
810 nbytes = fread(buf, sizeof(char), nbytes, fp);
814 * Strip out any embedded NULLs because the text widget will only
815 * accept data up to the first NULL.
817 error = _poStripEmbeddedNulls(buf, &nbytes);
826 static DtEditorErrorCode
827 _poStripEmbeddedNulls(char *strbuf, int *len)
829 DtEditorErrorCode retval = DtEDITOR_NO_ERRORS;
831 if (strlen(strbuf) != *len)
835 retval = DtEDITOR_NULLS_REMOVED;
838 * The file contains NULL characters, so we strip them out and
839 * report that we have done so.
841 while((firstNull = strlen(strbuf)) != *len)
843 int lastNull = firstNull;
845 while((lastNull+1) < *len && strbuf[lastNull+1] == (char)'\0')
848 memcpy(&strbuf[firstNull], &strbuf[lastNull+1], *len-lastNull);
849 *len -= 1 + lastNull - firstNull;
856 extern DtEditorErrorCode
857 _poEditorValidateFileAccess( char *file, int accessType )
860 unsigned short tmpMode;
862 if (file && *file ) return DtEDITOR_INVALID_FILENAME;
864 if (access(file, F_OK) != 0) return DtEDITOR_NONEXISTENT_FILE;
866 if( stat(file, &statbuf) != 0 ) return DtEDITOR_NO_FILE_ACCESS;
868 if( (statbuf.st_mode & S_IFMT) == S_IFDIR ) return DtEDITOR_DIRECTORY;
870 if( (statbuf.st_mode & S_IFMT) == S_IFCHR ) return DtEDITOR_CHAR_SPECIAL_FILE;
872 if((statbuf.st_mode & S_IFMT) == S_IFBLK) return DtEDITOR_BLOCK_MODE_FILE;
877 if (access(file, R_OK) != 0) return DtEDITOR_UNREADABLE_FILE;
880 if (access(file, W_OK) != 0) return DtEDITOR_UNWRITABLE_FILE;
884 } /* end stat suceeded */
886 return DtEDITOR_NO_ERRORS;