home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacGofer 0.22d / MacGofer Sources / mac_find.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-03  |  19.1 KB  |  900 lines  |  [TEXT/MPS ]

  1. #include "mac.h"
  2. #define MPW TRUE
  3. #include "mac_ctype.h"
  4.  
  5. static char findstring[256], replacestring[256];
  6. static Boolean backwards = FALSE, wraparound = FALSE,
  7.                casesens  = FALSE, fullword   = FALSE;
  8.  
  9.  
  10. Boolean wrappedround = FALSE;
  11. static Boolean inited = FALSE;
  12.  
  13. int finddialog();
  14. Boolean findLine();
  15. ListHandle SetUpDefnList();
  16.  
  17. extern char *safemalloc(), *nextDefn(), ftolower();
  18.  
  19. extern ListHandle SetUpModuleList(), createlist();
  20. extern short KeyModifiers;
  21.  
  22. extern pascal      Boolean ListDlgFilter();
  23. extern short       dlgOtherButton;
  24. extern CursHandle  watchcurs;                /* Ibeam and Watch cursors */
  25.  
  26.  
  27. Boolean equalstrings(patt,match,len,casesens)
  28. char *patt, *match;
  29. int len;
  30. Boolean casesens;
  31. {
  32.    int i;
  33.    
  34.    if(casesens)
  35.      return(strncmp(patt,match,len) == 0);
  36.  
  37.    else for(i=0; i<len; ++i,++patt,++match)
  38.        {
  39.          if(ftolower(*match)!=*patt)
  40.        return(FALSE);
  41.        }
  42.  
  43.    return(TRUE);
  44.        
  45.    /* Handle diacriticals -- removed for speed */
  46. #if 0
  47.    char *matchcopy = safemalloc(len+1);
  48.    Boolean res;
  49.  
  50.    strncpy(matchcopy,match,len);
  51.    matchcopy[len] = '\0';
  52.    
  53.    res = equalstring(patt,matchcopy,casesens,TRUE);
  54.    free(matchcopy);
  55.    return(res);
  56. #endif
  57. }
  58.  
  59.  
  60. /*
  61.     Wraparound does not work for repeated search.
  62.     Will search twice.
  63.     Solution -- remember original posn and set in wrapround code,
  64.     use this if wrapped around AND the direction hasn't changed.
  65. */
  66.  
  67. Boolean searchForText(text,windex,backwards)
  68. char *text;
  69. int windex;
  70. Boolean backwards;
  71. {
  72.   Boolean found = FALSE;
  73.   Boolean saveLock;
  74.  
  75.   if(inited && isLegalWindow(windex) && *text != '\0')
  76.     {
  77.       CharsHandle chbuff = TEGetText(TEHANDLE(windex));
  78.       char *chs;
  79.       int tlen = strlen(text);
  80.       short last = backwards? 0:
  81.                   (*TEHANDLE(windex))->teLength - tlen; 
  82.       short first = backwards? (*TEHANDLE(windex))->selStart-1:
  83.                   (*TEHANDLE(windex))->selEnd;
  84.       short pos, inc = backwards? -1: 1;
  85.       short count = wraparound?1:0;
  86.       
  87.       char *temptext;
  88.  
  89.       /* Convert the pattern to lower case, if necessary */     
  90.       if(!casesens)
  91.         {
  92.       int i;
  93.           temptext = safemalloc(tlen+1);
  94.       for(i=0; i < tlen; ++i)
  95.         *(temptext+i) = isupper(*(text+i))? tolower(*(text+i)):
  96.                         *(text+i);
  97.       text = temptext;
  98.     }
  99.       
  100.      SafeHLock((Handle) chbuff, &saveLock);
  101.      chs = (char *) **chbuff;
  102.       
  103.       SpinCursor(0);
  104.  
  105.       /* Repeat once or twice */  
  106.       do {      
  107.  
  108.         for (pos = first; inc > 0? pos <= last: pos >= last; pos+=inc)
  109.           {
  110.         if((pos & 0x3f) == 0)
  111.           SpinCursor(inc);
  112.  
  113.         if(equalstrings(text,chs+pos,tlen,casesens))
  114.           {
  115.              TESetSelect(pos,pos+tlen,TEHANDLE(windex));
  116.              found = TRUE;
  117.              break;
  118.           }
  119.        }
  120.      
  121.         if(!found && wraparound && !wrappedround)
  122.           {
  123.             last = backwards?
  124.                (*TEHANDLE(windex))->selEnd:
  125.                    (*TEHANDLE(windex))->selStart-1;
  126.         first = backwards?
  127.                    (*TEHANDLE(windex))->teLength - tlen:
  128.            0;
  129.             wrappedround = TRUE;
  130.       }
  131.       } while (!found && count-- > 0);
  132.  
  133.  
  134.       if(!found)
  135.         SysBeep(1);
  136.       else
  137.         ScrollToSelection(windex);
  138.  
  139.       SafeHUnlock((Handle) chbuff, saveLock);
  140.       InitCursor();
  141.     }
  142.   return(found);
  143. }
  144.  
  145.  
  146.  
  147.  
  148. Replace(replace,windex)
  149. char *replace;
  150. int windex;
  151. {
  152.   if(inited)
  153.     {
  154.       short start = (*TEHANDLE(windex))->selStart;
  155.  
  156.       /* Is there enough memory to undo the replace? */      
  157.       CheckMemory("Replace",strlen(replace)+strlen(findstring)+512);
  158.  
  159.       /* Save the undo information */
  160.       pasteundo(windex);
  161.  
  162.       TEDelete(TEHANDLE(windex));
  163.       if(*replace != '\0')
  164.         TEInsert((Ptr)replace, strlen(replace), TEHANDLE(windex));
  165.       
  166.       /* Highlight the new string */
  167.       TESetSelect(start,(*TEHANDLE(windex))->selEnd,TEHANDLE(windex));
  168.       changed(windex);
  169.  
  170.       /* Scroll to the new position */
  171.       AdjustScrollBars(windex);
  172.       ScrollToSelection(windex);
  173.     }
  174. }
  175.  
  176.  
  177.  
  178. Boolean SelIsSearch(windex,text)
  179. int windex;
  180. char *text;
  181. {
  182.   CharsHandle chbuff;
  183.   char *chs;
  184.   Boolean saveLock;
  185.  
  186.   short start = (*TEHANDLE(windex))->selStart,
  187.         end   = (*TEHANDLE(windex))->selEnd;
  188.  
  189.   int tlen = strlen(text);
  190.   Boolean equal;
  191.  
  192.   char *temptext;
  193.  
  194.   /* Convert the pattern to lower case, if necessary */     
  195.   if(!casesens)
  196.     {
  197.       int i;
  198.       temptext = safemalloc(tlen+1);
  199.       for(i=0; i < tlen; ++i)
  200.       *(temptext+i) = isupper(*(text+i))? tolower(*(text+i)):*(text+i);
  201.       text = temptext;
  202.     }
  203.  
  204.   chbuff = (CharsHandle) (*TEHANDLE(windex))->hText;   
  205.   SafeHLock((Handle) chbuff, &saveLock);
  206.   chs = (char *) *chbuff;
  207.  
  208.   equal = tlen > 0 && end-start == tlen && equalstrings(text,chs+start,tlen,casesens);
  209.  
  210.   SafeHUnlock((Handle) chbuff, saveLock);
  211.   if(!casesens)
  212.     free(text);
  213.  
  214.   return(equal);
  215. }
  216.  
  217.  
  218.  
  219. doreplaceagain(windex)
  220. int windex;
  221. {
  222.   if(isLegalWindow(windex))
  223.     if(SelIsSearch(windex,findstring) ||
  224.        searchForText(findstring,windex,backwards))
  225.       Replace(replacestring,windex);
  226. }
  227.  
  228.  
  229. dofind(windex)
  230. int windex;
  231. {
  232.   int dofind = finddialog();
  233.   
  234.   if(isLegalWindow(windex) && dofind != CANCEL)
  235.     {
  236.       updatewindows();
  237.       
  238.       /* Reset the "backwards" search direction */
  239.       setitem(Menu_Find,MItem_Find_Backwards,backwards?"Find Forwards":"Find Backwards");
  240.  
  241.       if(dofind == REPLACE_ALL)
  242.         {
  243.       TESetSelect(0,0,TEHANDLE(windex));
  244.           while(searchForText(findstring,windex,FALSE))
  245.             Replace(replacestring,windex);
  246.     }
  247.       else if((SelIsSearch(windex,findstring) || searchForText(findstring,windex,backwards))
  248.               && *replacestring != '\0')
  249.         Replace(replacestring,windex);
  250.     }
  251. }
  252.  
  253. dofindagain(windex)
  254. int windex;
  255. {
  256.   if(isLegalWindow(windex))
  257.     searchForText(findstring,windex,backwards);
  258. }
  259.  
  260.  
  261. dofindbackwards(windex)
  262. int windex;
  263. {
  264.   if(isLegalWindow(windex))
  265.     searchForText(findstring,windex,!backwards);
  266. }
  267.  
  268.  
  269. /*
  270.   Separated to deal with that *!#@ Gofer GC bug
  271. */
  272.  
  273. #define NO_MORE_MODULES    (-1)
  274. int dofindtypedefndialog();
  275.  
  276. dofindtypedefn()
  277. {
  278.   DialogPtr typedlg;
  279.   ListHandle defnlist;
  280.   int module;
  281.   Boolean showingmodules = TRUE;
  282.  
  283.   SetCursor(&(qd.arrow));
  284.   typedlg = GetNewDialog(Res_Dlg_Type,nil,(WindowPtr) -1);
  285.  
  286.   dlgOtherButton = 0;
  287.    
  288.   DisableButton(typedlg,MODULES);
  289.   DisableButton(typedlg,FIND);
  290.  
  291.   /* Now show dialog window */
  292.   ShowWindow(typedlg);
  293.   highlightDefault(typedlg);  
  294.  
  295.   defnlist = SetUpModuleList(typedlg,Res_DItem_Type,TRUE,TRUE,0);
  296.  
  297.   do
  298.     {
  299.       module = dofindtypedefndialog(typedlg,defnlist,showingmodules);
  300.       if(module == NO_MORE_MODULES)
  301.         break;
  302.       defnlist = SetUpDefnList(typedlg,module,Res_DItem_Type,FALSE);
  303.       (*defnlist)->selFlags = lNoExtend;
  304.       showingmodules = FALSE;
  305.     }
  306.   while (TRUE);
  307. }
  308.  
  309. int dofindtypedefndialog(typedlg,defnlist,showingmodules)
  310. DialogPtr typedlg;
  311. ListHandle defnlist;
  312. Boolean showingmodules;
  313. {
  314.  
  315.   for(;;)
  316.     {
  317.       short itemhit;
  318.  
  319.       ModalDialog((ModalFilterProcPtr) ListDlgFilter,&itemhit);
  320.       switch(itemhit)
  321.         {
  322.       case Res_DItem_Type:
  323.         {
  324.           Point mousePt;
  325.           GrafPtr savePort;
  326.           Cell cell;
  327.               Boolean doubleclick;
  328.  
  329.           GetPort(&savePort);
  330.           SetPort((*defnlist)->port);
  331.           GetMouse(&mousePt);
  332.           SetPort(savePort);
  333.  
  334.  
  335.           doubleclick = LClick(mousePt,KeyModifiers,defnlist);
  336.           SetPt(&cell,0,0);
  337.               if(LGetSelect(TRUE,&cell,defnlist))
  338.             EnableButton(typedlg,FIND);
  339.           
  340.           if(!doubleclick)
  341.         break;
  342.           itemhit = FIND;
  343.         }
  344.  
  345.           case FIND:
  346.         {
  347.           Cell cell;
  348.           SetPt(&cell,0,0);
  349.  
  350.           if(!LGetSelect(TRUE,&cell,defnlist))
  351.             {
  352.               SysBeep(1);
  353.           break;
  354.                 }
  355.  
  356.           if(showingmodules)
  357.             {
  358.            LDelColumn(0,0,defnlist);
  359.            LDispose(defnlist);
  360.              DisableButton(typedlg,FIND);
  361.            
  362.            showingmodules = FALSE;
  363.             EnableButton(typedlg,MODULES);
  364.              setitext(gethandle(Res_DItem_TypeHeader,typedlg),"Definitions:");
  365.            SetButtonTitle(typedlg,FIND,"Type");
  366.            
  367.            /* HACK */
  368.            return((int) cell.v);
  369.         }
  370.               showtypes(defnlist);
  371.         }
  372.             
  373.           case CANCEL:
  374.         LDispose(defnlist);
  375.             DisposDialog(typedlg);
  376.             return(NO_MORE_MODULES);
  377.       
  378.       case MODULES:
  379.         LDelColumn(0,0,defnlist);
  380.         LDispose(defnlist);
  381.           DisableButton(typedlg,FIND);
  382.           DisableButton(typedlg,MODULES);
  383.         SetButtonTitle(typedlg,FIND,"List");
  384.           setitext(gethandle(Res_DItem_TypeHeader,typedlg),"Modules:");
  385.  
  386.         defnlist = SetUpModuleList(typedlg,Res_DItem_Type,FALSE,TRUE,0);
  387.         showingmodules = TRUE;
  388.         break;
  389.         }
  390.     }
  391. }
  392.  
  393.  
  394.  
  395. showtypes(defnlist)
  396. ListHandle defnlist;
  397. {
  398.   Cell cell;
  399.   short len;
  400.   char buff[256];
  401.   
  402.   windowtofront(worksheet);
  403.  
  404.   SetPt(&cell,0,0);
  405.   while(LGetSelect(TRUE,&cell,defnlist))
  406.     {
  407.       len = 255;
  408.       LGetCell(buff,&len,cell,defnlist);
  409.       buff[len] = '\0';
  410.       showType(buff);
  411.       ++(cell.v);
  412.     }
  413.   printPrompt();
  414. }
  415.  
  416.  
  417. dofindtype()
  418. {
  419.   char defn[256];
  420.     
  421.   getdefnfromselection(defn);
  422.  
  423.   if(defn[0] == '\0')
  424.     SysBeep(1);
  425.   else
  426.     {
  427.       windowtofront(worksheet);
  428.       writeNewLine();
  429.       finddefn(defn,TYPE);
  430.     }
  431. }
  432.  
  433.  
  434. getdefnfromselection(defn)
  435. char *defn;
  436. {
  437.   TEHandle teh;
  438.   thefrontwindow = findMyWindow(FrontWindow());
  439.  
  440.   defn[0] = '\0';
  441.   
  442.   if(thefrontwindow != ILLEGAL_WINDOW && (teh=TEHANDLE(thefrontwindow)) != NIL)
  443.     {
  444.        char *text = *(char **)((*teh)->hText);
  445.        if((*teh)->selStart != (*teh)->selEnd)
  446.          {
  447.        strncpy(defn,text+(*teh)->selStart,
  448.                     (*teh)->selEnd - (*teh)->selStart);
  449.        defn[(*teh)->selEnd - (*teh)->selStart] = '\0';
  450.        if(strpbrk(defn," \t\n\r\f") != NULL)
  451.          defn[0] = '\0';
  452.      }
  453.        else
  454.          {
  455.         short testart, teend, length = (*teh)->teLength;
  456.         int id_found = FALSE;
  457.         char ch;
  458.         
  459.         for ( testart = (*teh)->selStart-1;
  460.               testart >= 0 && ((ch=text[testart]) == '_'  || ch == '\'' || isalnum(ch)); --testart)
  461.           id_found |= !isdigit(ch);
  462.         ++testart;
  463.                     
  464.         for ( teend = (*teh)->selStart;
  465.               teend <= length && ((ch=text[teend]) == '_'  || ch == '\'' || isalnum(ch)); ++teend)
  466.           id_found |= !isdigit(ch);
  467.         --teend;
  468.         
  469.         if(!id_found)
  470.           {
  471.               for ( testart = (*teh)->selStart-1; testart >= 0 && (issymb(text[testart]) || text[teend] == '~'); --testart)
  472.              /* SKIP */;
  473.         ++testart;
  474.                     
  475.             for ( teend = (*teh)->selStart; teend < length && (issymb(text[teend]) || text[teend] == '~'); ++teend)
  476.               /* SKIP */;
  477.         --teend;
  478.         
  479.         id_found = testart <= teend;
  480.           }
  481.           
  482.         if(id_found)
  483.           {
  484.             int length = teend-testart+1;
  485.         if(length > 255)
  486.           length = 255;
  487.         else if (length <= 0)
  488.           return;
  489.           
  490.             strncpy(defn,text+testart,length);
  491.         defn[length] = '\0';
  492.               }
  493.      }
  494.     }
  495. }
  496.  
  497.  
  498. /*
  499.   Split into dofinddefn/finddefn because of Gofer GC.
  500. */
  501.  
  502.  
  503. dofinddefn()
  504. {
  505.   char defn[256];
  506.  
  507.   getdefnfromselection(defn);
  508.     
  509.   if(defn[0] == '\0')
  510.      SysBeep(1);
  511.    else
  512.     {
  513.       writeNewLine();
  514.       finddefn(defn,FIND);
  515.     }
  516. }
  517.  
  518.  
  519. dofinddefns()
  520. {
  521.   char defn[256];
  522.   int action = FIND;
  523.  
  524.   action = defndialog(defn);
  525.   updatewindows();
  526.  
  527.   finddefn(defn,action);
  528. }
  529.  
  530.  
  531. finddefn(defn,action)
  532. char *defn;
  533. int action;
  534. {
  535.   if(action == FIND && *defn != '\0')
  536.     {
  537.       char file[256];
  538.       int windex, line;
  539.       short volnum, dummy;
  540.  
  541.       long dirID;
  542.  
  543.       /* Get zero-indexed line for defn in file */     
  544.       if(getfilefor(defn,&line,file,&volnum,&dirID,&dummy) == FALSE)
  545.         {
  546.       windowtofront(worksheet);
  547.           return;
  548.     }
  549.  
  550.       windex = doopenfile(file,volnum,dirID);
  551.  
  552.       if(!findLine(windex,line))
  553.           ActivateTheWindow(FrontWindow(),TRUE);
  554.     }
  555.  
  556.   else if (action == TYPE)
  557.     {
  558.       windowtofront(worksheet);
  559.       showType(defn);
  560.       printPrompt();
  561.     }
  562. }
  563.  
  564.  
  565. extern int errorLine, errorMod;
  566.  
  567. findError()
  568. {
  569.    char file[256];
  570.    short volnum;
  571.    long dirID;
  572.  
  573.    if(getprojfile(errorMod,file,&volnum,&dirID) == FALSE)
  574.      return;
  575.  
  576.    findFile(file,volnum,dirID,errorLine);
  577. }
  578.  
  579.  
  580. findFile(file,volnum,dirID,line)
  581. char *file;
  582. short volnum;
  583. long dirID;
  584. int line;
  585. {
  586.    int windex;
  587.    
  588.    resolvealias(&file,&volnum,&dirID,FALSE);
  589.      
  590.    windex = findMyWindowName(file,volnum,dirID);
  591.   
  592.    if(isLegalWindow(windex))
  593.       openthewindow(windex);
  594.    else
  595.       windex = doopenfile(file,volnum,dirID);
  596.  
  597.    if(!findLine(windex,line))
  598.      ActivateTheWindow(FrontWindow(),TRUE);
  599. }
  600.  
  601.  
  602.  
  603. Boolean findLine(windex,line)
  604. int windex, line;
  605. {
  606.   if(isLegalWindow(windex) && OPEN(windex))
  607.     {
  608.       short linestart, lineend;
  609.       TEHandle teh = TEHANDLE(windex);
  610.       
  611.       if(iconic(windex))
  612.         DeIconiseWindow(windex);
  613.  
  614.       if(line > (*teh)->nLines)
  615.         line = (*teh)->nLines;
  616.       if(line <= 0)
  617.         line = 1;
  618.  
  619.       linestart = (*teh)->lineStarts[line-1];
  620.       lineend = line == (*teh)->nLines? (*teh)->teLength:
  621.                                         (*teh)->lineStarts[line];
  622.       TESetSelect(linestart,lineend,teh);
  623.       ActivateTheWindow(WINDOW(windex),TRUE);
  624.       updatewindows();
  625.       ScrollToSelection(windex);
  626.       return(TRUE);
  627.     }
  628.   else
  629.     return(FALSE);
  630. }
  631.  
  632.  
  633. ListHandle SetUpDefnList(dlg,modind,item,drawframe)
  634. DialogPtr dlg;
  635. short modind, item;
  636. Boolean drawframe;
  637. {
  638.   int i;
  639.   ListHandle hlist;
  640.   Cell cell;
  641.   /* NB: Do not declare module "short" -- if you do, Gofer's GC may bite */
  642.   int module = (int) GetModFromIndex(modind);
  643.   int numdefns = initmoddefns(module+1);
  644.   
  645.   SetCursor(&(qd.arrow));
  646.   hlist = createlist(dlg,item,numdefns,drawframe);
  647.   
  648.   /* Set up the definition list. */  
  649.   for( i=0; i < numdefns; ++i )
  650.     {
  651.       char *nextdefn = nextDefn();
  652.  
  653.       /* Ignore system Identifiers and bad values */
  654.       if(nextdefn != NULL)
  655.         {
  656.           SetPt(&cell,0,i);
  657.           LSetCell(nextdefn,strlen(nextdefn),cell,hlist);
  658.     }
  659.     }
  660.     
  661.   enableSingletons(dlg,hlist,numdefns);
  662.  
  663.   /* Tidy up and draw the list */    
  664.   donemoddefns();
  665.   LDoDraw(TRUE,hlist);
  666.   LUpdate((*hlist)->port->visRgn,hlist);
  667.   
  668.   resetDlgSearch(hlist,TRUE);
  669.     
  670.   return(hlist);
  671. }
  672.  
  673.  
  674. /*
  675.   Separated to deal with that *!#@ Gofer GC bug
  676. */
  677.  
  678. int dodefndialog();
  679.  
  680. defndialog(defn)
  681. char *defn;
  682. {
  683.   DialogPtr defndlg;
  684.   ListHandle defnlist;
  685.   Boolean showingmodules = TRUE;
  686.  
  687.   SetCursor(&(qd.arrow));
  688.   defndlg = GetNewDialog(Res_Dlg_Definitions,nil,(WindowPtr) -1);
  689.  
  690.   dlgOtherButton = TYPE;
  691.    
  692.   DisableButton(defndlg,MODULES);
  693.   DisableButton(defndlg,FIND);
  694.   DisableButton(defndlg,TYPE);
  695.  
  696.   /* Now show dialog window */
  697.   ShowWindow(defndlg);
  698.   highlightDefault(defndlg); 
  699.  
  700.   defnlist = SetUpModuleList(defndlg,Res_DItem_Definition,TRUE,TRUE,0);
  701.  
  702.   do
  703.     {
  704.       int module = dodefndialog(defn,defndlg,defnlist,showingmodules);
  705.       if(module >= 0)
  706.         return(module);
  707.       defnlist = SetUpDefnList(defndlg,-(module+1),Res_DItem_Definition,FALSE);
  708.       (*defnlist)->selFlags = lOnlyOne;
  709.       showingmodules = FALSE;
  710.     }
  711.   while (TRUE);
  712. }
  713.  
  714.  
  715. dodefndialog(defn,defndlg,defnlist,showingmodules)
  716. char *defn;
  717. DialogPtr defndlg;
  718. ListHandle defnlist;
  719. Boolean showingmodules;
  720. {
  721.   short itemhit;
  722.  
  723.   for(;;)
  724.     {
  725.       ModalDialog((ModalFilterProcPtr) ListDlgFilter,&itemhit);
  726.       switch(itemhit)
  727.         {
  728.       case Res_DItem_Definition:
  729.         {
  730.           Point mousePt;
  731.           GrafPtr savePort;
  732.           Cell cell;
  733.           Boolean doubleclick;
  734.  
  735.           GetPort(&savePort);
  736.           SetPort((*defnlist)->port);
  737.           GetMouse(&mousePt);
  738.           SetPort(savePort);
  739.  
  740.           doubleclick = LClick(mousePt,0,defnlist);
  741.           SetPt(&cell,0,0);
  742.               if(LGetSelect(TRUE,&cell,defnlist))
  743.             {
  744.               EnableButton(defndlg,FIND);
  745.               if(showingmodules)
  746.                 DisableButton(defndlg,TYPE);
  747.           else
  748.             EnableButton(defndlg,TYPE);
  749.         }
  750.           
  751.           if(!doubleclick)
  752.         break;
  753.  
  754.           itemhit = FIND;
  755.         }
  756.  
  757.           case FIND:
  758.       case TYPE:
  759.         {
  760.           Cell cell;
  761.           short len;
  762.           SetPt(&cell,0,0);
  763.  
  764.           if(!LGetSelect(TRUE,&cell,defnlist))
  765.             {
  766.               SysBeep(1);
  767.           break;
  768.                 }
  769.  
  770.           if(showingmodules)
  771.             {
  772.            LDelColumn(0,0,defnlist);
  773.            LDispose(defnlist);
  774.              DisableButton(defndlg,TYPE);
  775.              DisableButton(defndlg,FIND);
  776.  
  777.             EnableButton(defndlg,MODULES);
  778.              setitext(gethandle(Res_DItem_DefnHeader,defndlg),"Definitions:");
  779.            SetButtonTitle(defndlg,FIND,"Find");
  780.  
  781.            return((int)-(cell.v+1));
  782.         }
  783.         
  784.           /* Get the defn name -- no more than 255 characters */
  785.           len = 255;
  786.           LGetCell((DataPtr)defn,&len,cell,defnlist);
  787.           defn[len] = '\0';
  788.         }
  789.             
  790.           case CANCEL:
  791.         LDispose(defnlist);
  792.             DisposDialog(defndlg);
  793.             return(itemhit);
  794.       
  795.       case MODULES:
  796.         LDelColumn(0,0,defnlist);
  797.         LDispose(defnlist);
  798.           DisableButton(defndlg,FIND);
  799.           DisableButton(defndlg,TYPE);
  800.           DisableButton(defndlg,MODULES);
  801.         SetButtonTitle(defndlg,FIND,"List");
  802.  
  803.         defnlist = SetUpModuleList(defndlg,Res_DItem_Definition,FALSE,TRUE,0);
  804.         showingmodules = TRUE;
  805.           setitext(gethandle(Res_DItem_DefnHeader,defndlg),"Modules:");
  806.         break;
  807.         }
  808.     }
  809. }
  810.  
  811.  
  812. int finddialog()
  813. {
  814.   DialogPtr fnddlg;
  815.   short itemhit;
  816.   Boolean okisreplace = FALSE;
  817.  
  818.   if(!inited)
  819.     {
  820.       strcpy(findstring,"");
  821.       strcpy(replacestring,"");
  822.       backwards = FALSE;
  823.       wraparound = FALSE;
  824.       inited = TRUE;
  825.     }
  826.     
  827.   wrappedround = FALSE;
  828.  
  829.   /* Initialise dialog */  
  830.   SetCursor(&(qd.arrow));
  831.   fnddlg = GetNewDialog(Res_Dlg_Find,nil,(WindowPtr) -1);
  832.   ShowWindow(fnddlg);
  833.   highlightDefault(fnddlg);
  834.   
  835.   /* Initialise strings */
  836.   SetDlgItemText(fnddlg, Res_DItem_Replaceitem, replacestring);
  837.   SetDlgItemText(fnddlg, Res_DItem_Finditem,    findstring);
  838.  
  839.   /* Set Check Boxes */
  840.   SetCtlValue(getctlhandle(Res_DItem_Backwards,  fnddlg), backwards);    
  841.   SetCtlValue(getctlhandle(Res_DItem_Wraparound, fnddlg), wraparound);    
  842.   SetCtlValue(getctlhandle(Res_DItem_Casesens,   fnddlg), casesens);    
  843.  
  844.   /* Set the Find/Replace Button */  
  845.   if(*replacestring != '\0')
  846.     {
  847.       okisreplace = TRUE;
  848.       SetButtonTitle(fnddlg,OK,"Replace");
  849.     }
  850.  
  851.   /* Now show dialog window */
  852.   ShowWindow(fnddlg);
  853.   highlightDefault(fnddlg);
  854.  
  855.   for(;;)
  856.     {
  857.       ModalDialog((ModalFilterProcPtr) NIL,&itemhit);
  858.       switch(itemhit)
  859.         {
  860.       case REPLACE_ALL:
  861.           case FIND:
  862.             getitext(gethandle(Res_DItem_Finditem,    fnddlg), findstring);
  863.             getitext(gethandle(Res_DItem_Replaceitem, fnddlg), replacestring);
  864.         if(itemhit == REPLACE_ALL && *replacestring=='\0')
  865.           {
  866.             SysBeep(1);
  867.         break;
  868.           }
  869.  
  870.         backwards =  GetCtlValue(getctlhandle(Res_DItem_Backwards,  fnddlg));    
  871.           wraparound = GetCtlValue(getctlhandle(Res_DItem_Wraparound, fnddlg));    
  872.           casesens =   GetCtlValue(getctlhandle(Res_DItem_Casesens,   fnddlg));    
  873.             
  874.           case CANCEL:
  875.             DisposDialog(fnddlg);
  876.             return(itemhit);
  877.         
  878.       case Res_DItem_Backwards:
  879.       case Res_DItem_Wraparound:
  880.       case Res_DItem_Casesens:
  881.         InvertDlgItemValue(fnddlg,itemhit);
  882.          break;
  883.         
  884.       case Res_DItem_Replaceitem:
  885.             getitext(gethandle(Res_DItem_Replaceitem, fnddlg), replacestring);
  886.         if(okisreplace && *replacestring == '\0')
  887.           {
  888.             okisreplace = FALSE;
  889.             SetButtonTitle(fnddlg,OK,"Find");
  890.           }
  891.         else if(!okisreplace && *replacestring != '\0')
  892.              {
  893.             okisreplace = TRUE;
  894.               SetButtonTitle(fnddlg,OK,"Replace");
  895.          }
  896.        break;
  897.         }
  898.     }
  899. }
  900.