home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / runtime / mac / os_mac_Print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-09  |  12.5 KB  |  465 lines

  1. /* os_mac_Print.c */
  2. /* 28Sep92  e     */
  3. /* adapted from ...
  4. /*
  5. ** Apple Macintosh Developer Technical Support
  6. **
  7. ** Program:     MacShell
  8. ** File:        print.c
  9. ** Written by:  Eric Soldan
  10. ** Based on:    Code from Pete "Luke" Alexander.
  11. **
  12. ** Copyright ⌐ 1989-1991 Apple Computer, Inc.
  13. ** All rights reserved.
  14. */
  15.  
  16. /* portions Copyright ⌐ 1992 e.  All rights reserved. */
  17.  
  18. #include <MacHeaders>
  19.  
  20. /*****************************************************************************/
  21.  
  22. /* 10Dec92  e  edited for Tricia */
  23.  
  24. #ifdef THINK_C
  25. #if THINK_C < 5
  26. #define THINK_PRE_5
  27. #endif
  28. #endif
  29.  
  30. #include "os_mac_eEdit.h"
  31.  
  32. #include <Packages.h>
  33.  
  34. #define rPrStatusDlg (270)
  35.  
  36. #ifndef __ERRORS__
  37. #include <Errors.h>
  38. #endif
  39.  
  40. #ifndef __RESOURCES__
  41. #include <Resources.h>
  42. #endif
  43.  
  44. /*****************************************************************************/
  45.  
  46. static pascal void    PrintIdleProc( void );
  47. static DialogPtr    PrintingStatusDialog;
  48.  
  49. /*****************************************************************************/
  50.  
  51. /* eEdit specific stuff... */
  52.  
  53. extern void eTeDrawLine( eRec **hE, ChPos beginPos, Point location );
  54.  
  55. static void eTePrintGuts( eRec **hE, short *vNext, Rect *area, short lpp )
  56. {
  57.     eRec *pE;
  58.     short vLast, vFirst;
  59.     ChPos    startPos;
  60.     Point    location;
  61.     /* Rect    tRect; */
  62.     
  63.     HLock( (Handle )hE );
  64.     pE = *hE;
  65.     
  66.     if ( ( vFirst = *vNext ) < 0 )
  67.         vFirst = 0;
  68.  
  69.     vLast = vFirst - 1 + lpp;    /* lpp was: ( (*area).bottom - (*area).top ) / (*pE).vScale; */
  70.  
  71.     if ( vLast >= (*pE).bounds.v ) 
  72.     {    vLast = (*pE).bounds.v - 1;
  73.         *vNext = -1;
  74.     }
  75.     else
  76.         *vNext = vLast + 1;    /* for next time */
  77.  
  78.     /* EraseRect( &tRect ); */
  79.  
  80.     if ( vFirst < (*pE).bounds.v && vLast >= 0)
  81.  
  82.     {    location.h = (*area).left /* (*pE).leftMargin */ ;
  83.         location.v = (*area).top  /* (*pE).topMargin */  ;
  84.         startPos.h = 0;
  85.  
  86.         for ( startPos.v = vFirst;
  87.               startPos.v <= vLast;
  88.               location.v += (*pE).vScale, ++startPos.v )
  89.         {    eTeDrawLine( hE, startPos, location );
  90.         }
  91.         (**hE).curStyle = NOSTYLE;    /* gotta do to force first font/size/style in window */
  92.     }
  93.     HUnlock( (Handle )hE );
  94. }
  95.  
  96. static void headerPrepare( eRec **hE, short style )
  97. {
  98.     (**hE).curStyle = style;
  99.     TextFont( (**hE).style[style].tsFont );
  100.     TextFace( (**hE).style[style].tsFace );
  101.     TextSize( (**hE).style[style].tsSize );
  102.     /* RGBColor tsColor; */
  103.     PenMode(patCopy);PenSize(1,1);PenPat(&black);
  104. }
  105.  
  106. #define leftMargin(port) ((port)->portRect.left + 4)
  107.  
  108. static void dpyTab( short tabwidth )
  109. {
  110.     GrafPort *gPort;
  111.     short targetX;
  112.  
  113.     GetPort( &gPort );
  114.     targetX = leftMargin(gPort) + 
  115.         ( ( gPort->pnLoc.h - leftMargin(gPort) ) / tabwidth + 1 ) * tabwidth;
  116.     MoveTo( targetX, gPort->pnLoc.v );
  117. }
  118.  
  119. #define WAGspace (3)
  120.  
  121. static void    eTePrintPages( eRec **hE, TPPrPort printPort, Str255 nameString, short lastPage )
  122. {
  123.     Rect            area, frame;
  124.     OSErr            err;
  125.     short            tabwidth;
  126.     short            vNext = 0;
  127.     short             ePrintPage = 1;
  128.     short            lpp, lh;
  129.     long            time;
  130.     /* Str255        timeString, dateString, tStr; */
  131.     unsigned char   timeString[32];
  132.     unsigned char   dateString[64];
  133.     unsigned char   tStr[32];
  134.  
  135.     headerPrepare( hE, 1 );
  136.     tabwidth = CharWidth(' ') * (12);
  137.     GetDateTime( &time );
  138.     IUTimeString( time, 0, timeString );
  139.     IUDateString( time, abbrevDate, dateString );
  140.             
  141.     area = ((WindowPtr )printPort)->portRect;
  142.     ClipRect( &area );
  143.     InsetRect( &area, 4, 4 );    /* Just so no characters get clipped. */
  144.     lh = (**hE).vScale;
  145.     lpp = ( area.bottom - area.top ) / lh;
  146.     area.bottom = area.top + WAGspace + lpp * lh;
  147.     
  148.     frame = area;
  149.     InsetRect( &frame, -4, 0 );
  150.     area.top += lh + WAGspace;
  151.  
  152.     while( ePrintPage <= lastPage && ! (err = PrError()) )
  153.     {
  154.         PrOpenPage( printPort, nil );
  155.         if( ! (err = PrError()) )
  156.         {
  157.             headerPrepare( hE, 1 );
  158.             MoveTo( frame.left, frame.top + lh );            /* WAG */
  159.             Line(   frame.right - frame.left, 0 );
  160.             MoveTo( area.left, frame.top + (**hE).fontAscent );
  161.             DrawString( dateString );
  162.             dpyTab(tabwidth);
  163.             DrawString( timeString );
  164.             dpyTab(tabwidth);
  165.             DrawString( nameString );
  166.             dpyTab(tabwidth);
  167.             DrawString( "\ppage " );
  168.             NumToString( ePrintPage, &tStr );
  169.             DrawString( &tStr );
  170.  
  171.             eTePrintGuts( hE, &vNext, &area, lpp - 1 );
  172.             
  173.             headerPrepare( hE, 1 );
  174.             MoveTo( frame.left, frame.bottom );
  175.             LineTo( frame.right, frame.bottom);
  176.         }
  177.         PrClosePage( printPort );
  178.         if( vNext == -1 ) break;    /* Text didn't go to bottom of page so we're done */
  179.         ++ePrintPage;
  180.     }
  181. }
  182.  
  183. /*****************************************************************************/
  184. /* mostly generic stuff... */
  185.  
  186. /* This print-loop function is designed to be called under various situations.
  187. ** The big issue that it handles is finder printing.  If multiple documents
  188. ** are to be printed from the finder, the user should only see one job dialog
  189. ** for all the files.  (If a job dialog is shown for each file, how does the
  190. ** user know for which file the dialog is for?)  So, for situations where
  191. ** there is more than one file to be printed, call this code the first time
  192. ** with the firstJob boolean true.  Normally, the jobDlg boolean will also
  193. ** be true, except that under 7.0, you may be printing in the background.
  194. ** If this is the case, you don't want a job dialog for even the first file,
  195. ** and you should pass in false for the jobDlg boolean in this case.  For
  196. ** files 2-N, you should pass false for both booleans.  For regular application
  197. ** printing, you should pass true for both booleans, since the file is the
  198. ** first (only) file, and you are not in the background.
  199. **
  200. ** After calling this function to print a document, you need to call it
  201. ** again with a nil document handle.  The print record for the first (or only)
  202. ** document printed is preserved in a static variable.  This is so that the
  203. ** job dialog information can be passed on to documents 2-N in the print job.
  204. ** Calling this function with the document handle nil tells this function
  205. ** that you are done printing documents, and that the print record for the
  206. ** first job can be disposed of.
  207. */
  208.  
  209. OSErr    eTePrint( eRec **hE, Boolean jobDlg, Boolean firstJob, Str255 flnm)
  210. {
  211.     OSErr            err;
  212.     short            i, copies, keepResFile, fstPage, lstPage;
  213.     Boolean         do_init;
  214.     TPrStatus        status;
  215.     THPrint            prRecHndl;
  216.     TPPrPort        printPort;
  217.     GrafPtr            oldPort;
  218.     ControlHandle    proceedButton;
  219.     Rect             rct;
  220.  
  221.     static THPrint    prMergeHndl;
  222.  
  223.     if ( ! hE )
  224.     {    if ( prMergeHndl )
  225.         {    DisposHandle( (Handle )prMergeHndl );
  226.             prMergeHndl = nil;
  227.         }
  228.         return( noErr );
  229.     }
  230.  
  231.     PrintingStatusDialog = nil;
  232.  
  233.     if( ! (prRecHndl = (THPrint )NewHandle( sizeof( TPrint )) ) )
  234.     {    /* If we can't generate a print record handle, we are out of here. */
  235.         return(memFullErr);
  236.     }
  237.     if( (**hE).hPrint )
  238.     {    /* Get the document's print info into the print record handle. */
  239.         BlockMove( (Ptr )(*(**hE).hPrint), (Ptr )(*prRecHndl), sizeof( TPrint ) );
  240.         do_init = FALSE;
  241.     }
  242.     else
  243.     {    if (!((**hE).hPrint = (THPrint)NewHandle(sizeof(TPrint))))
  244.         {    /* If we can't generate a print record handle, we are out of here. */
  245.             DisposHandle( (Handle )prRecHndl );
  246.             return( memFullErr );
  247.         }
  248.         do_init = TRUE;
  249.     }
  250.  
  251.     GetPort(&oldPort);
  252.  
  253.     SetCursor(&qd.arrow);
  254.  
  255.     PrOpen();
  256.     err = PrError();
  257.  
  258.     if (!err) {
  259.         keepResFile = CurResFile();    /* some printers change CurResFile & we are being safe! */
  260.  
  261.         if( do_init )
  262.         {    PrintDefault(prRecHndl);        /* The document print record was never 
  263.             err = PrError();                ** initialized.  Now is is. */
  264.         }            
  265.         if( ! err )
  266.         {    PrValidate( prRecHndl );        /* Do this just 'cause Apple says so. */
  267.             err = PrError();
  268.         }
  269.         if( ! err )
  270.         {    if( jobDlg )                    /* User gets to click some buttons. */
  271.             {    if (!(PrJobDialog(prRecHndl))) err = userCanceledErr;
  272.                 else                           err = PrError();
  273.             }
  274.         }
  275.         if( ! err )
  276.         {    if( ! firstJob )
  277.             {    fstPage = (*prMergeHndl)->prJob.iFstPage;
  278.                 lstPage = (*prMergeHndl)->prJob.iLstPage;
  279.                 PrJobMerge(prMergeHndl, prRecHndl);
  280.                 (*prMergeHndl)->prJob.iFstPage = (*prRecHndl)->prJob.iFstPage = fstPage;
  281.                 (*prMergeHndl)->prJob.iLstPage = (*prRecHndl)->prJob.iLstPage = lstPage;
  282.                 err = PrError();
  283.             }
  284.         }
  285.  
  286.         if( ! err )
  287.         {    /* Put the defaulted/validated/jobDlg'ed print record in the doc. */
  288.             fstPage = (*prRecHndl)->prJob.iFstPage;
  289.             lstPage = (*prRecHndl)->prJob.iLstPage;
  290.             copies  = (*prRecHndl)->prJob.iCopies;
  291.             BlockMove((Ptr)(*prRecHndl), (Ptr)(*(**hE).hPrint), sizeof(TPrint));
  292.             /* Setup the proceed/pause/cancel dialog with the document name. */
  293.             ParamText( flnm, nil, nil, nil);
  294.             PrintingStatusDialog = GetNewDialog( rPrStatusDlg, nil, (WindowPtr )-1 );
  295.             if (PrintingStatusDialog)
  296.             {
  297. #ifndef THINK_PRE_5
  298.                 GetDItem(PrintingStatusDialog, 1, &i, (Handle *)&proceedButton, &rct);
  299. #else
  300.                 GetDItem(PrintingStatusDialog, 1, &i, &proceedButton, &rct);
  301. #endif
  302.                 HiliteControl(proceedButton, 255);
  303.                 /* Hook in the proceed/pause/cancel dialog. */
  304.                 (*prRecHndl)->prJob.pIdleProc = PrintIdleProc;
  305.             }
  306.             UseResFile( keepResFile );    /* some printers change CurResFile & we are being safe! */
  307.  
  308.             for( i = 1; i <= copies && ! err; ++i )
  309.             {
  310.                 printPort = PrOpenDoc(prRecHndl, nil, nil);
  311.                 if ( ! ( err = PrError() ) ) eTePrintPages( hE, printPort, flnm, lstPage );
  312.                 PrCloseDoc( printPort );
  313.             }
  314.         }
  315.         else if( do_init )
  316.         {    DisposHandle( (Handle)(**hE).hPrint );
  317.             (**hE).hPrint = NULL;
  318.         }
  319.  
  320.         if ((!err) && ((*prRecHndl)->prJob.bJDocLoop == bSpoolLoop) && (!(err = PrError())) )
  321.         {
  322.             PrPicFile(prRecHndl, nil, nil, nil, &status);
  323.             err = PrError();
  324.         }
  325.     }
  326.  
  327.     if (firstJob) prMergeHndl = prRecHndl;
  328.     else          DisposHandle( (Handle )prRecHndl );
  329.  
  330.     if( PrintingStatusDialog ) DisposDialog( PrintingStatusDialog );
  331.  
  332.     PrClose();
  333.     SetPort(oldPort);
  334.  
  335.     return(err);
  336. }
  337.  
  338. /*****************************************************************************/
  339.  
  340. /* PrintIdleProc will handle events in the 'Printing Status Dialog' which
  341. ** gives the user the option to 'Proceed', 'Pause', or 'Cancel' the current
  342. ** printing job during print time.
  343. **
  344. ** The buttons:
  345. **        1: Proceed
  346. **        2: Pause
  347. **        3: Cancel 
  348. */
  349.  
  350. pascal void        PrintIdleProc(void)
  351. {
  352.     Boolean                button, paused;
  353.     ControlHandle        pauseButton, proceedButton;
  354.     DialogPtr            aDialog;
  355.     EventRecord            anEvent;
  356.     GrafPtr                oldPort;
  357.     Rect                 rct;
  358.     short                item, itemType;
  359.  
  360.     if( ! PrintingStatusDialog ) return;
  361.     
  362.     GetPort( &oldPort );
  363.  
  364. #ifndef THINK_PRE_5
  365.     GetDItem( PrintingStatusDialog, 1, &itemType, (Handle *)&proceedButton, &rct );
  366.     HiliteControl( proceedButton, 255 );
  367.     GetDItem( PrintingStatusDialog, 2, &itemType, (Handle *)&pauseButton, &rct );
  368. #else
  369.     GetDItem( PrintingStatusDialog, 1, &itemType, &proceedButton, &rct );
  370.     HiliteControl( proceedButton, 255 );
  371.     GetDItem( PrintingStatusDialog, 2, &itemType, &pauseButton, &rct );
  372. #endif
  373.  
  374.     paused = false;
  375.     do {
  376.         if( GetNextEvent( (mDownMask + mUpMask + updateMask), &anEvent ) ) {
  377.             if( PrintingStatusDialog != FrontWindow () )
  378.                 SelectWindow( PrintingStatusDialog );
  379.  
  380.             if ( IsDialogEvent( &anEvent ) ) {
  381.                 button = DialogSelect( &anEvent, &aDialog, &item );
  382.  
  383.                 if ( (button) && (aDialog == PrintingStatusDialog) ) {
  384.                     switch (item) {
  385.                         case 1:
  386.                             HiliteControl( pauseButton, 0 );        /* Enable PAUSE    */
  387.                             HiliteControl( proceedButton, 255 );    /* Disable PROCEED */
  388.                             paused = false;
  389.                             break;
  390.                         case 2:
  391.                             HiliteControl( pauseButton, 255 );    /* Disable PAUSE  */
  392.                             HiliteControl( proceedButton, 0 );    /* Enable PROCEED */
  393.                             paused = true;
  394.                             break;
  395.                         case 3:
  396.                             PrSetError( iPrAbort );               /* CANCEL printing */
  397.                             paused = false;
  398.                             break;
  399.                     }
  400.                 }
  401.             }
  402.         }
  403.     } while( paused != false ); 
  404.  
  405.     SetPort( oldPort );
  406. }
  407.  
  408. /*****************************************************************************/
  409.  
  410. OSErr    PageSetupDialog( eRec **hE )
  411. {
  412.     OSErr        err;
  413.     Boolean     do_init;
  414.     THPrint        prRecHndl;
  415.  
  416.     SetCursor( &qd.arrow );
  417.     
  418.     if( ! ( prRecHndl = (THPrint )NewHandle( sizeof( TPrint )) ) )
  419.     {    /* If we can't generate a print record handle, we are out of here. */
  420.         return( memFullErr );
  421.     }
  422.     if( (**hE).hPrint )
  423.     {    /* Get the document's print info into the print record handle. */
  424.         BlockMove( (Ptr )(*(**hE).hPrint), (Ptr )(*prRecHndl), sizeof( TPrint ) );
  425.         do_init = FALSE;
  426.     }
  427.     else
  428.     {    if( ! ( (**hE).hPrint = (THPrint )NewHandle( sizeof( TPrint )) ) )
  429.         {    /* If we can't generate a print record handle, we are out of here. */
  430.              err = memFullErr;
  431.              goto pguperr;
  432.         }
  433.         do_init = TRUE;
  434.     }
  435.  
  436.     PrOpen();
  437.  
  438.     if( ! (err = PrError()) )
  439.  
  440.     {    if( do_init ) PrintDefault( prRecHndl );
  441.         else          PrValidate( prRecHndl );
  442.         if( ! (err = PrError()) )
  443.         {    if( PrStlDialog(prRecHndl) )
  444.             {    BlockMove((Ptr)*prRecHndl, (Ptr)(*(**hE).hPrint), sizeof(TPrint));
  445.                 /* (*frHndl)->doc.printRecValid  = true; */
  446.                 /* (*frHndl)->fileState.docDirty = true; */
  447.             }
  448.             else
  449.             {    err = userCanceledErr;
  450.                 if( do_init )
  451.                 {    DisposHandle((Handle)(**hE).hPrint);
  452.                     (**hE).hPrint = NULL;
  453.                 }
  454.             }
  455.         }
  456.     }
  457.     PrClose();
  458.  
  459. pguperr:
  460.     DisposHandle( (Handle)prRecHndl );
  461.     return( err );
  462. }
  463.  
  464. /* end of os_mac_Print.c */
  465.