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 libraries 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>
75 #if 0 && defined(PRINTING_SUPPORTED)
77 #endif /* PRINTING_SUPPORTED */
79 #include <Dt/Editor.h>
84 #define WRITE_ACCESS 2
86 static void _poSetInnerPageDimensions(
93 static int _poDoGetLinesPerPage(PrintOutput*);
94 static int _poGetTopPosition(PrintOutput *pOutput);
95 static DtEditorErrorCode
96 _poGetFileContents(char **contents, char *file);
97 static DtEditorErrorCode
98 _poStripEmbeddedNulls(char *strbuf, int *len);
99 extern DtEditorErrorCode
100 _poEditorValidateFileAccess(char *file, int accessType);
103 * Used to initialize the top, right, bottom, and left margins
104 * between the outside edge of the page (_form) and the inner
105 * page that is written on.
107 const char *const _poDefaultMargin = ".5in";
109 /************************************************************************
111 * Creates and initialiazes a new PrintOutput output including the
113 ************************************************************************/
115 PrintOutputCreate(Widget shell)
119 PrintOutput *pOutput;
121 pOutput = (PrintOutput *) XtMalloc(sizeof(PrintOutput));
122 pOutput->pShell = shell;
124 pOutput->currentLine = 0;
125 pOutput->linesPerPage = 0;
127 w = XtVaCreateWidget("Page",
130 XmNresizePolicy, XmRESIZE_NONE,
134 w = XtVaCreateWidget("InnerPage",
137 XmNresizePolicy, XmRESIZE_NONE,
139 pOutput->innerPage = w;
141 w = XtVaCreateManagedWidget("HeaderLeft",
144 XmNalignment, XmALIGNMENT_BEGINNING,
145 XmNleftAttachment, XmATTACH_FORM,
146 XmNtopAttachment, XmATTACH_FORM,
148 pOutput->headerLeft = w;
150 w = XtVaCreateManagedWidget("HeaderRight",
153 XmNalignment, XmALIGNMENT_END,
154 XmNrightAttachment, XmATTACH_FORM,
155 XmNleftAttachment, XmATTACH_WIDGET,
156 XmNleftWidget, pOutput->headerLeft,
157 XmNtopAttachment, XmATTACH_FORM,
159 pOutput->headerRight = w;
161 w = XtVaCreateManagedWidget("Editor",
168 DtNscrollVertical, FALSE,
169 DtNscrollHorizontal, FALSE,
170 DtNshowStatusLine, FALSE,
172 XmNeditMode, XmMULTI_LINE_EDIT,
173 XmNleftAttachment, XmATTACH_FORM,
174 XmNrightAttachment, XmATTACH_FORM,
175 XmNtopAttachment, XmATTACH_WIDGET,
176 XmNtopWidget, pOutput->headerLeft,
180 w = XtVaCreateManagedWidget("FooterLeft",
183 XmNalignment, XmALIGNMENT_BEGINNING,
184 XmNleftAttachment, XmATTACH_FORM,
185 XmNbottomAttachment, XmATTACH_FORM,
187 pOutput->footerLeft = w;
189 w = XtVaCreateManagedWidget("FooterRight",
192 XmNalignment, XmALIGNMENT_END,
193 XmNleftAttachment, XmATTACH_WIDGET,
194 XmNleftWidget, pOutput->footerLeft,
195 XmNrightAttachment, XmATTACH_FORM,
196 XmNbottomAttachment, XmATTACH_FORM,
198 pOutput->footerRight = w;
202 XmNbottomAttachment, XmATTACH_WIDGET,
203 XmNbottomWidget, pOutput->footerLeft,
206 XtManageChild(pOutput->innerPage);
207 XtManageChild(pOutput->page);
209 PrintOutputSetPageMargins(
216 assert(parseError == 0);
221 /************************************************************************
224 ************************************************************************/
226 PrintOutputDestroy(PrintOutput *pOutput)
228 if (pOutput == NULL) return;
229 XtDestroyWidget(pOutput->page);
230 XtFree((char*) pOutput);
233 /************************************************************************
234 * PrintOutputHideFooter
235 * PrintOutputShowFooter
236 * PrintOutputHideHeader
237 * PrintOutputShowHeader
238 * Unmanages/Manages the footer/header widgets
239 ************************************************************************/
241 PrintOutputHideFooters(PrintOutput *pOutput)
243 XtUnmanageChild(pOutput->footerLeft);
244 XtUnmanageChild(pOutput->footerRight);
245 XtVaSetValues(pOutput->editor, XmNbottomAttachment, XmATTACH_FORM, NULL);
249 PrintOutputShowFooters(PrintOutput *pOutput)
251 XtManageChild(pOutput->footerLeft);
252 XtManageChild(pOutput->footerRight);
255 XmNbottomAttachment, XmATTACH_WIDGET,
256 XmNbottomWidget, pOutput->footerLeft,
261 PrintOutputHideHeaders(PrintOutput *pOutput)
263 XtUnmanageChild(pOutput->headerLeft);
264 XtUnmanageChild(pOutput->headerRight);
265 XtVaSetValues(pOutput->editor, XmNtopAttachment, XmATTACH_FORM, NULL);
269 PrintOutputShowHeaders(PrintOutput *pOutput)
271 XtManageChild(pOutput->headerLeft);
272 XtManageChild(pOutput->headerRight);
275 XmNtopAttachment, XmATTACH_WIDGET,
276 XmNtopWidget, pOutput->headerLeft,
280 /************************************************************************
281 * PrintOutputSetHdrFtrString
282 * Set the contents of the specifies header/footer
283 ************************************************************************/
285 PrintOutputSetHdrFtrString(
286 PrintOutput *pOutput,
287 _DtPrintHdrFtrEnum which,
294 if (contents == (char *) NULL)
299 case DTPRINT_OPTION_HEADER_LEFT:
300 w = pOutput->headerLeft;
302 case DTPRINT_OPTION_HEADER_RIGHT:
303 w = pOutput->headerRight;
305 case DTPRINT_OPTION_FOOTER_LEFT:
306 w = pOutput->footerLeft;
308 case DTPRINT_OPTION_FOOTER_RIGHT:
309 w = pOutput->footerRight;
315 xms = XmStringCreateLocalized(contents);
316 XtVaSetValues(w, XmNlabelString, xms, NULL);
320 /************************************************************************
321 * PrintOutputSetHdrFtrStrings
322 * Set the contents of all the header/footers
323 ************************************************************************/
325 PrintOutputSetHdrFtrStrings(
326 PrintOutput *pOutput,
337 xms = XmStringCreateLocalized(hdrLeft);
338 XtVaSetValues(pOutput->headerLeft, XmNlabelString, xms, NULL);
344 xms = XmStringCreateLocalized(hdrRight);
345 XtVaSetValues(pOutput->headerRight, XmNlabelString, xms, NULL);
351 xms = XmStringCreateLocalized(ftrLeft);
352 XtVaSetValues(pOutput->footerLeft, XmNlabelString, xms, NULL);
358 xms = XmStringCreateLocalized(ftrRight);
359 XtVaSetValues(pOutput->footerRight, XmNlabelString, xms, NULL);
364 /************************************************************************
365 * PrintOutputSetPageMargin
366 * Set the contents of the specified page margin
367 ************************************************************************/
369 PrintOutputSetPageMargin(
370 PrintOutput *pOutput,
371 _DtPrintMarginEnum which,
377 XtEnum xtParseError = FALSE;
378 char *marginString = XtNewString(margin);
385 case DTPRINT_OPTION_MARGIN_TOP:
386 pixels = XmConvertStringToUnits(
387 XtScreenOfObject(pOutput->pShell),
392 if (!xtParseError && pixels > 0)
393 pOutput->marginTop = pixels;
395 case DTPRINT_OPTION_MARGIN_RIGHT:
396 pixels = XmConvertStringToUnits(
397 XtScreenOfObject(pOutput->pShell),
402 if (!xtParseError && pixels > 0)
403 pOutput->marginRight = pixels;
405 case DTPRINT_OPTION_MARGIN_BOTTOM:
406 pixels = XmConvertStringToUnits(
407 XtScreenOfObject(pOutput->pShell),
412 if (!xtParseError && pixels > 0)
413 pOutput->marginBottom = pixels;
415 case DTPRINT_OPTION_MARGIN_LEFT:
416 pixels = XmConvertStringToUnits(
417 XtScreenOfObject(pOutput->pShell),
422 if (!xtParseError && pixels > 0)
423 pOutput->marginLeft = pixels;
430 _poSetInnerPageDimensions(
433 pOutput->marginRight,
434 pOutput->marginBottom,
435 pOutput->marginLeft);
439 XtFree(marginString);
442 /************************************************************************
443 * PrintOutputSetPageMargins
444 * Set the contents of all the page margins
445 ************************************************************************/
447 PrintOutputSetPageMargins(
448 PrintOutput *pOutput,
457 XtEnum xtParseError = FALSE;
462 margin = XtNewString(top);
463 pixels = XmConvertStringToUnits(
464 XtScreenOfObject(pOutput->pShell),
470 if (!xtParseError && pixels > 0)
472 pOutput->marginTop = pixels;
480 margin = XtNewString(right);
481 pixels = XmConvertStringToUnits(
482 XtScreenOfObject(pOutput->pShell),
488 if (!xtParseError && pixels > 0)
490 pOutput->marginRight = pixels;
498 margin = XtNewString(bottom);
499 pixels = XmConvertStringToUnits(
500 XtScreenOfObject(pOutput->pShell),
506 if (!xtParseError && pixels > 0)
508 pOutput->marginBottom = pixels;
516 margin = XtNewString(left);
517 pixels = XmConvertStringToUnits(
518 XtScreenOfObject(pOutput->pShell),
524 if (!xtParseError && pixels > 0)
526 pOutput->marginLeft = pixels;
534 _poSetInnerPageDimensions(
537 pOutput->marginRight,
538 pOutput->marginBottom,
539 pOutput->marginLeft);
543 /************************************************************************
544 * PrintOutputSetWordWrap
545 * Set the wrap to fit value in the editor
546 ************************************************************************/
548 PrintOutputSetWordWrap(PrintOutput *pOutput, Boolean onoff)
551 XtVaSetValues(pOutput->editor, DtNwordWrap, onoff, NULL);
553 XtVaSetValues(pOutput->editor, XmNwordWrap, onoff, NULL);
557 /************************************************************************
558 * PrintOutputGetLinesPerPage
559 * Returns the number of lines per page.
560 ************************************************************************/
562 PrintOutputGetLinesPerPage(PrintOutput *pOutput)
564 return ((int) pOutput->linesPerPage);
567 /************************************************************************
568 * PrintOutputGetNumLines
569 * Returns the number of lines of test in the editor.
570 ************************************************************************/
572 PrintOutputGetNumLines(PrintOutput *pOutput)
579 saveTop = pOutput->currentLine;
580 PrintOutputFirstPage(pOutput);
581 while (PrintOutputPageDown(pOutput))
582 total += pOutput->linesPerPage;
584 DtEditorGoToLine(pOutput->editor, saveTop);
585 pOutput->currentLine = saveTop;
587 XtVaGetValues(pOutput->editor, XmNtotalLines, &p, NULL);
593 /************************************************************************
595 ************************************************************************/
597 PrintOutputPageUp(PrintOutput *pOutput)
599 XmTextPosition top_before, top_after;
605 pOutput->currentLine - pOutput->linesPerPage
607 pOutput->currentLine -= pOutput->linesPerPage;
608 if (pOutput->currentLine < 1)
610 pOutput->currentLine = 1;
614 top_before = (XmTextPosition) _poGetTopPosition(pOutput);
615 XmTextScroll(pOutput->editor, -1 * pOutput->linesPerPage);
616 top_after = (XmTextPosition) _poGetTopPosition(pOutput);
617 retval = (top_before > top_after) ? TRUE : FALSE;
623 /************************************************************************
624 * PrintOutputPageDown
625 ************************************************************************/
627 PrintOutputPageDown(PrintOutput *pOutput)
629 XmTextPosition top_before, top_after;
631 top_before = (XmTextPosition) _poGetTopPosition(pOutput);
636 pOutput->currentLine + pOutput->linesPerPage
638 pOutput->currentLine += pOutput->linesPerPage;
640 XmTextScroll(pOutput->editor, pOutput->linesPerPage);
643 top_after = (XmTextPosition) _poGetTopPosition(pOutput);
644 return (top_before < top_after) ? TRUE : FALSE;
647 /************************************************************************
648 * PrintOutputFirstPage
649 ************************************************************************/
651 PrintOutputFirstPage(PrintOutput *pOutput)
654 XtVaSetValues(pOutput->editor, DtNtopCharacter, (XmTextPosition) 0, NULL);
655 pOutput->currentLine = 1;
657 XmTextSetTopCharacter(pOutput->editor, (XmTextPosition) 0);
661 /************************************************************************
662 * PrintOutputLoadFile
663 ************************************************************************/
665 PrintOutputLoadFile( PrintOutput *pOutput, char *file)
667 char *contents = NULL;
668 DtEditorErrorCode errorCode;
671 errorCode = DtEditorSetContentsFromFile(pOutput->editor, file);
673 errorCode = _poGetFileContents(&contents, file);
674 if (contents != NULL)
676 XmTextSetString(pOutput->editor, contents);
684 /************************************************************************
685 ************************************************************************
687 * Private class methods
689 * _poDoGetLinesPerPage - Returns number of rows in the editor.
690 * _poSetInnerPageDimensions- Sets the XmN x,y,width,height of InnerPage.
691 * _poGetTopPosition - Returns the position of the 1st visible char.
692 * _poGetFileContents - Returns the contents of the specified file.
693 * _poStripEmbeddedNulls - Removes any embedded NULLs (\0) in a
694 * string of length 'length'. The removal
695 * occurs in place, with 'length' set to the
696 * new, stripped length. The resulting string
697 * is terminated with a trailing NULL.
699 ************************************************************************
700 ************************************************************************/
703 _poDoGetLinesPerPage(PrintOutput *pOutput)
707 XtVaGetValues(pOutput->editor, XmNrows, &lpp, NULL);
713 _poSetInnerPageDimensions(
714 PrintOutput *pOutput,
721 XtArgVal outer_height0, outer_width0, footer_height0, header_height0;
722 Dimension inner_height, inner_width, inner_x, inner_y,
723 outer_height, outer_width,
724 editor_height, footer_height, header_height;
726 XtVaGetValues(pOutput->page,
727 XmNheight, &outer_height0,
728 XmNwidth, &outer_width0,
731 XtVaGetValues(pOutput->headerLeft,
732 XmNheight, &header_height0,
735 XtVaGetValues(pOutput->footerLeft,
736 XmNheight, &footer_height0,
739 outer_height = (Dimension)outer_height0;
740 outer_width = (Dimension)outer_width0;
741 header_height = (Dimension)header_height0;
742 footer_height = (Dimension)footer_height0;
746 inner_height = (outer_height > (Dimension) (top + bottom)) ?
747 (outer_height - (top + bottom)) :
749 inner_width = (outer_width > (Dimension) (left + right)) ?
750 (outer_width - (left + right)) :
753 (inner_height > (Dimension) (header_height + footer_height)) ?
754 (inner_height - (header_height + footer_height)) :
757 XtVaSetValues(pOutput->editor, XmNheight, editor_height, NULL);
759 XtVaSetValues(pOutput->innerPage,
760 XmNleftAttachment, XmATTACH_NONE,
761 XmNtopAttachment, XmATTACH_NONE,
764 XmNheight, inner_height,
765 XmNwidth, inner_width,
768 pOutput->linesPerPage = _poDoGetLinesPerPage(pOutput);
775 _poGetTopPosition(PrintOutput *pOutput)
777 XmTextPosition top = (XmTextPosition) 0;
780 XtVaGetValues(pOutput->editor, DtNtopCharacter, &top, NULL);
782 top = XmTextGetTopCharacter(pOutput->editor);
787 static DtEditorErrorCode
788 _poGetFileContents(char **contents, char *file)
790 DtEditorErrorCode error = DtEDITOR_NO_ERRORS;
796 if (file == NULL || *file == '\0') return
799 * Open the file for reading.
801 error = _poEditorValidateFileAccess(file, READ_ACCESS);
802 if (error != DtEDITOR_NO_ERRORS) return error;
804 if( (fp = fopen(file, "r")) == NULL )
805 return DtEDITOR_UNREADABLE_FILE;
807 if(stat(file, &statbuf) == -1) {
809 return DtEDITOR_UNREADABLE_FILE;
811 nbytes = statbuf.st_size;
814 * Read the file contents (with room for null) & convert to a
815 * string. We want to use a string because the
816 * DtEditorSetContents/Append/Insert/... functions create another
817 * copy of the data before actually putting it into the widget.
819 buf = (char *) malloc(nbytes + 1);
822 return DtEDITOR_INSUFFICIENT_MEMORY;
825 nbytes = fread(buf, sizeof(char), nbytes, fp);
829 * Strip out any embedded NULLs because the text widget will only
830 * accept data up to the first NULL.
832 error = _poStripEmbeddedNulls(buf, &nbytes);
841 static DtEditorErrorCode
842 _poStripEmbeddedNulls(char *strbuf, int *len)
844 DtEditorErrorCode retval = DtEDITOR_NO_ERRORS;
846 if (strlen(strbuf) != *len)
850 retval = DtEDITOR_NULLS_REMOVED;
853 * The file contains NULL characters, so we strip them out and
854 * report that we have done so.
856 while((firstNull = strlen(strbuf)) != *len)
858 int lastNull = firstNull;
860 while((lastNull+1) < *len && strbuf[lastNull+1] == (char)'\0')
863 memcpy(&strbuf[firstNull], &strbuf[lastNull+1], *len-lastNull);
864 *len -= 1 + lastNull - firstNull;
871 extern DtEditorErrorCode
872 _poEditorValidateFileAccess( char *file, int accessType )
875 unsigned short tmpMode;
877 if (file && *file ) return DtEDITOR_INVALID_FILENAME;
879 if (access(file, F_OK) != 0) return DtEDITOR_NONEXISTENT_FILE;
881 if( stat(file, &statbuf) != 0 ) return DtEDITOR_NO_FILE_ACCESS;
883 if( (statbuf.st_mode & S_IFMT) == S_IFDIR ) return DtEDITOR_DIRECTORY;
885 if( (statbuf.st_mode & S_IFMT) == S_IFCHR ) return DtEDITOR_CHAR_SPECIAL_FILE;
887 if((statbuf.st_mode & S_IFMT) == S_IFBLK) return DtEDITOR_BLOCK_MODE_FILE;
892 if (access(file, R_OK) != 0) return DtEDITOR_UNREADABLE_FILE;
895 if (access(file, W_OK) != 0) return DtEDITOR_UNWRITABLE_FILE;
899 } /* end stat suceeded */
901 return DtEDITOR_NO_ERRORS;