home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / EMBL Search / Sources / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-04  |  8.9 KB  |  373 lines  |  [TEXT/KAHL]

  1. /*
  2. *********************************************************************
  3. *    
  4. *    print.c
  5. *    Print routines
  6. *        
  7. *    Rainer Fuchs
  8. *    EMBL Data Library
  9. *    Postfach 10.2209
  10. *    D-6900 Heidelberg, FRG
  11. *    E-mail: fuchs@embl-heidelberg.de
  12. *
  13. *    Copyright © 1992 EMBL Data Library
  14. *        
  15. **********************************************************************
  16. *    
  17. */ 
  18.  
  19. #include <PrintTraps.h>
  20. #include <Packages.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #include "EMBL-Search.h"
  25. #include "EMBL-Search.rsrc.h"
  26.  
  27. #define headerMargin    10
  28. #define topMargin        40
  29. #define bottomMargin    60
  30. #define footerMargin    10
  31.  
  32. #define leftMargin     40
  33. #define rightMargin    40
  34.  
  35. /*
  36. ******************************* Prototypes ***************************
  37. */
  38.  
  39. #include "print.h"
  40. #include "util.h"
  41. #include "window.h"
  42. #include "pstr.h"
  43. #include "sequence.h"
  44. #include "hitstorage.h"
  45.  
  46. static void DoPrinting(WDPtr wdp);
  47. static void PrintHeader(Rect *printRect, FONTINFO *fCourier, StringPtr windowName, short page);
  48. static void PrintFooter(Rect *printRect, FONTINFO *fCourier, StringPtr dateInfo);
  49. static pascal void myIdleProc(void);
  50. static short HowMany(void);
  51.  
  52.  
  53.  
  54. /*
  55. ******************************** Global variables ********************
  56. */
  57.  
  58. extern Str255    gAppName;
  59. static THPrint    prRecHdl;                            /* print info */
  60.  
  61.  
  62. /**************************************
  63. *    Prepare printing
  64. */
  65.  
  66. void PrepPrint()
  67. {
  68.     PrOpen();
  69.     prRecHdl=(THPrint)NewHandle(sizeof(TPrint));    /* get new print record    */
  70.     if(prRecHdl)
  71.         PrintDefault(prRecHdl);                            /* validate it                                */
  72.     else
  73.         FatalErrorMsg(ERR_MEMORY);
  74.     PrClose();
  75. }
  76.  
  77.  
  78. /**************************************
  79. *    Show page setup
  80. *    Return value:    none
  81. */
  82.  
  83. void PrintDialog()
  84. {
  85.     PrOpen();                                    /* open/close PrintMgr acc. to TN    */
  86.     PrStlDialog(prRecHdl);                    /* get page setup                         */
  87.     PrClose();
  88. }
  89.  
  90. /**************************************
  91. *    Main print loop
  92. *    Return value:    none
  93. */
  94.  
  95. void PrintIt(WDPtr wdp)
  96. {
  97.     short            copies;
  98.     GrafPtr        savePort;
  99.     DialogPtr    mySpoolDlg,myPrintDlg;
  100.     TPrStatus    myPrStatus;
  101.     
  102.     if( wdp == NULL )
  103.         return;
  104.         
  105.     GetPort(&savePort);
  106.     PrOpen();                                    /* init PrintMgr */
  107.     PrSetError(noErr);                        /* just in case last print job was 
  108.                                                         cancelled by user */
  109.  
  110.     if(PrJobDialog(prRecHdl)) {            /* get print job details */
  111.         StartWaitCursor();
  112.         for(copies=HowMany();copies && !PrError();--copies) {
  113.             /* show status information */
  114.             if((**prRecHdl).prJob.bJDocLoop == bSpoolLoop) {
  115.                 CenterDA('DLOG',SPOOLINFO_DLG,50);
  116.                 ShowWindow(mySpoolDlg=GetNewDialog(SPOOLINFO_DLG,NULL,(WindowPtr)-1));
  117.                 DrawDialog(mySpoolDlg);
  118.             }
  119.             else {
  120.                 CenterDA('DLOG',PRINTINFO_DLG,50);
  121.                 ShowWindow(myPrintDlg=GetNewDialog(PRINTINFO_DLG,NULL,(WindowPtr)-1));
  122.                 DrawDialog(myPrintDlg);
  123.             }
  124.             
  125.             DoPrinting(wdp);
  126.  
  127.             /* now print spool file */
  128.             if((**prRecHdl).prJob.bJDocLoop == bSpoolLoop && !PrError()) {
  129.                 DisposDialog(mySpoolDlg);
  130.                 CenterDA('DLOG',PRINTINFO_DLG,50);
  131.                 ShowWindow(myPrintDlg=GetNewDialog(PRINTINFO_DLG,NULL,(WindowPtr)-1));
  132.                 DrawDialog(myPrintDlg);
  133.                 PrPicFile(prRecHdl,NULL,NULL,NULL,&myPrStatus);
  134.             } /* end if */
  135.             DisposDialog(myPrintDlg);
  136.         } /* end for */
  137.         
  138.         if(PrError())
  139.             if(PrError() == iPrAbort)
  140.                 ErrorMsg(ERR_PRINTABORT);
  141.             else
  142.                 ErrorMsg(ERR_PRINT);
  143.         InitCursor();
  144.     } /* end if */
  145.     
  146.     PrClose();
  147.     SetPort(savePort);
  148. }
  149.  
  150. /**************************************
  151. *    Actual print routines
  152. *    Return value:    none
  153. */
  154.  
  155. static void DoPrinting(WDPtr wdp)
  156. {
  157.     TPPrPort            myPrPort;
  158.     FONTINFO            fCourier;
  159.     Rect                printRect;
  160.     short             linesPerPage;
  161.     short             line=0;
  162.     short             lineBase;
  163.     unsigned long    dateTime;
  164.     Str255            temp,dateInfo,windowName;
  165.     short                page;
  166.     ResultHdl        resHdl;
  167.     SeqRecHdl        seqRecHdl;
  168.     CString80Hdl    bufHdl;
  169.     SignedByte        oldState;
  170.     short                hitPos,bufPos;
  171.     GrafPtr            savePort;
  172.     
  173.     GetDateTime(&dateTime);
  174.     IUDateString(dateTime,longDate,dateInfo);
  175.     IUTimeString(dateTime,FALSE,temp);
  176.     pstrcat(dateInfo,"\p    ");
  177.     pstrcat(dateInfo,temp);
  178.     
  179.     GetWTitle((WindowPtr)wdp,windowName);
  180.  
  181.     /* to have rotating wait cursor: */
  182.     (**prRecHdl).prJob.pIdleProc=(ProcPtr)myIdleProc;
  183.  
  184.     savePort = ChangePort((GrafPtr)(myPrPort=PrOpenDoc(prRecHdl,NULL,NULL)));
  185.             
  186.     /* replace Monaco by Courier (looks nicer in print) */
  187.     GetFNum("\pCourier",&fCourier.num);
  188.     TextSize(10);
  189.     TextFont(fCourier.num);
  190.     GetFontInfo(&fCourier.finfo);
  191.     fCourier.height=fCourier.finfo.ascent+ fCourier.finfo.descent+
  192.                     fCourier.finfo.leading;
  193.     
  194.     /* calculate lines per page */
  195.     printRect=(**prRecHdl).prInfo.rPage;
  196.     linesPerPage=
  197.         (printRect.bottom-printRect.top-topMargin-bottomMargin)/
  198.         fCourier.height;
  199. /*    leftMargin=
  200.         (printRect.right-printRect.left-80*fCourier.finfo.widMax)/2;
  201. */
  202.                                     
  203.     switch(((WindowPeek)wdp)->windowKind) {
  204.         case queryW:
  205.             break;
  206.         case seqW:
  207.             seqRecHdl = (SeqRecHdl)(wdp->userHandle);
  208.             if(seqRecHdl == NULL)
  209.                 break;
  210.                 
  211.             /* Lock down sequence data */
  212.             bufHdl = (**seqRecHdl).lineBufHdl;
  213.             oldState=LockHandleHigh((Handle)bufHdl);
  214.             
  215.             hitPos = bufPos = 0;
  216.             for(page=1; !PrError() && hitPos < (**seqRecHdl).nlines; ++page) {
  217.                 PrOpenPage(myPrPort,NULL); /* create new page */
  218.                 if(!PrError()) {
  219.                     PrintHeader(&printRect,&fCourier,windowName,page);
  220.                     MoveTo(printRect.left+leftMargin,
  221.                            lineBase = printRect.top+topMargin+fCourier.height);
  222.                     /* Now print line by line */
  223.                     for(line=0;
  224.                         line < linesPerPage && hitPos < (**seqRecHdl).nlines;
  225.                         ++line) {
  226.                         if( hitPos < (**seqRecHdl).buftop ||
  227.                              hitPos >= (**seqRecHdl).buftop + SEQBUFLINES ) {
  228.                             if(!FillLineBuffer(seqRecHdl,hitPos)) {
  229.                                 /* we fake a print error */
  230.                                 PrSetError(iPrAbort);
  231.                                 break;
  232.                             }
  233.                             else
  234.                                 bufPos = 0;
  235.                         }
  236.                         DrawString((StringPtr)(*bufHdl)[bufPos]);
  237.                         MoveTo(printRect.left+leftMargin,lineBase += fCourier.height);    
  238.                         ++hitPos,++bufPos;
  239.                     }
  240.                     PrintFooter(&printRect,&fCourier,dateInfo);
  241.                 }
  242.                 PrClosePage(myPrPort);
  243.             }
  244.             
  245.             HSetState((Handle)bufHdl,oldState);
  246.             break;
  247.             
  248.         case resW:
  249.             resHdl = (ResultHdl)(wdp->userHandle);
  250.             if(resHdl == NULL)
  251.                 break;
  252.                 
  253.             /* Lock down result data */
  254.             bufHdl = (**resHdl).descBufHdl;
  255.             oldState=LockHandleHigh((Handle)bufHdl);
  256.             
  257.             hitPos = bufPos = 0;
  258.             for(page=1; !PrError() && hitPos < (**resHdl).nhits; ++page) {
  259.                 PrOpenPage(myPrPort,NULL); /* create new page */
  260.                 if(!PrError()) {
  261.                     PrintHeader(&printRect,&fCourier,windowName,page);
  262.                     MoveTo(printRect.left+leftMargin,
  263.                            lineBase = printRect.top+topMargin+fCourier.height);
  264.                     /* Now print line by line */
  265.                     for(line=0;
  266.                         line < linesPerPage && hitPos < (**resHdl).nhits;
  267.                         ++line) {
  268.                         if( hitPos < (**resHdl).buftop ||
  269.                              hitPos >= (**resHdl).buftop + MAXBUFLINES ) {
  270.                             if(!FillDEBuffer(resHdl,hitPos,FALSE)) {
  271.                                 /* we fake a print error */
  272.                                 PrSetError(iPrAbort);
  273.                                 break;
  274.                             }
  275.                             else
  276.                                 bufPos = 0;
  277.                         }
  278.                         DrawString((StringPtr)(*bufHdl)[bufPos]);
  279.                         MoveTo(printRect.left+leftMargin,lineBase += fCourier.height);    
  280.                         ++hitPos,++bufPos;
  281.                     }
  282.                     PrintFooter(&printRect,&fCourier,dateInfo);
  283.                 }
  284.                 PrClosePage(myPrPort);
  285.             }
  286.             
  287.             HSetState((Handle)bufHdl,oldState);
  288.             break;
  289.     } /* end switch */
  290.             
  291.     PrCloseDoc(myPrPort);
  292.     SetPort(savePort);
  293. }
  294.  
  295. /**************************************
  296. *    Print a nice header
  297. *    Return value:    none
  298. */
  299.  
  300. static void PrintHeader(Rect *printRect, FONTINFO *fCourier, StringPtr windowName,
  301.                                 short page)
  302. {
  303.     Str255 pageStr,numStr;
  304.     
  305.     TextFace(bold);
  306.     MoveTo(printRect->left + leftMargin,
  307.             printRect->top + headerMargin + fCourier->height);
  308.     DrawString(windowName);
  309.  
  310.     GetIndString(pageStr,OTHERS,PAGESTR);
  311.     NumToString((long)page,numStr);
  312.     pstrcat(pageStr,numStr);
  313.  
  314.     MoveTo(printRect->right - rightMargin - StringWidth(pageStr),
  315.         printRect->top + headerMargin + fCourier->height);
  316.     DrawString(pageStr);
  317.     TextFace(0);
  318. }
  319.  
  320. /**************************************
  321. *    Print a nice footer
  322. *    Return value:    none
  323. */
  324.  
  325. static void PrintFooter(Rect *printRect, FONTINFO *fCourier, StringPtr dateInfo)
  326. {
  327.     Str255 pageStr;
  328.     
  329.     TextFace(bold);
  330.     MoveTo(printRect->left + leftMargin,
  331.             printRect->bottom - footerMargin - fCourier->height);
  332.     DrawString(gAppName);
  333.  
  334.     MoveTo(printRect->right - rightMargin - StringWidth(dateInfo),
  335.         printRect->bottom - footerMargin - fCourier->height);
  336.     DrawString(dateInfo);
  337.     TextFace(0);
  338. }
  339.  
  340.  
  341. /**************************************
  342. *    Check for user-initiated print cancelling
  343. *    Return value:    none
  344. */
  345.  
  346. static pascal void myIdleProc()
  347. {
  348.     EventRecord myEvent;
  349.     GrafPtr        savePort;    /* actually no need to store GrafPort (TN294) because we
  350.                                         don't draw */
  351.     
  352.     RotateWaitCursor();    
  353.     if(WaitNextEvent(everyEvent,&myEvent,0L,NULL)) {
  354.         if(myEvent.what == keyDown || myEvent.what == autoKey) {
  355.             if( CmdPeriod(&myEvent) || ( (myEvent.message & keyCodeMask) >> 8 == ESCAPE))
  356.                 PrSetError(iPrAbort);
  357.         }
  358.     }
  359. }
  360.  
  361.  
  362. /**************************************
  363. *    Determine number of copies; only required for draft printing
  364. *    Return value:    number of copies to print
  365. */
  366.  
  367. static short HowMany()
  368. {
  369.     return(((**prRecHdl).prJob.bJDocLoop == bDraftLoop) ?
  370.               (**prRecHdl).prJob.iCopies : 1);
  371. }
  372.  
  373.