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

  1. /*
  2. *********************************************************************
  3. *    
  4. *    Sequence.c
  5. *    Handling of sequence window
  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. #include <ctype.h>
  22.  
  23. #include "EMBL-Search.h"
  24. #include "EMBL-Search.rsrc.h"
  25.  
  26. /*
  27. ******************************* Prototypes ***************************
  28. */
  29.  
  30. #include "sequence.h"
  31. #include "util.h"
  32. #include "window.h"
  33. #include "export.h"
  34. #include "pstr.h"
  35. #include "xref.h"
  36. #include "click.h"
  37.  
  38. static Boolean OpenSeqWindow(CString80Hdl descBufHdl, short pos, short w, SeqRecHdl seqRecHdl);
  39. static Boolean NewSequenceRec(SeqRecHdl *new);
  40. static Boolean NewSeqLineBuf(CString80Hdl *new);
  41. static Boolean InitSequenceRec(SeqRecHdl *new, short dbcode);
  42. static void DisposeSeqRec(SeqRecHdl seqRecHdl);
  43. static Boolean FillSequenceRec(ResultHdl resHdl, short bufPos, SeqRecHdl seqRecHdl);
  44. static OSErr ReadLine(short refNum, long *count, Ptr buf, StringPtr fName);
  45. static void DrawSeqWin1(WDPtr wdp, short updown);
  46. static pascal void ScrollSeqProc(ControlHandle theControl, short theCode);
  47.  
  48.  
  49.  
  50. /*
  51. ******************************** Global variables *****************
  52. */
  53.  
  54. extern short        gSysVersion;
  55. extern WDRec        gWindows[MAXWIN];
  56. extern Rect            gSeqWinRect;
  57. extern FONTINFO    fMonaco,fSystem;
  58. extern char            gError[256];
  59. extern short         gScrollAmt,gScrollCode;
  60. extern Boolean        gScrollDir;
  61. extern DBInfo        gDBInfo[DB_NUM];
  62. extern IndexFiles    gFileList;
  63. extern Prefs         gPrefs;
  64. extern Boolean        gInBackground;
  65.  
  66. /**************************************
  67. *    Create and open a new sequence window
  68. */
  69.  
  70. Boolean NewSequenceWindow(ResultHdl resHdl,short bufPos)
  71. {
  72.     short                w;
  73.     SeqRecHdl        seqRecHdl;
  74.     CString80Hdl    descBufHdl;
  75.  
  76.     if( resHdl == NULL )
  77.         return(FALSE);
  78.         
  79.     if( (descBufHdl = (**resHdl).descBufHdl) == NULL )
  80.         return(FALSE);
  81.         
  82.     if( (w=GetFreeWindow()) == -1 )
  83.         return(ErrorMsg(ERR_MAXWIN));
  84.  
  85.     if( !InitSequenceRec(&seqRecHdl,(**resHdl).dbcode) )
  86.         return(ErrorMsg(ERR_MEMORY));
  87.     
  88.     if( !FillSequenceRec(resHdl,bufPos,seqRecHdl) ) {
  89.         DisposeSeqRec(seqRecHdl);
  90.         DisposHandle((Handle)seqRecHdl);
  91.         return(FALSE);
  92.     }
  93.     else {
  94.         return(OpenSeqWindow(descBufHdl,bufPos-(**resHdl).buftop,w,seqRecHdl));
  95.     }
  96. }
  97.  
  98.  
  99. /**************************************
  100. *    Open a new sequence window
  101. */
  102.  
  103. static Boolean OpenSeqWindow(CString80Hdl descBufHdl,
  104.                         short pos,short w,SeqRecHdl seqRecHdl)
  105. {
  106.     Rect            tempRect;
  107.     WStateData    **stateHdl;
  108.     WDPtr            wdp;
  109.     Str255        title;
  110.     WindowPtr    wPtr;
  111.     
  112.     tempRect = gSeqWinRect;
  113.     AdjustPosition(w,&tempRect);
  114.  
  115.     wdp = &gWindows[w];
  116.     SetPort(NewWindow(wdp,&tempRect,"\p",FALSE,documentProc + 8,(void *)-1,TRUE,0L));
  117.  
  118.     wPtr = (WindowPtr)wdp;
  119.  
  120.     /* anchor sequence record */
  121.     wdp->userHandle = (Handle)seqRecHdl;
  122.             
  123.     ExtractEname(descBufHdl,pos,title);
  124.     SetWTitle(wPtr,title);
  125.     TextFont(fMonaco.num);
  126.     TextSize(9);
  127.  
  128.     ((WindowPeek)wPtr)->windowKind = seqW;
  129.     pstrcpy(wdp->fName,title);
  130.     wdp->vRefNum = 0;
  131.     wdp->dirty = TRUE;
  132.     wdp->inited = FALSE;
  133.     wdp->inUse = TRUE;
  134.     
  135.     /* adjust zoom standard state */
  136.     stateHdl = (WStateData **)((WindowPeek)wPtr)->dataHandle;
  137.     AdjustWSize(seqW,&(**stateHdl).stdState,fMonaco.height,fMonaco.finfo.widMax);
  138.     
  139.     /* draw vertical scroll bar */
  140.     tempRect = wPtr->portRect;
  141.     tempRect.left = tempRect.right-SBarWidth;
  142.     tempRect.right += 1;
  143.     tempRect.top -= 1;
  144.     tempRect.bottom -= (SBarWidth-1);
  145.     wdp->vScroll = NewControl(wPtr,&tempRect,"\p",TRUE,0,0,10,scrollBarProc,0L);
  146.     
  147.     /* draw horizontal scroll bar */
  148.     tempRect = wPtr->portRect;
  149.     tempRect.top = tempRect.bottom-SBarWidth;
  150.     tempRect.bottom += 1;
  151.     tempRect.right -= (SBarWidth-1);
  152.     tempRect.left -= 1;
  153.     wdp->hScroll = NewControl(wPtr,&tempRect,"\p",TRUE,0,0,10,scrollBarProc,0L);
  154.     
  155.     /* Set scroll bars */
  156.     SetVScroll(wdp);
  157.     SetHScroll(wdp);
  158.     
  159.     AddWindowToMenu(title);
  160.     
  161.     ShowWindow(wPtr);
  162.     return(TRUE);
  163. }
  164.  
  165.  
  166.  
  167. /**************************************
  168. *    Allocates movable memory block for sequence record
  169. *    Return values:
  170. *        TRUE if successful, FALSE on failure
  171. *        By side effect: Handle to this block
  172. */
  173.  
  174. static Boolean NewSequenceRec(SeqRecHdl *new)
  175. {
  176.     *new = (SeqRecHdl)NewHandleClear(sizeof(SequenceRec));
  177.     return( *new != NULL );
  178. }
  179.  
  180.  
  181. /**************************************
  182. *    Allocates movable memory block for sequence line buffer
  183. *    Return values:
  184. *        TRUE if successful, FALSE on failure
  185. *        By side effect: Handle to this block
  186. */
  187.  
  188. static Boolean NewSeqLineBuf(CString80Hdl *new)
  189. {
  190.     *new = (CString80Hdl)NewHandleClear((Size)SEQBUFLINES * sizeof(CString80));
  191.     return( *new != NULL );
  192. }
  193.  
  194.  
  195. /**************************************
  196. *    Gets a new sequence record, incl. line buffer, and initialises it
  197. *    Return values:
  198. *        TRUE if successful, FALSE on failure
  199. *        By side effect: Handle to new sequence record
  200. */
  201.  
  202. static Boolean InitSequenceRec(SeqRecHdl *new, short dbcode)
  203. {
  204.     SeqRecPtr seqPtr;
  205.     short        i;
  206.     
  207.     if( new == NULL )
  208.         return(FALSE);
  209.         
  210.     /* Allocate memory for sequence record */
  211.     if ( !NewSequenceRec(new) )
  212.         return( FALSE );
  213.     
  214.     /* Get a pointer to it */
  215.     LockHandleHigh((Handle)*new);
  216.     seqPtr = (SeqRecPtr)**new;
  217.     
  218.     /* Allocate memory for sequence line buffer */
  219.     if ( !NewSeqLineBuf(&seqPtr->lineBufHdl) ) {
  220.         DisposHandle((Handle)*new);
  221.         *new = NULL;
  222.         return(FALSE);
  223.     }
  224.     
  225.     /* Init other fields */
  226.     seqPtr->dbcode=dbcode;
  227.     seqPtr->nlines = 0;
  228.     seqPtr->buftop = 0;
  229.     seqPtr->seqStart = 0L;
  230.     for(i=0;i<MAXBUFPARTS;seqPtr->bufpart[i++]=0L)
  231.         ;
  232.     seqPtr->xrefHdl = NULL;
  233.     seqPtr->firstSel = seqPtr->lastSel = -1;
  234.     
  235.     HUnlock((Handle)*new);
  236.     return(TRUE);
  237. }
  238.  
  239.  
  240. /**************************************
  241. *    Dispose of contents of an existing sequence record
  242. *    Return values:
  243. *        none
  244. */
  245.  
  246. static void DisposeSeqRec(SeqRecHdl seqRecHdl)
  247. {
  248.     SeqRecPtr seqPtr;
  249.     
  250.     if(seqRecHdl == NULL)
  251.         return;
  252.     
  253.     /* Get a pointer to the sequence record */
  254.     LockHandleHigh((Handle)seqRecHdl);
  255.     seqPtr = *seqRecHdl;
  256.     
  257.     /* Free memory linked to this record */
  258.     if( seqPtr->lineBufHdl != NULL)
  259.         DisposHandle((Handle)seqPtr->lineBufHdl);
  260.     if( seqPtr->xrefHdl != NULL)
  261.         DisposHandle((Handle)seqPtr->xrefHdl);
  262.         
  263.     HUnlock((Handle)seqRecHdl);
  264. }
  265.  
  266.  
  267.  
  268. /**************************************
  269. *    Close sequence window and dispose of sequence record
  270. */
  271.  
  272. void DisposeSequence(WDPtr wdp)
  273. {
  274.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != seqW)
  275.         return;
  276.         
  277.     if (wdp->inUse)
  278.         CloseWindow((WindowPtr)wdp);
  279.         
  280.     if(wdp->userHandle) {
  281.         DisposeSeqRec((SeqRecHdl)wdp->userHandle);
  282.         DisposHandle(wdp->userHandle);
  283.     }
  284.         
  285.     ClearWindowRec(wdp);
  286. }
  287.  
  288.  
  289. /**************************************
  290. *    Fill sequence line buffer from disk so that "from" is in buffer.
  291. *    To avoid continous loading when a user browses through the sequence,
  292. *    the buffer is filled (if possible) such that "from" is in the middle of
  293. *    the buffer.
  294. *    Return values:
  295. *        TRUE, if successful,
  296. *        FALSE, if an error occurred
  297. */
  298.  
  299. Boolean FillLineBuffer(SeqRecHdl seqRecHdl,short first)
  300. {
  301.     CString80Ptr    buf;
  302.     Str255            fName;
  303.     short                vRefNum,input;
  304.     SignedByte        oldState;
  305.     short                i,part;
  306.     u_long            pos;
  307.     long                size,count;
  308.     DescRec            rec;
  309.     OSErr                err = noErr;
  310.     char                line[80],*s,*t;
  311.     
  312.     if(seqRecHdl == NULL)
  313.         return(FALSE);
  314.         
  315.     if( (**seqRecHdl).lineBufHdl == NULL )
  316.         return(FALSE);
  317.         
  318.     /* calculate first hit to be loaded. The size of the buffer guarantees
  319.         that we always load at least two screen fulls */
  320.     if (first >= SEQBUFLINES/2)
  321.         part = (first - SEQBUFLINES/4) / (SEQBUFLINES/2);
  322.     else part = 0;
  323.     
  324.     /* Open sequence data file */
  325.     pstrcpy(fName,(**seqRecHdl).fName);
  326.     vRefNum = (**seqRecHdl).vRefNum;
  327.     if(OpenMacFileReadOnly(fName,vRefNum,&input, TRUE) != noErr)
  328.         return(FALSE);
  329.     
  330.     /* Lock block */
  331.     oldState = LockHandleHigh((Handle)(**seqRecHdl).lineBufHdl);
  332.     buf = *((**seqRecHdl).lineBufHdl);
  333.     
  334.     if( (err = SetFPos(input,fsFromStart,(**seqRecHdl).bufpart[part])) != noErr) {
  335.         sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),
  336.                         PtoCstr(fName),err );
  337.         ErrorMsg(0);
  338.     }
  339.     else {
  340.         for(i=0; i<SEQBUFLINES; ++i) { 
  341.             /* read line */
  342.             count=80;
  343.             if( (err=ReadLine(input,&count,line,fName)) != noErr )
  344.                 break;
  345.             
  346.             for(s=line,t=buf[i];*s != '\r';*t++ = *s++)
  347.                 ;
  348.             *t = EOS;
  349.     
  350.             CtoPstr((char *)buf[i]);
  351.             if( !strncmp(line,"//",2) )
  352.                 break;
  353.         }
  354.     }
  355.  
  356.     FSClose(input);
  357.     HSetState((Handle)(**seqRecHdl).lineBufHdl,oldState);
  358.     (**seqRecHdl).buftop = part*(SEQBUFLINES/2);
  359.  
  360.     return(err == noErr);
  361. }
  362.  
  363.  
  364.  
  365. /**************************************
  366. *    Reads entry line by line and stores information in SeqRec and lineBuf
  367. *    Return values:
  368. *        TRUE if successful, FALSE on failure
  369. */
  370.  
  371. static Boolean FillSequenceRec(ResultHdl resHdl,short bufPos,SeqRecHdl seqRecHdl)
  372. {
  373.     HitlistHdl        hlHdl;
  374.     short                dbcode;
  375.     Str255            indexFName,divFName;
  376.     short                input;
  377.     u_long            rec;
  378.     OSErr                err;
  379.     long                size,count,offset;
  380.     EnameRec            enameRec;
  381.     CString80Ptr    buf;
  382.     SignedByte        oldState;
  383.     short                nlines,part;
  384.     char                line[81];
  385.     char                *s,*t;
  386.     short                maxlines;
  387.     
  388.     if(resHdl == NULL || seqRecHdl == NULL)
  389.         return(FALSE);
  390.                 
  391.     if( (hlHdl = (**resHdl).hlHdl) == NULL )
  392.         return(FALSE);
  393.         
  394.     dbcode = (**seqRecHdl).dbcode;
  395.     
  396.     /* Open entryname index  */
  397.     pstrcpy(indexFName,gFileList.enameIdxFName);
  398.     if( OpenMacFileReadOnly(indexFName,gDBInfo[dbcode].InxWDRefNum,&input, TRUE) != noErr )
  399.         return(FALSE);
  400.     
  401.     /* goto appropriate position */
  402.     size = sizeof(EnameRec);
  403.     rec = (*hlHdl)[bufPos].ename_rec;
  404.     
  405.     if( (err=SetFPos(input,fsFromStart,rec*size+sizeof(Header))) != noErr) {
  406.         sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),
  407.                     PtoCstr(indexFName),err );
  408.         FSClose(input);
  409.         return(ErrorMsg(0));
  410.     }
  411.  
  412.     /* read record */
  413.     count=size;
  414.     if( ReadMacFile(input,&count,&enameRec,indexFName,TRUE) ) {
  415.         FSClose(input);
  416.         return(FALSE);
  417.     }
  418.     else
  419.         FSClose(input);
  420.     
  421.     /* convert values */
  422.     ConvertLong(&enameRec.annotation_offset);
  423.     ConvertLong(&enameRec.sequence_offset);
  424.     ConvertShort(&enameRec.div_code);
  425.     
  426.     /* Store data file name and vRefNum */    
  427.     pstrcpy(divFName,
  428.         (StringPtr)(*gDBInfo[dbcode].gDivNames + (enameRec.div_code)*(DIVNAMELEN+1)));
  429.     pstrcpy((**seqRecHdl).fName,
  430.         (StringPtr)(*gDBInfo[dbcode].gDivNames + (enameRec.div_code)*(DIVNAMELEN+1)));
  431.     (**seqRecHdl).vRefNum = gDBInfo[dbcode].SeqWDRefNum;
  432.     
  433.     /* Open sequence data file */
  434.     if( OpenMacFileReadOnly(divFName,gDBInfo[dbcode].SeqWDRefNum,&input,TRUE) != noErr )
  435.         return(FALSE);
  436.     
  437.     /* Move to entry */
  438.     offset=enameRec.annotation_offset;
  439.         
  440.     if( (err=SetFPos(input,fsFromStart,offset)) != noErr ) {
  441.         FSClose(input);
  442.         sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),PtoCstr(divFName),err );
  443.         return(ErrorMsg(0));
  444.     }
  445.  
  446.     oldState=LockHandleHigh((Handle)(**seqRecHdl).lineBufHdl);
  447.     buf = *((**seqRecHdl).lineBufHdl);
  448.     nlines=0;
  449.     part = 0;
  450.     
  451.     err=noErr;
  452.     maxlines = MAXBUFPARTS * SEQBUFLINES;
  453.     do {
  454.         RotateWaitCursor();
  455.         
  456.         /* store byte offset for every SEQBUFLINES/2th line */
  457.         if( nlines % (SEQBUFLINES/2) == 0 ) {
  458.             if( (err=GetFPos(input,&((**seqRecHdl).bufpart[part]))) != noErr ) {
  459.                 sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),
  460.                         PtoCstr(divFName),err );
  461.                 ErrorMsg(0);
  462.                 break;
  463.             }
  464.             else
  465.                 ++part;
  466.         }
  467.         
  468.         /* read line */
  469.         count=80;
  470.         if( (err=ReadLine(input,&count,line,divFName)) != noErr )
  471.             break;
  472.         
  473.         if(nlines < SEQBUFLINES) {
  474.             for(s=line,t=buf[nlines];*s != '\r';*t++ = *s++)
  475.                 ;
  476.             *t = EOS;
  477.             CtoPstr((char *)buf[nlines]);
  478.         }
  479.         
  480.         if( linetype(line,"DR") ) {
  481.             if( !ParseDRLine(seqRecHdl,line) ) {
  482.                 err = notEnoughMemoryErr;
  483.                 break;
  484.             }
  485.         }
  486.             
  487.         if( linetype(line,"SQ") ) {
  488.             if( (err=GetFPos(input,&((**seqRecHdl).seqStart))) != noErr ) {
  489.                 sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),
  490.                         PtoCstr(divFName),err );
  491.                 ErrorMsg(0);
  492.                 break;
  493.             }
  494.         }
  495.         
  496.         ++nlines;
  497.     } while( nlines < maxlines && !linetype(line,"//") );
  498.     
  499.     (**seqRecHdl).nlines = nlines;
  500.     (**seqRecHdl).buftop = 0;
  501.     
  502.     HSetState((Handle)(**seqRecHdl).lineBufHdl,oldState);
  503.     FSClose(input);
  504.     return(err == noErr);
  505. }
  506.  
  507. /**************************************
  508. *    Reads database entry line by line
  509. *    Return values:
  510. *        OSErr
  511. */
  512.  
  513. static OSErr ReadLine(short refNum, long *count, Ptr buf, StringPtr fName)
  514. {
  515.     ParamBlockRec    pb;            
  516.     OSErr            err;
  517.     
  518.     pb.ioParam.ioRefNum        = refNum;
  519.     pb.ioParam.ioCompletion    = NULL;
  520.     pb.ioParam.ioBuffer        = buf;
  521.     pb.ioParam.ioReqCount    = *count;
  522.     pb.ioParam.ioPosMode    =  ('\n' << 8) | 128 ;
  523.     pb.ioParam.ioPosOffset    = 0;
  524.     
  525.     if( (err = PBRead((ParmBlkPtr) &pb, FALSE)) == noErr ) {
  526.         *count = pb.ioParam.ioActCount;
  527.         buf[*count] = EOS;
  528.     }
  529.     else {
  530.         sprintf(gError,LoadErrorStr(ERR_READFILE,FALSE),PtoCstr(fName),err);
  531.         CtoPstr((char *)fName);
  532.         ErrorMsg(0);
  533.      }
  534.         
  535.     return(err);
  536. }
  537.  
  538.  
  539. /**************************************
  540. *    Completely redraws a sequence window
  541. */
  542.  
  543. void DrawSeqWinAll(WDPtr wdp,short dummy)
  544. {
  545.     GrafPtr            savePort;
  546.     Rect                area,linebox,viewRect;
  547.     short                i,visLines;
  548.     SeqRecHdl        seqRecHdl;
  549.     CString80Hdl    bufHdl;
  550.     WindowPtr        topWindow = FrontWindow();
  551.     short             vert,horiz;
  552.     short                bufPos,linePos,horizPos;
  553.     SignedByte        oldState;
  554.     RgnHandle        oldClipRgn,newClipRgn;
  555.     
  556.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != seqW)
  557.         return;
  558.             
  559.     /* Locate and lock down sequence data */
  560.     seqRecHdl = (SeqRecHdl)(wdp->userHandle);
  561.     if(seqRecHdl == NULL)
  562.         return;
  563.     bufHdl = (**seqRecHdl).lineBufHdl;
  564.     oldState=LockHandleHigh((Handle)bufHdl);
  565.     
  566.     savePort = ChangePort((GrafPtr)wdp);
  567.         
  568.     /* Calculate text area without small margin (for redrawing) */
  569.     GetViewRect((WindowPtr)wdp,&area);
  570.     viewRect = area;
  571.     InsetRect(&viewRect,SEQ_MARGIN,0);
  572.     
  573.     /* How many lines to be shown */
  574.     visLines = (area.bottom - area.top) / fMonaco.height;
  575.  
  576.     linePos = GetCtlValue(wdp->vScroll);    /* first hit on screen */
  577.     /* Check whether buffer contains enough lines */
  578.     if(    (linePos + visLines > (**seqRecHdl).buftop +SEQBUFLINES) ||
  579.             (linePos < (**seqRecHdl).buftop) ) {
  580.         /* Refill buffer with new chunk of data */
  581.         if( !FillLineBuffer(seqRecHdl,linePos) )
  582.             goto err;
  583.     }
  584.  
  585.     bufPos = linePos - (**seqRecHdl).buftop;    /* where in buffer is first line? */
  586.  
  587.     /* empty drawing area */
  588.     EraseRect(&area);
  589.     
  590.     /* store old clip region */
  591.     oldClipRgn = NewRgn();
  592.     GetClip(oldClipRgn);
  593.     
  594.     /* calculate horizontal and vertical drawing positions */
  595.     horizPos = GetCtlValue(wdp->hScroll);
  596.     horiz = area.left + SEQ_MARGIN - horizPos*fMonaco.finfo.widMax;
  597.                     /* this takes horizontal scrolling into account */
  598.     vert = area.top + fMonaco.finfo.ascent + fMonaco.finfo.leading;
  599.     
  600.     /* initialise area for "selected" box (hilighted hits) */
  601.     linebox = area;
  602.     linebox.bottom = linebox.top + fMonaco.height;
  603.     
  604.     /* Replace clip region by section of clip region and text view area */
  605.     newClipRgn = NewRgn();
  606.     RectRgn(newClipRgn,&viewRect);
  607.     SectRgn(oldClipRgn,newClipRgn,newClipRgn);
  608.  
  609.     /* now draw line by line and advance printing position */
  610.     for(    i = 0;
  611.             i < visLines && bufPos < SEQBUFLINES && linePos < (**seqRecHdl).nlines;
  612.             ++i, ++bufPos, ++linePos, vert += fMonaco.height ) {
  613.  
  614.         SetClip(newClipRgn);
  615.         MoveTo(horiz,vert);
  616.         DrawString( (StringPtr)(*bufHdl)[bufPos] );
  617.     
  618.         /* Reset old clip region */
  619.         SetClip(oldClipRgn);
  620.         
  621.         /* Hilite if selected */
  622.         if( !gInBackground &&
  623.                 (WindowPtr)wdp == topWindow &&
  624.                 linePos >= (**seqRecHdl).firstSel && linePos <= (**seqRecHdl).lastSel )
  625.             DoInvertRect(&linebox);
  626.         OffsetRect(&linebox,0,fMonaco.height);    /* next line */
  627.     }
  628.     
  629.     DisposeRgn(newClipRgn);        
  630.     DisposeRgn(oldClipRgn);
  631.     
  632. err:
  633.     SetPort(savePort);
  634.     HSetState((Handle)bufHdl,oldState);
  635. }
  636.  
  637.  
  638. static void DrawSeqWin1(WDPtr wdp, short updown)
  639. {
  640.     GrafPtr            savePort;
  641.     Rect                area,linebox,viewRect;
  642.     short                visLines;
  643.     SeqRecHdl        seqRecHdl;
  644.     CString80Hdl    bufHdl;
  645.     WindowPtr        topWindow = FrontWindow();
  646.     short                vert,horiz;
  647.     short                linePos,bufPos,horizPos;
  648.     SignedByte         oldState;
  649.     RgnHandle        oldClipRgn,newClipRgn;
  650.  
  651.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != seqW)
  652.         return;
  653.         
  654.     /* Locate and lock down sequence data */
  655.     seqRecHdl = (SeqRecHdl)(wdp->userHandle);
  656.     if(seqRecHdl == NULL)
  657.         return;
  658.     bufHdl = (**seqRecHdl).lineBufHdl;
  659.     oldState=LockHandleHigh((Handle)bufHdl);
  660.             
  661.     savePort = ChangePort((GrafPtr)wdp);
  662.     
  663.     /* Calculate text area without small margin (for redrawing) */
  664.     GetViewRect((WindowPtr)wdp,&area);
  665.     viewRect = area;
  666.     InsetRect(&viewRect,SEQ_MARGIN,0);
  667.  
  668.     /* How many lines on screen ? */
  669.     visLines = (area.bottom - area.top) / fMonaco.height;
  670.     if (visLines < 1)
  671.         return;
  672.  
  673.     /* first hit on page = first line on screen */
  674.     linePos = GetCtlValue(wdp->vScroll);
  675.     /* Check whether buffer contains enough lines */
  676.     if(    (linePos + visLines > (**seqRecHdl).buftop +SEQBUFLINES) ||
  677.             (linePos < (**seqRecHdl).buftop) ) {
  678.         /* Refill buffer with new chunk of data */
  679.         if( !FillLineBuffer(seqRecHdl,linePos) )
  680.             goto err;
  681.     }
  682.     
  683.     /* calculate horizontal and vertical drawing positions */
  684.     horizPos = GetCtlValue(wdp->hScroll);
  685.     horiz = area.left + SEQ_MARGIN - horizPos*fMonaco.finfo.widMax;
  686.     vert = area.top + fMonaco.finfo.ascent + fMonaco.finfo.leading;
  687.  
  688.     /* DralHandle theControl, short theCode)
  689. {
  690.     short            oldValue,newValue;
  691.     WindowPtr    ctlWindow=(*theControl)->contrlOwner;
  692.     short            max=GetCtlMax(theControl);
  693.     
  694.     if(theCode == gScrollCode) {
  695.         oldValue=GetCtlValue(theControl);    
  696.         newValue=oldValue+gScrollAmt;
  697.         /* limit check */
  698.         if(newValue < 0) newValue=0;
  699.         if(newValue > max) newValue=max;
  700.             
  701.         SetCtlValue( theControl, newValue );
  702.         AdjustSeqText(ctlWindow,oldValue,newValue,gScrollDir);
  703.     }
  704. }
  705.  
  706.  
  707. Boolean SaveSeqData(StringPtr fName,short vRefNum,SeqRecHdl seqRecHdl)
  708. {
  709.     char            *inpBuf,*outBuf;
  710.     short            input,output;
  711.     Str255        divFName;
  712.     Boolean        ret=TRUE;
  713.     DialogTHndl    myHandle;
  714.     DialogPtr    myDialog;
  715.     
  716.     if( seqRecHdl == NULL )
  717.         return(FALSE);
  718.         
  719.     /* Allocate file buffers */
  720.     inpBuf=NewPtr((Size)FILEBUF);
  721.     if(inpBuf)
  722.         if( !(outBuf=NewPtr((Size)FILEBUF)) )
  723.             DisposPtr((Ptr)inpBuf);
  724.     if ( !inpBuf || !outBuf )
  725.         return(ErrorMsg(ERR_MEMORY));
  726.  
  727.     if(gSysVersion >= 0x0700) {
  728.         myHandle = (DialogTHndl)GetResource('DLOG',EXPORT_DLG);
  729.         (**myHandle).procID = movableDBoxProc;
  730.     }
  731.     CenterDA('DLOG',EXPORT_DLG,50);
  732.     myDialog = GetNewDialog(EXPORT_DLG,NULL,(WindowPtr) -1);
  733.     DisableMenuBar();
  734.     
  735.     ParamText(fName,"\p","\p","\p");
  736.     ShowWindow(myDialog);
  737.     DrawDialog(myDialog);
  738.  
  739.     /* Open sequence data file */
  740.     pstrcpy(divFName,(**seqRecHdl).fName);
  741.     ret = (OpenMacFileReadOnly(divFName,(**seqRecHdl).vRefNum,&input, TRUE) == noErr);
  742.     if(!ret) goto end_proc;
  743.     
  744.     if( !(ret=
  745.         ( CreateMacFile(fName,vRefNum,gPrefs.creatorSig,kSeqFileType,TRUE) == noErr )) ) {
  746.         FSClose(input);
  747.         goto end_proc;
  748.     }
  749.         
  750.     if( !(ret= (OpenMacFile(fName,vRefNum, &output, TRUE) == noErr))) {
  751.         FSClose(input);
  752.         goto end_proc;
  753.     }
  754.     
  755.     ret=Export2(input,(**seqRecHdl).bufpart[0],(**seqRecHdl).seqStart,(**seqRecHdl).dbcode,
  756.                     divFName,inpBuf,outBuf,output,fName,myDialog);    
  757.     FSClose(input);    
  758.     FSClose(output);
  759.     FlushVol(NULL,vRefNum);
  760.  
  761. end_proc:
  762.     DisposPtr((Ptr)inpBuf);
  763.     DisposPtr((Ptr)outBuf);
  764.     DisposDialog(myDialog);
  765.     EnableMenuBar();
  766.     return(ret);    
  767. }
  768.  
  769. /**************************************
  770. *    (De)Selects whole sequence and redraws screen
  771. */
  772.  
  773. void SelectAllSeq(WDPtr wdp,Boolean what)
  774. {
  775.     short            i;
  776.     SeqRecHdl    seqHdl;
  777.     Rect            r;
  778.     GrafPtr        savePort;
  779.     
  780.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != seqW)
  781.         return;
  782.         
  783.     seqHdl = (SeqRecHdl)(wdp->userHandle);
  784.     if(seqHdl == NULL)
  785.         return;
  786.  
  787.     savePort = ChangePort((GrafPtr)wdp);
  788.     if(what) {
  789.         (**seqHdl).firstSel = 0;
  790.         (**seqHdl).lastSel = (**seqHdl).nlines - 1;
  791.     }
  792.     else {
  793.         (**seqHdl).firstSel = (**seqHdl).lastSel = -1;
  794.     }
  795.     
  796.     InvalRect(&((WindowPtr)wdp)->portRect);
  797.     SetPort(savePort);
  798. }
  799.  
  800.  
  801. /**************************************
  802. *    Show hiliting or remove it (eg if window becomes active/inactive)
  803. */
  804.  
  805. void HideShowSeqSelections(WDPtr wdp, Boolean show)
  806. {
  807.     SeqRecHdl        seqRecHdl;
  808.     SignedByte         oldState;
  809.     CString80Hdl    bufHdl;
  810.     Rect                 viewRect,linebox;
  811.     short             screenTop,visLines;
  812.     short             i;
  813.     short             top,horizPos,horiz,vert;
  814.     RgnHandle        oldClipRgn,newClipRgn;
  815.     GrafPtr            savePort;
  816.     
  817.     if(wdp == NULL || ((WindowPeek)wdp)->windowKind != seqW)
  818.         return;
  819.         
  820.     /* Locate and lock down sequence data */
  821.     seqRecHdl = (SeqRecHdl)(wdp->userHandle);
  822.     if(seqRecHdl == NULL)
  823.         return;
  824.     bufHdl = (**seqRecHdl).lineBufHdl;
  825.     oldState=LockHandleHigh((Handle)bufHdl);
  826.         
  827.     savePort = ChangePort((GrafPtr)wdp);
  828.         
  829.     GetViewRect((WindowPtr)wdp,&viewRect);
  830.     top = viewRect.top;
  831.     
  832.     /* store old clip region */
  833.     oldClipRgn = NewRgn();
  834.     GetClip(oldClipRgn);
  835.  
  836.     /* Replace clip region by section of clip region and text view area */
  837.     newClipRgn = NewRgn();
  838.     RectRgn(newClipRgn,&viewRect);
  839.     SectRgn(oldClipRgn,newClipRgn,newClipRgn);
  840.  
  841.     /* calculate horizontal and vertical drawing positions */
  842.     horizPos = GetCtlValue(wdp->hScroll);
  843.     horiz = viewRect.left + SEQ_MARGIN - horizPos*fMonaco.finfo.widMax;
  844.                     /* this takes horizontal scrolling into account */
  845.     vert = viewRect.top + fMonaco.finfo.ascent + fMonaco.finfo.leading;
  846.     
  847.     /* initialise area for "selected" box (hilighted hits) */
  848.     linebox = viewRect;
  849.     linebox.bottom = linebox.top + fMonaco.height;
  850.  
  851.     screenTop = GetCtlValue(wdp->vScroll);    /* first hit on screen */
  852.     visLines = (viewRect.bottom - viewRect.top) / fMonaco.height;
  853.  
  854.     /* Check whether buffer contains enough lines */
  855.     if(    (screenTop + visLines > (**seqRecHdl).buftop +SEQBUFLINES) ||
  856.             (screenTop < (**seqRecHdl).buftop) ) {
  857.         /* Refill buffer with new chunk of data */
  858.         if( !FillLineBuffer(seqRecHdl,screenTop) )
  859.             goto err;
  860.     }
  861.  
  862.     for(i = screenTop; i < screenTop + visLines && i <(**seqRecHdl).nlines; ++i) {
  863.         if( i >= (**seqRecHdl).firstSel && i <= (**seqRecHdl).lastSel ) {
  864.             viewRect.top = top + (i-screenTop) * fMonaco.height;
  865.             viewRect.bottom = viewRect.top + fMonaco.height;
  866.             EraseRect(&viewRect);
  867.             vert = viewRect.top + fMonaco.finfo.ascent + fMonaco.finfo.leading;
  868.             MoveTo(horiz,vert);
  869.             DrawString( (StringPtr)(*bufHdl)[i - (**seqRecHdl).buftop] );
  870.             if(show)
  871.                 DoInvertRect(&viewRect);
  872.             ValidRect(&viewRect);
  873.         }
  874.     }
  875.     
  876. err:
  877.     /* Reset old clip region */
  878.     SetClip(oldClipRgn);
  879.     DisposeRgn(newClipRgn);        
  880.     DisposeRgn(oldClipRgn);
  881.     SetPort(savePort);
  882.     HSetState((Handle)bufHdl,oldState);
  883. }