home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / ANSIshellƒ / os_mac_Print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-15  |  13.0 KB  |  479 lines  |  [TEXT/R*ch]

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