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

  1. /*
  2. *********************************************************************
  3. *    
  4. *    Results.c
  5. *    Handling of results
  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 <stdio.h>
  20. #include <string.h>
  21.  
  22. #include "EMBL-Search.h"
  23. #include "EMBL-Search.rsrc.h"
  24.  
  25. /*
  26. ******************************* Prototypes ***************************
  27. */
  28.  
  29. #include "results.h"
  30. #include "util.h"
  31. #include "window.h"
  32. #include "hitstorage.h"
  33. #include "pstr.h"
  34. #include "click.h"
  35. #include "export.h"
  36. #include "events.h"
  37.  
  38. static void DrawResWin1(WDPtr wdp, short updown);
  39. static pascal void ScrollResProc(ControlHandle theControl, short theCode);
  40. static Boolean ReadResults(StringPtr fName, short vRefNum, QueryHdl *queryHdlP, HitmapHdl *hitmapHdlP);
  41. static pascal Boolean resFileFilter(ParmBlkPtr myPBp);
  42.  
  43.  
  44.  
  45. /*
  46. ******************************** Global variables *****************
  47. */
  48.  
  49. extern WDRec        gWindows[MAXWIN];
  50. extern Rect            gResWinRect;
  51. extern FONTINFO    fMonaco,fSystem;
  52. extern char            gError[256];
  53. extern short        gScrollAmt,gScrollCode;
  54. extern Boolean        gScrollDir;
  55. extern DBInfo        gDBInfo[DB_NUM];
  56. extern Boolean        gInBackground;
  57.  
  58. short gResNo;
  59.  
  60.  
  61. /**************************************
  62. *    Open a new result window
  63. *    Return value:    TRUE, if successful
  64. *                        FALSE, if an error occurred
  65. */
  66.  
  67. Boolean NewResultWindow(short w,WDPtr wdp, ResultHdl resHdl, StringPtr title)
  68. {
  69.     Rect            tempRect;
  70.     WStateData    **stateHdl;
  71.     WindowPtr    wPtr = (WindowPtr) wdp;
  72.     Boolean        ret;
  73.     
  74.     if( resHdl == NULL || wdp == NULL )
  75.         return(FALSE);
  76.         
  77.     /* fill short description buffer */
  78.     StartWaitCursor();
  79.     ret = FillDEBuffer(resHdl,0,FALSE);
  80.     InitCursor();
  81.     if ( !ret )
  82.         return(FALSE);
  83.  
  84.     tempRect = gResWinRect;
  85.     AdjustPosition(w,&tempRect);
  86.     SetPort(NewWindow(wdp,&tempRect,"\p",FALSE,documentProc + 8,(void *)-1,TRUE,0L));
  87.     
  88.     /* anchor result record */
  89.     wdp->userHandle = (Handle)resHdl;
  90.             
  91.     SetWTitle(wPtr,title);
  92.     TextFont(fMonaco.num);
  93.     TextSize(9);
  94.  
  95.     ((WindowPeek)wPtr)->windowKind = resW;
  96.     pstrcpy(wdp->fName,title);
  97.     wdp->vRefNum = 0;
  98.     wdp->dirty = TRUE;
  99.     wdp->inited = FALSE;
  100.     wdp->inUse = TRUE;
  101.         
  102.     /* adjust zoom standard state */
  103.     stateHdl = (WStateData **)((WindowPeek)wPtr)->dataHandle;
  104.     AdjustWSize(resW,&(**stateHdl).stdState,fMonaco.height,fMonaco.finfo.widMax);
  105.     
  106.     /* draw vertical scroll bar */
  107.     tempRect = wPtr->portRect;
  108.     tempRect.left = tempRect.right-SBarWidth;
  109.     tempRect.right += 1;
  110.     tempRect.top += 3*fMonaco.height - 1;
  111.     tempRect.bottom -= (SBarWidth-1);
  112.     wdp->vScroll = NewControl(wPtr,&tempRect,"\p",TRUE,0,0,10,scrollBarProc,0L);
  113.     
  114.     /* draw horizontal scroll bar */
  115.     tempRect = wPtr->portRect;
  116.     tempRect.top = tempRect.bottom-SBarWidth;
  117.     tempRect.bottom += 1;
  118.     tempRect.right -= (SBarWidth-1);
  119.     tempRect.left -= 1;
  120.     wdp->hScroll = NewControl(wPtr,&tempRect,"\p",TRUE,0,0,10,scrollBarProc,0L);
  121.     
  122.     /* Set scroll bars */
  123.     SetVScroll(wdp);
  124.     SetHScroll(wdp);
  125.     
  126.     /* Draw buttons */
  127.     wdp->ctrl1 = GetNewControl(128,wPtr);
  128.     wdp->ctrl2 = NULL;
  129.     
  130.     AddWindowToMenu(title);
  131.     
  132.     ShowWindow(wPtr);
  133.     return(TRUE);
  134. }
  135.  
  136.  
  137. /**************************************
  138. *    Close result window and dispose of result record
  139. */
  140.  
  141. void DisposeResults(WDPtr wdp)
  142. {
  143.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != resW)
  144.         return;
  145.     
  146.     if (wdp->inUse)
  147.         CloseWindow((WindowPtr)wdp);
  148.         
  149.     if(wdp->userHandle) {
  150.         DisposeResRec((ResultHdl)wdp->userHandle);
  151.         DisposHandle(wdp->userHandle);
  152.     }
  153.             
  154.     ClearWindowRec(wdp);
  155. }
  156.  
  157.  
  158. /**************************************
  159. *    Completely redraws a result window
  160. */
  161.  
  162. void DrawResWinAll(WDPtr wdp,short dummy)
  163. {
  164.     GrafPtr            savePort;
  165.     Rect                area,linebox,viewRect;
  166.     short                i,visLines;
  167.     ResultHdl        resHdl;
  168.     HitlistHdl        hlHdl;
  169.     CString80Hdl    bufHdl;
  170.     WindowPtr        topWindow = FrontWindow();
  171.     short             vert,horiz;
  172.     short                bufPos,hitPos,horizPos;
  173.     SignedByte        oldState;
  174.     RgnHandle        oldClipRgn,newClipRgn;
  175.     Boolean            ret;
  176.     
  177.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != resW)
  178.         return;
  179.     
  180.     /* Locate and lock down result data */
  181.     resHdl = (ResultHdl)(wdp->userHandle);
  182.     if(resHdl == NULL)
  183.         return;
  184.     bufHdl = (**resHdl).descBufHdl;
  185.     oldState=LockHandleHigh((Handle)bufHdl);
  186.     hlHdl = (**resHdl).hlHdl;
  187.     
  188.     savePort = ChangePort((GrafPtr)wdp);
  189.     
  190.     DrawResHeader(wdp,resHdl);
  191.     
  192.     GetViewRect((WindowPtr)wdp,&area);
  193.     /* Calculate text area without small margin (for redrawing) */
  194.     viewRect = area;
  195.     InsetRect(&viewRect,RES_MARGIN,0);
  196.     
  197.     /* How many lines to be shown */
  198.     visLines = (area.bottom - area.top) / fMonaco.height;
  199.  
  200.     hitPos = GetCtlValue(wdp->vScroll);    /* first hit on screen */
  201.     /* Check whether buffer contains enough lines */
  202.     if(    (hitPos + visLines > (**resHdl).buftop + MAXBUFLINES) ||
  203.             (hitPos < (**resHdl).buftop) ) {
  204.         /* Refill buffer with new chunk of data */
  205.         StartWaitCursor();
  206.         ret = FillDEBuffer(resHdl,hitPos,TRUE);
  207.         InitCursor();
  208.         if( !ret )
  209.             goto err;
  210.     }
  211.  
  212.     bufPos = hitPos - (**resHdl).buftop;    /* where in buffer is first line? */
  213.  
  214.     /* empty drawing area */
  215.     EraseRect(&area);
  216.     
  217.     /* store old clip region */
  218.     oldClipRgn = NewRgn();
  219.     GetClip(oldClipRgn);
  220.     
  221.     /* calculate horizontal and vertical drawing positions */
  222.     horizPos = GetCtlValue(wdp->hScroll);
  223.     horiz = area.left + RES_MARGIN - horizPos*fMonaco.finfo.widMax;
  224.                     /* this takes horizontal scrolling into account */
  225.     vert = area.top + fMonaco.finfo.ascent + fMonaco.finfo.leading;
  226.     
  227.     /* initialise area for "selected" box (hilighted hits) */
  228.     linebox = area;
  229.     linebox.bottom = linebox.top + fMonaco.height;
  230.  
  231.     /* Replace clip region by section of clip region and text viewRect area */
  232.     newClipRgn = NewRgn();
  233.     RectRgn(newClipRgn,&viewRect);
  234.     SectRgn(oldClipRgn,newClipRgn,newClipRgn);
  235.  
  236.     /* now draw line by line and advance printing position */
  237.     for(    i = 0;
  238.             i < visLines && bufPos < MAXBUFLINES && hitPos < (**resHdl).nhits;
  239.             ++i, ++bufPos, ++hitPos, vert += fMonaco.height ) {
  240.  
  241.         SetClip(newClipRgn);
  242.         MoveTo(horiz,vert);
  243.         DrawString( (StringPtr)(*bufHdl)[bufPos] );
  244.     
  245.         /* Reset old clip region */
  246.         SetClip(oldClipRgn);
  247.         
  248.         /* Hilite if selected */
  249.         if( !gInBackground &&
  250.                 (WindowPtr)wdp == topWindow && GetSelectState(hlHdl,hitPos) )
  251.             DoInvertRect(&linebox);
  252.         OffsetRect(&linebox,0,fMonaco.height);    /* next line */
  253.     }
  254.     
  255.     DisposeRgn(newClipRgn);        
  256.     DisposeRgn(oldClipRgn);
  257.     
  258. err:
  259.     SetPort(savePort);
  260.     HSetState((Handle)bufHdl,oldState);
  261. }
  262.  
  263.  
  264. /**************************************
  265. *    Redraws one line of a result window
  266. */
  267.  
  268. static void DrawResWin1(WDPtr wdp, short updown)
  269. {
  270.     GrafPtr            savePort;
  271.     Rect                area,linebox,viewRect;
  272.     short                visLines;
  273.     ResultHdl        resHdl;
  274.     HitlistHdl        hlHdl;
  275.     CString80Hdl    bufHdl;
  276.     WindowPtr        topWindow = FrontWindow();
  277.     short                vert,horiz;
  278.     short                hitPos,bufPos,horizPos;
  279.     SignedByte         oldState;
  280.     RgnHandle        oldClipRgn,newClipRgn;
  281.     Boolean            ret;
  282.     
  283.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != resW)
  284.         return;
  285.     
  286.     /* Locate and lock down result data */
  287.     resHdl = (ResultHdl)(wdp->userHandle);
  288.     if(resHdl == NULL)
  289.         return;
  290.     bufHdl = (**resHdl).descBufHdl;
  291.     oldState = LockHandleHigh((Handle)bufHdl);
  292.     hlHdl = (**resHdl).hlHdl;
  293.             
  294.     savePort = ChangePort((GrafPtr)wdp);
  295.     GetViewRect((WindowPtr)wdp,&area);    
  296.     /* Calculate text area without small margin (for redrawing) */
  297.     viewRect = area;
  298.     InsetRect(&viewRect,RES_MARGIN,0);
  299.  
  300.     /* How many lines on screen ? */
  301.     visLines = (area.bottom - area.top) / fMonaco.height;
  302.     if (visLines < 1)
  303.         return;
  304.  
  305.     /* first hit on page = first line on screen */
  306.     hitPos = GetCtlValue(wdp->vScroll);
  307.     /* Check whether buffer contains enough lines */
  308.     if(    (hitPos + visLines > (**resHdl).buftop + MAXBUFLINES) ||
  309.             (hitPos < (**resHdl).buftop) ) {
  310.         /* Refill buffer with new chunk of data */
  311.         StartWaitCursor();
  312.         ret = FillDEBuffer(resHdl,hitPos,TRUE);
  313.         InitCursor();
  314.         if( !ret )
  315.             goto err;
  316.     }
  317.     
  318.     /* calculate horizontal and vertical drawing positions */
  319.     horizPos = GetCtlValue(wdp->hScroll);
  320.     horiz = area.left + RES_MARGIN - horizPos*fMonaco.finfo.widMax;
  321.     vert = area.top + fMonaco.finfo.ascent + fMonaco.finfo.leading;
  322.  
  323.     /* Draw first line or last line ? */
  324.     if( updown > 0) { /* Down arrown/page => move upwards */
  325.         hitPos += visLines-1;    /* we must redraw last line on screen */
  326.         vert += fMonaco.height * (visLines-1);
  327.     }
  328.  
  329.     /* Is last line blank? Then we can exit */
  330.     if(hitPos > (**resHdl).nhits)
  331.         goto err;
  332.  
  333.     bufPos = hitPos - (**resHdl).buftop; /* where in buffer */
  334.  
  335.     /* store old clip region */
  336.     oldClipRgn = NewRgn();
  337.     GetClip(oldClipRgn);
  338.     
  339.     /* Replace clip region by section of clip region and text view area */
  340.     newClipRgn = NewRgn();
  341.     RectRgn(newClipRgn,&viewRect);
  342.     SectRgn(oldClipRgn,newClipRgn,newClipRgn);
  343.     SetClip(newClipRgn);
  344.     DisposeRgn(newClipRgn);    
  345.         
  346.     /* Draw that line */
  347.     MoveTo(horiz,vert);
  348.     DrawString( (StringPtr)(*bufHdl)[bufPos] );
  349.         
  350.     /* Reset old clip region */
  351.     SetClip(oldClipRgn);
  352.     DisposeRgn(oldClipRgn);
  353.     
  354.     /* Is it selected ? */
  355.     if( (WindowPtr)wdp == topWindow && GetSelectState(hlHdl,hitPos) ) {
  356.         linebox = area;
  357.         linebox.bottom = vert + fMonaco.finfo.descent;
  358.         linebox.top = linebox.bottom - fMonaco.height;
  359.         DoInvertRect(&linebox);
  360.     }
  361.  
  362. err:
  363.     SetPort(savePort);
  364.     HSetState((Handle)bufHdl,oldState);
  365. }
  366.  
  367.  
  368. /**************************************
  369. *    (De)Selects all hits and redraws screen
  370. */
  371.  
  372. void SelectAllResults(WDPtr wdp,Boolean what)
  373. {
  374.     short            i;
  375.     ResultHdl    resHdl;
  376.     Rect            r;
  377.     GrafPtr        savePort;
  378.     
  379.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != resW)
  380.         return;
  381.         
  382.     resHdl = (ResultHdl)(wdp->userHandle);
  383.     if(resHdl == NULL)
  384.         return;
  385.  
  386.     savePort = ChangePort((GrafPtr)wdp);
  387.     for( i = 0; i < (**resHdl).nhits; ++i)
  388.         SelectDraw(wdp,i,what);
  389.         
  390.     InvalRect(&((WindowPtr)wdp)->portRect);
  391.     GetViewRect((WindowPtr)wdp,&r);
  392.     ValidRect(&r);
  393.     SetPort(savePort);
  394. }
  395.  
  396.  
  397. /**************************************
  398. *    (De)Hilites selected records
  399. */
  400.  
  401. void SelectDraw(WDPtr wdp, short i, short what)
  402. {
  403.     ResultHdl    resHdl;
  404.     HitlistHdl    hlHdl;
  405.     short            oldState;
  406.     Rect            viewRect;
  407.     short            screenTop,visLines;
  408.     
  409.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != resW)
  410.         return;
  411.  
  412.     resHdl = (ResultHdl)(wdp->userHandle);
  413.     if(resHdl == NULL)
  414.         return;
  415.     hlHdl = (**resHdl).hlHdl;
  416.  
  417.     oldState = GetSelectState(hlHdl,i);
  418.     SetSelectState(hlHdl,i,what);
  419.     
  420.     /* if new state different from old state, we invert box around record */
  421.     if(oldState != what) {
  422.         GetViewRect((WindowPtr)wdp,&viewRect);
  423.         screenTop = GetCtlValue(wdp->vScroll);    /* first hit on screen */
  424.         visLines = (viewRect.bottom - viewRect.top) / fMonaco.height;
  425.         if(i >= screenTop && i < screenTop + visLines) {
  426.             viewRect.top += (i-screenTop) * fMonaco.height;
  427.             viewRect.bottom = viewRect.top + fMonaco.height;
  428.             DoInvertRect(&viewRect);
  429.         }
  430.     
  431.         if(what ) ++(**resHdl).nsel;
  432.         else --(**resHdl).nsel;
  433.     }
  434. }
  435.  
  436.  
  437. /**************************************
  438. *    Redrawing of screen after scrolling or sizing 
  439. */
  440.  
  441. void AdjustResText(WindowPtr wPtr,short oldvalue,short newvalue,
  442.                         scrollBarType which)
  443. {
  444.     void            (*drawFct)(WDPtr, short);
  445.     Rect            r;
  446.     RgnHandle    updateRgn, clip, eraseRgn;
  447.     ResultHdl    resHdl;
  448.     short            delta = oldvalue-newvalue;
  449.     WDPtr            wdp = FindMyWindow(wPtr);
  450.     GrafPtr        savePort;
  451.     
  452.     if(wPtr == NULL || ((WindowPeek)wPtr)->windowKind != resW)
  453.         return;
  454.  
  455.     resHdl = (ResultHdl)wdp->userHandle;
  456.     if(resHdl == NULL)
  457.         return;
  458.     
  459.     savePort = ChangePort(wPtr);
  460.     /* calculate drawing area */
  461.     GetViewRect(wPtr,&r);
  462.     
  463.     /* We need a new region for ScrollRect */
  464.     updateRgn  = NewRgn();
  465.     
  466.     if(which == vertBar) {
  467.         /* Scroll screen vertically */
  468.         ScrollRect(&r,0,delta * fMonaco.height,updateRgn);
  469.         /* Redraw complete screen or only one line (top or bottom) ? */
  470.         if(delta == 1 || delta == -1)
  471.             drawFct = DrawResWin1;
  472.         else
  473.             drawFct = DrawResWinAll;
  474.     }
  475.     else {
  476.         /* scroll screen horizontally */
  477.         ScrollRect(&r,delta * fMonaco.finfo.widMax, 0,updateRgn);
  478.         drawFct = DrawResWinAll;    /* redraw complete screen */
  479.     }
  480.     
  481.     /* clip drawing area and do drawing */
  482.     clip = wPtr->clipRgn;
  483.     wPtr->clipRgn = updateRgn;
  484.     (*drawFct)(wdp,-delta);
  485.     wPtr->clipRgn = clip;
  486.     DisposeRgn(updateRgn);
  487.     SetPort(savePort);
  488. }
  489.  
  490.  
  491. /**************************************
  492. *    Callback procedure called by TrackControl 
  493. */
  494.  
  495. static pascal void    ScrollResProc(ControlHandle theControl, short theCode)
  496. {
  497.     short            oldValue,newValue;
  498.     WindowPtr    ctlWindow=(*theControl)->contrlOwner;
  499.     short            max=GetCtlMax(theControl);
  500.     
  501.     if(theCode == gScrollCode) {
  502.         oldValue=GetCtlValue(theControl);    
  503.         newValue=oldValue+gScrollAmt;
  504.         /* limit check */
  505.         if(newValue < 0) newValue=0;
  506.         if(newValue > max) newValue=max;
  507.             
  508.         SetCtlValue( theControl, newValue );
  509.         AdjustResText(ctlWindow,oldValue,newValue,gScrollDir);
  510.     }
  511. }
  512.  
  513.  
  514. /**************************************
  515. *    Handling of key clicks in result window contents region
  516. */
  517.  
  518. void DoResClicks(WDPtr wdp, EventRecord *eventPtr)
  519. {
  520.     ControlHandle    theControl;
  521.     short                cntlCode;
  522.     short                oldvalue,newvalue;
  523.     Rect                viewRect;
  524.     short                pagesize;
  525.     Point                where;
  526.     GrafPtr            savePort;
  527.  
  528.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != resW)
  529.         return;
  530.  
  531.     savePort = ChangePort((GrafPtr)wdp);
  532.     where = eventPtr->where;
  533.     GlobalToLocal(&where);    /* convert to local coordinates     */
  534.     GetViewRect((WindowPtr)wdp,&viewRect);
  535.     
  536.     if (!(cntlCode = FindControl(where, (WindowPtr)wdp, &theControl))) {
  537.         if(PtInRect(where,&viewRect))
  538.             DoResContentClick(eventPtr,&viewRect,wdp);
  539.     }
  540.     else {
  541.         if( theControl == wdp->ctrl1) {
  542.             if( cntlCode == inButton )
  543.                 if (TrackControl(theControl,where,NULL))
  544.                     ExportRes(wdp);
  545.             SetPort(savePort);
  546.             return;
  547.         }
  548.         else if( theControl == wdp->vScroll ) {    /* click in scroll bar */
  549.             gScrollDir = vertBar;
  550.             pagesize = (viewRect.bottom - viewRect.top) / fMonaco.height;
  551.         }
  552.         else if (theControl == wdp->hScroll) { 
  553.             gScrollDir = horizBar;
  554.             pagesize = (viewRect.right - viewRect.left - 2*RES_MARGIN) /
  555.                             fMonaco.finfo.widMax;;
  556.         }
  557.         
  558.         if(cntlCode == inThumb) {
  559.             oldvalue=GetCtlValue(theControl);
  560.             TrackControl(theControl, where, NULL);
  561.             AdjustResText((WindowPtr)wdp,oldvalue,GetCtlValue(theControl),gScrollDir);
  562.         }
  563.         else {
  564.             switch(cntlCode) {
  565.                 case inUpButton: gScrollAmt = -1;
  566.                     break;
  567.                 case inDownButton: gScrollAmt = 1;
  568.                     break;
  569.                 case inPageUp: gScrollAmt = -pagesize;
  570.                     break;
  571.                 case inPageDown: gScrollAmt = pagesize;
  572.                     break;
  573.             }
  574.             gScrollCode=cntlCode;
  575.             TrackControl(theControl, where, (ProcPtr)ScrollResProc);
  576.         } /* end else (cntlCode == inThumb) */
  577.     } /* end else FindControl */
  578.     SetPort(savePort);
  579. }
  580.  
  581.  
  582. /**************************************
  583. *    Load results, check for database version and open window
  584. *    ( also called from CheckApp() )
  585. */
  586.  
  587. Boolean Load1Results(short w,StringPtr fName, short vRefNum)
  588. {
  589.     Str255        temp;
  590.     WDPtr            wdp;
  591.     QueryHdl        queryHdl;
  592.     HitmapHdl    hitmapHdl;
  593.     ResultHdl    resHdl;
  594.     short            dbcode;
  595.           
  596.    /* Read in resources from file */
  597.    if(ReadResults(fName,vRefNum,&queryHdl,&hitmapHdl)) {
  598.         wdp = &gWindows[w];
  599.  
  600.        /* Check for database version  */
  601.          dbcode = (**queryHdl).dbcode;
  602.         if( strcmp( (**queryHdl).DBRelNum,gDBInfo[dbcode].DBRelNum ) ) {
  603.             DisposHandle((Handle)queryHdl);
  604.             DisposHandle((Handle)hitmapHdl);
  605.             ErrorMsg(ERR_INCVERSION);
  606.             return(FALSE);
  607.         }
  608.  
  609.         /* Initialise result record */
  610.         if( !InitResultRec(&resHdl, dbcode, hitmapHdl, queryHdl) ) {
  611.             DisposHandle((Handle)queryHdl);
  612.             DisposHandle((Handle)hitmapHdl);
  613.             ErrorMsg(ERR_MEMORY);
  614.             return(FALSE);
  615.         }
  616.         if( !NewResultWindow(w,wdp,resHdl,fName) )
  617.             DisposeResults(wdp);
  618.  
  619.         wdp->vRefNum = vRefNum;
  620.         wdp->dirty = FALSE;
  621.         wdp->inited = TRUE;
  622.     }
  623. }
  624.  
  625.  
  626. /**************************************
  627. *    Communication with user to load results from disk
  628. */
  629.  
  630. void LoadResults()
  631. {
  632.     Point         where;
  633.     SFTypeList    myTypes;
  634.     SFReply         reply;
  635.     short            w;
  636.     
  637.     if( (w=GetFreeWindow() ) == -1 ) {
  638.         ErrorMsg(ERR_MAXWIN);
  639.         return;
  640.     }
  641.  
  642.     /* Get file name */
  643.     HandleActivates(FrontWindow(),0);
  644.     CenterSFDlg(getDlgID,&where);
  645.     myTypes[0] = kResFileType;
  646.     SFGetFile(where,"\p",(ProcPtr)resFileFilter,1,myTypes,NULL,
  647.         &reply);     /* ask for file name */
  648.  
  649.    if (reply.good == TRUE)    {
  650.        StartWaitCursor();
  651.        Load1Results(w,reply.fName,reply.vRefNum);
  652.           InitCursor();
  653.    }
  654. }
  655.  
  656.  
  657. /**************************************
  658. *    Read result file from disk
  659. *    Return value:    TRUE, if successful
  660. *                        FALSE, if an error occurred
  661. */
  662.  
  663. static Boolean ReadResults(StringPtr fName, short vRefNum,
  664.                                     QueryHdl *queryHdlP, HitmapHdl *hitmapHdlP)
  665. {
  666.     short            oldVRefNum;
  667.     Str255        volName;
  668.     short            refNum;
  669.     OSErr            err;
  670.     Boolean        ret=FALSE;            /* We assume failure */
  671.     short            curResFile;
  672.     
  673.     /* set default directory */
  674.     GetVol(volName,&oldVRefNum);
  675.     SetVol(NULL,vRefNum);
  676.     
  677.     /* store refnum of current resource file */
  678.     curResFile = CurResFile();
  679.     
  680.     /* Open resource file. We ignore data fork of result file completely */
  681.     if( (refNum=OpenResFile(fName)) == -1) {
  682.         sprintf(gError,LoadErrorStr(ERR_OPENRES,FALSE),
  683.                     PtoCstr(fName),ResError());
  684.         CtoPstr((char *)fName);
  685.         ErrorMsg(0);
  686.         goto end;
  687.     }
  688.  
  689.     /* Make it active resource file and read necessary resources */
  690.     UseResFile(refNum);    
  691.     *queryHdlP = (QueryHdl)Get1Resource(kQueryRsrcType,kStdRsrc);
  692.     if( (err=ResError()) != noErr ) {
  693.         CloseResFile(refNum);
  694.         sprintf(gError,LoadErrorStr(ERR_READRES,FALSE),
  695.                     PtoCstr(fName),err);
  696.         CtoPstr((char *)fName);
  697.         ErrorMsg(0);
  698.         goto end;
  699.     }
  700.     
  701.     *hitmapHdlP = (HitmapHdl)Get1Resource(kHitmapRsrcType,kStdRsrc);
  702.     if( (err = ResError()) != noErr ){
  703.         CloseResFile(refNum);
  704.         sprintf(gError,LoadErrorStr(ERR_READRES,FALSE),
  705.                     PtoCstr(fName),err);
  706.         CtoPstr((char *)fName);
  707.         ErrorMsg(0);
  708.         goto end;
  709.     }
  710.     
  711.     /* Detach resources and close file */
  712.     DetachResource((Handle)*queryHdlP);
  713.     DetachResource((Handle)*hitmapHdlP);
  714.     CloseResFile(refNum);
  715.     ret=TRUE;
  716.  
  717. end:
  718.     /* reset old values */
  719.    UseResFile(curResFile);
  720.     SetVol(NULL,oldVRefNum);
  721.     return(ret);
  722. }
  723.  
  724.  
  725. /**************************************
  726. *    Filter procedure for SFGetFile. We show only files created by our application
  727. *    (we should also check file type !)
  728. *    Return value:    TRUE, if file is to be hidden
  729. *                        FALSE, if file should be displayed in dialog
  730. */
  731.  
  732. static pascal Boolean resFileFilter(ParmBlkPtr myPBp) /* only our files */
  733. {
  734.     return( (*myPBp).fileParam.ioFlFndrInfo.fdCreator != kApplSignature );
  735. }
  736.  
  737.  
  738. /**************************************
  739. *    Draw header lines in result window
  740. */
  741.  
  742. void DrawResHeader(WDPtr wdp, ResultHdl resHdl)
  743. {
  744.     Rect        myRect;
  745.     GrafPtr    savePort;
  746.     char        line[256];
  747.     Str255    str;
  748.     short        border,vert;
  749.     
  750.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != resW)
  751.         return;
  752.  
  753.     savePort = ChangePort((GrafPtr)wdp);
  754.     
  755.     /* Erase top three lines */
  756.     myRect=((WindowPtr)wdp)->portRect;
  757.     myRect.bottom = myRect.top+3*fMonaco.height-1;
  758.     myRect.right = myRect.left + 200;
  759.     EraseRect(&myRect);
  760.     myRect.right = ((WindowPtr)wdp)->portRect.right;
  761.     
  762.     /* use system font */
  763.     TextFont(fSystem.num);
  764.     TextSize(12);
  765.     
  766.     /* Print number of records and how many are selected */
  767.     border = (myRect.bottom-myRect.top-fSystem.height)/2;
  768.     vert = myRect.bottom-border-fSystem.finfo.descent-fSystem.finfo.leading-2;
  769.     GetIndString(str,OTHERS,RESHEADER);
  770.     sprintf(line,PtoCstr(str),(**resHdl).nhits,(**resHdl).nsel);
  771.     MoveTo(RES_MARGIN,vert);
  772.     DrawString(CtoPstr((char *)line));
  773.     
  774.     /* reset window font */
  775.     TextFont(fMonaco.num);
  776.     TextSize(9);
  777.     
  778.     /* Draw double line */
  779.     MoveTo(0,myRect.bottom);
  780.     Line(myRect.right,0);
  781.     MoveTo(0,myRect.bottom-2);
  782.     Line(myRect.right,0);
  783.     
  784.     /* no need to redraw it */
  785.     ValidRect(&myRect);
  786.     
  787.     /* (De)Activate "Export selection" button */
  788.     if( (**resHdl).nsel ) {
  789.         if(wdp->ctrl1)
  790.             HiliteControl(wdp->ctrl1,ACTIVE);
  791.     }
  792.     else {
  793.         if(wdp->ctrl1)
  794.             HiliteControl(wdp->ctrl1,INACTIVE);
  795.     }
  796.     
  797.     SetPort(savePort);
  798. }
  799.  
  800.  
  801. /**************************************
  802. *    Show hiliting or remove it (eg if window becomes active/inactive)
  803. */
  804.  
  805. void HideShowResSelections(WDPtr wdp, Boolean show)
  806. {
  807.     ResultHdl        resHdl;
  808.     HitlistHdl        hlHdl;
  809.     CString80Hdl    bufHdl;
  810.     SignedByte         oldState;
  811.     Rect                 viewRect;
  812.     short             screenTop,visLines;
  813.     short             i;
  814.     short             top,horizPos,horiz,vert;
  815.     RgnHandle        oldClipRgn,newClipRgn;
  816.     GrafPtr            savePort;
  817.     Boolean            ret;
  818.     
  819.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != resW)
  820.         return;
  821.  
  822.     resHdl = (ResultHdl)(wdp->userHandle);
  823.     if(resHdl == NULL)
  824.         return;
  825.     bufHdl = (**resHdl).descBufHdl;
  826.     oldState = LockHandleHigh((Handle)bufHdl);
  827.     hlHdl = (**resHdl).hlHdl;
  828.     
  829.     savePort = ChangePort((GrafPtr)wdp);
  830.     GetViewRect((WindowPtr)wdp,&viewRect);
  831.     top = viewRect.top;
  832.  
  833.     /* store old clip region */
  834.     oldClipRgn = NewRgn();
  835.     GetClip(oldClipRgn);
  836.  
  837.     /* Replace clip region text view area */
  838.     newClipRgn = NewRgn();
  839.     RectRgn(newClipRgn,&viewRect);
  840.     SetClip(newClipRgn);
  841.  
  842.     /* calculate horizontal and vertical drawing positions */
  843.     horizPos = GetCtlValue(wdp->hScroll);
  844.     horiz = viewRect.left + RES_MARGIN - horizPos*fMonaco.finfo.widMax;
  845.  
  846.     screenTop = GetCtlValue(wdp->vScroll);    /* first hit on screen */
  847.     visLines = (viewRect.bottom - viewRect.top) / fMonaco.height;
  848.  
  849.     /* Check whether buffer contains enough lines */
  850.     if(    (screenTop + visLines > (**resHdl).buftop + MAXBUFLINES) ||
  851.             (screenTop < (**resHdl).buftop) ) {
  852.         /* Refill buffer with new chunk of data */
  853.         StartWaitCursor();
  854.         ret = FillDEBuffer(resHdl,screenTop,TRUE);
  855.         InitCursor();
  856.         if( !ret )
  857.             goto err;
  858.     }
  859.  
  860.     for(i = screenTop; i < screenTop + visLines && i <(**resHdl).nhits; ++i) {
  861.         if(GetSelectState(hlHdl,i)) {
  862.             viewRect.top = top + (i-screenTop) * fMonaco.height;
  863.             viewRect.bottom = viewRect.top + fMonaco.height;
  864.             EraseRect(&viewRect);
  865.             vert = viewRect.top + fMonaco.finfo.ascent + fMonaco.finfo.leading;
  866.             MoveTo(horiz,vert);
  867.             DrawString( (StringPtr)(*bufHdl)[i - (**resHdl).buftop] );
  868.             if(show)
  869.                 DoInvertRect(&viewRect);
  870.             ValidRect(&viewRect);
  871.         }
  872.     }
  873.     
  874. err:
  875.     /* Reset old clip region */
  876.     SetClip(oldClipRgn);
  877.     DisposeRgn(newClipRgn);        
  878.     DisposeRgn(oldClipRgn);
  879.     SetPort(savePort);
  880.     HSetState((Handle)bufHdl,oldState);
  881. }