home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / dirs / snoopdos_451.lzh / 'Liner / Source / search.c < prev    next >
C/C++ Source or Header  |  1991-02-06  |  12KB  |  407 lines

  1. /*                   Search.c                   */
  2. /*The routines in this module handle the search/replace functions of 'Liner*/
  3.  
  4. #include "Globals.h"
  5. #include "SearchWdws.h"
  6.  
  7. #define MAYBE 2
  8. #define NONONO 3
  9.  
  10. extern void ModSearchWdw();
  11.  
  12. struct SearchParameters
  13. {
  14.    char Search[80],Replace[80];
  15.    BYTE rep,cse,partial;
  16. };
  17.  
  18. struct SearchParameters parameters =
  19. {
  20.    "","",FALSE,FALSE,TRUE
  21. };
  22.  
  23. struct Window *SearchWdw,*ReplAllWdw;
  24. char *SearchStr,*ReplaceStr;
  25. struct Gadget *SearchFor,*ReplaceWith;
  26.  
  27. GetSRParameters()/*Opens a window to get the parameters for Search/Replace*/
  28. {
  29.    int status;
  30.    struct Gadget junkgad;
  31.    struct Gadget *SearchGadgets,*Cur,*Temp;
  32.    struct StringInfo *si;
  33.    ULONG add;
  34.  
  35.    NewSearchWindow.Screen=(struct Screen *)Screen;
  36.  
  37.       /*Get the difference between the screen font point size and the*/
  38.       /*Topaz point size (8).  Used to properly position the screen*/
  39.       /*stuff when a different default font is being used*/
  40.    add=Screen->Font->ta_YSize-Topaz.ta_YSize;
  41.  
  42.    Temp=Cur=(struct Gadget *)MakeButtonGadgets(&junkgad,SearchButtons,VisInfo,
  43.       &Topaz,SEARCHBUTTONS,add);
  44.  
  45.    Cur=(struct Gadget *)MakeStringGadgets(Cur,SearchStrings,VisInfo,&Topaz,
  46.        SEARCHSTRINGS,StringData,add);
  47.  
  48.    /*Get buffers for Search/Replace*/
  49.    si=(SearchFor=(struct Gadget *)Temp->NextGadget)->SpecialInfo;
  50.    SearchStr=si->Buffer;
  51.  
  52.    si=(ReplaceWith=(struct Gadget *)Temp->NextGadget->NextGadget)
  53.      ->SpecialInfo;
  54.    ReplaceStr=si->Buffer;
  55.  
  56.    strcpy(SearchStr,parameters.Search);
  57.    strcpy(ReplaceStr,parameters.Replace);
  58.  
  59.    Cur=(struct Gadget *)MakeCheckGadgets(Cur,SearchCheck,VisInfo,&Topaz,
  60.        SEARCHCHECK,CheckStates,add);
  61.  
  62.    NewSearchWindow.FirstGadget=SearchGadgets=
  63.      junkgad.NextGadget;
  64.  
  65.       /*If a non-topaz screen font is in use, increase the window height*/
  66.       /*accordingly (to make room for the extra space the title bar will*/
  67.       /*take up*/
  68.    NewSearchWindow.Height+=add;
  69.  
  70.    SearchWdw=(struct Window *)OpenWindow(&NewSearchWindow);
  71.    if(SearchWdw==NULL)
  72.    {
  73.       Leave(0,"Can't open the search/replace window!");
  74.       return(FALSE);
  75.    }
  76.  
  77.       /*Draw a bevel (raised 3D) box around OK, CANCEL, WAIT*/
  78.    DrawBevelBoxA(SearchWdw->RPort,9,13+add,193,65,&beveltag[0]);
  79.  
  80.       /*Around Case sensitive, etc...*/
  81.    DrawBevelBoxA(SearchWdw->RPort,28,81+add,155,42,&beveltag[0]);
  82.  
  83.       /*And around the text gadgets*/
  84.    DrawBevelBoxA(SearchWdw->RPort,9,126+add,193,17,&beveltag[0]);
  85.  
  86.    NewSearchWindow.Height-=add; /*Return the height to its original value*/
  87.  
  88.    ActivateGadget(SearchFor,SearchWdw,NULL);
  89.      /*Activate the Search for... text gadget*/
  90.  
  91.    while((status=MonitorButtons())==NONONO); /*Let user enter info*/
  92.  
  93.    if(status) /*Copy users's choices into parameters structure*/
  94.    {          /*And store them for future use in Search gadgets*/
  95.       strcpy(parameters.Search,SearchStr);
  96.       strcpy(parameters.Replace,ReplaceStr);
  97.       CheckStates[0]=!parameters.partial;
  98.       CheckStates[1]=parameters.cse;
  99.       CheckStates[2]=parameters.rep;
  100.       if(status==MAYBE)   /*If Wait, then change to Cancel*/
  101.      status=FALSE;
  102.    }
  103.    else /*Pressed cancel, so restore gadgets*/
  104.    {
  105.       strcpy(SearchStr,parameters.Search);
  106.       strcpy(ReplaceStr,parameters.Replace);
  107.       parameters.rep=CheckStates[2];
  108.       parameters.cse=CheckStates[1];
  109.       parameters.partial=!CheckStates[0];
  110.    }
  111.  
  112.    CloseWindow(SearchWdw);
  113.    FreeGadgets(SearchGadgets);
  114.    return(status);
  115. }
  116.  
  117. MonitorButtons() /*Monitor the IDCMP port*/
  118. {
  119.    ULONG Class;
  120.    struct Gadget *gadg;
  121.    struct IntuiMessage *mesg;
  122.  
  123.    for(;;)
  124.    {
  125.       Wait(1<<SearchWdw->UserPort->mp_SigBit);
  126.       while((mesg=(struct IntuiMessage *)GetMsg(SearchWdw->UserPort))!=NULL)
  127.       {
  128.      Class=mesg->Class;   /*Get the information*/
  129.      gadg=mesg->IAddress;
  130.      ReplyMsg(mesg);      /*Reply to the message*/
  131.  
  132.      switch(Class)
  133.      {
  134.         case CLOSEWINDOW: /*Close gadget == CANCEL*/
  135.            return(FALSE);
  136.         case GADGETUP:
  137.            switch(gadg->GadgetID)
  138.            {
  139.           case 8:  /*Cancel*/
  140.              return(FALSE);
  141.           case 7:  /*Wait*/
  142.              return(MAYBE);
  143.           case 6:  /*OK*/
  144.              return(TRUE);
  145.           case 5:  /*Replace*/
  146.              parameters.rep=!parameters.rep;
  147.              return(NONONO);
  148.           case 4:
  149.              parameters.partial=!parameters.partial;
  150.              return(NONONO);
  151.           case 3:
  152.              parameters.cse=!parameters.cse;
  153.           case 2:
  154.              return(NONONO);
  155.           case 1:
  156.              ActivateGadget(ReplaceWith,SearchWdw,NULL);
  157.             /*Activate the Replace with... string gadget when*/
  158.             /*the user presses RETURN in the Search for...*/
  159.             /*gadget*/
  160.              return(NONONO); /*Don't alter a flag :-) */
  161.            }
  162.      }
  163.       }
  164.    }
  165. }
  166.  
  167.  
  168. extern struct LineItem *SearchText(Item,Pos,string,scase,partial)
  169.       /*Search an outline for a particular string of characters*/
  170. struct LineItem *Item; /*Item to start searching on*/
  171. USHORT *Pos;           /*Position in that item to start on*/
  172. char *string;           /*Search string*/
  173. BYTE scase,partial;    /*scase    - TRUE if case matters, FALSE otherwise*/
  174.                /*partial-TRUE if it may be a part of a word*/
  175. {
  176.    int c,found,start,thestart;
  177.    struct LineItem *cur,*theitem;
  178.    BYTE status=FALSE;
  179.    char chr,fchr;
  180.  
  181.    if(!scase) /*If case sensitive, convert the string to all uppercase*/
  182.       for(c=0;c<strlen(string);c++)
  183.      string[c]=toupper(string[c]);
  184.  
  185.    if(*Pos >= strlen(Item->Text)) /*If at the end of the line*/
  186.    {
  187.       start=0;    /*Start of next line*/
  188.       Item=(struct LineItem *)Item->NextItem;
  189.    }
  190.    else
  191.       start=*Pos;  /*Else, start at cursor position*/
  192.  
  193.    for(cur=(struct LineItem *)Item;cur != NULL && !status;/*Search until end*/
  194.      cur=(struct LineItem *)cur->NextItem) /*or text is found*/
  195.       for(c=start;c<strlen(cur->Text) && !status ;++c)
  196.       {        /*Loop that searches each line:    */
  197.      start=0;
  198.  
  199.      if((partial) || ( (!partial) && ((c==0) || (cur->Text[c-1]==' ') )))
  200.            /*If partial words are OK, or if not, if the character*/
  201.            /*currently being checked is the first letter in a word*/
  202.      {
  203.         if(!scase)  /*If case is important*/
  204.            chr=toupper(cur->Text[c]); /*Switch to uppercase (see above)*/
  205.         else
  206.            chr=cur->Text[c];
  207.  
  208.         if(string[0]==chr) /*If first character matches...*/
  209.         {
  210.            status=TRUE;
  211.            theitem=(struct LineItem *)cur;
  212.            thestart=c;
  213.            for(found=1;found<strlen(string) && status ;found++)
  214.            {     /*see if the rest matches...*/
  215.           if(!scase)
  216.              fchr=toupper(cur->Text[c+found]);
  217.           else
  218.              fchr=cur->Text[c+found];
  219.  
  220.           if(fchr!=string[found])
  221.              status=FALSE;
  222.            }            /*If the word is a prefix of another word*/
  223.            if(cur->Text[c+found] != ' ' && cur->Text[c+found]!= NULL &&
  224.             !partial)
  225.           status = FALSE;      /*return FALSE*/
  226.         }
  227.      }
  228.       }
  229.    if(status) /*If found...*/
  230.    {
  231.       *Pos=thestart;    /*Return the position of the start of the text*/
  232.       return(theitem);  /*And the item that it is found in*/
  233.    }            /*(so that the cursor can be moved accordingly)*/
  234.    else
  235.       return(NULL);     /*Otherwise, nothing*/
  236. }
  237.  
  238. DoSearch(again,arexx)  /*Main entry point for 'Search/Replace' and 'Next'*/
  239. BYTE again,arexx;      /*Again:  TRUE if 'Next', FALSE if 'Search/Replace'*/
  240. {
  241.    char Buffer[8],reslt[160],preservation[80];
  242.    int status;
  243.    UBYTE TempY;
  244.    struct LineItem *tempitem,*result;
  245.    struct LineItem *firstitem=(struct LineItem *)CurrentItem;
  246.  
  247.    USHORT Pos=(again && again != 100) ? CurX-MinX(CurrentItem)+1 :
  248.       CurX-MinX(CurrentItem);
  249.  
  250.  
  251.    status = (again) ? TRUE : GetSRParameters();
  252.      /*If 'Next', search no matter what.  Otherwise, depends on user*/
  253.    CancelInvs();  /*Cancel text highlighting*/
  254.    if(ErrorInTitle)     /*Cancel any errors in the title bar*/
  255.       TitleErrorCancel();
  256.  
  257.  
  258.    if(status)     /*If it's OK to search*/
  259.    {
  260.       strcpy(preservation,parameters.Search);   /*Store the search string*/
  261.         /*so if SearchText turns it to all caps, we'll still have the*/
  262.         /*original*/
  263.  
  264.       result=(struct LineItem *) /*Search the text*/
  265.         SearchText(CurrentItem,&Pos,parameters.Search,parameters.cse,
  266.         parameters.partial);
  267.  
  268.       if(result!=NULL)  /*If found...*/
  269.       {
  270.      /*Place the cursor at the start of the word*/
  271.      if(result!=FirstScrnItem || result!=firstitem)
  272.      {
  273.         FirstScrnItem=CurrentItem=(struct LineItem *)result;
  274.         PrintItemList(CurrentItem,1);
  275.      }
  276.      PlotCursor(MinX(CurrentItem)+Pos,1);
  277.      if(parameters.rep) /*If a search and replace*/
  278.      {            /*Replace!!!!*/
  279.         strcpy(reslt,&(CurrentItem->Text[Pos+strlen(parameters.Search)]));
  280.         strins(reslt,parameters.Replace);
  281.         CurrentItem->Text[Pos]=NULL;
  282.         strins(reslt,CurrentItem->Text);
  283.  
  284.            /*Break the line apart if necessary*/
  285.         tempitem=(struct LineItem *)BreakLineApart(CurrentItem,
  286.           CurrentItem->NextItem,reslt);
  287.  
  288.         PlotCursor(1,CurY);
  289.         Buffer[0]=CSI;
  290.         Buffer[1]=0x4b;
  291.         WriteConsole(Buffer,2);
  292.         TempY=CurY;
  293.         if(tempitem==CurrentItem)
  294.            PrintItem(CurrentItem);
  295.         else
  296.            PrintItemList(CurrentItem,CurY);
  297.         PlotCursor(MinX(CurrentItem)+Pos,TempY);
  298.         CheckModified();  /*Text has been modified*/
  299.      }
  300.      strcpy(parameters.Search,preservation);
  301.      return(TRUE);
  302.       }
  303.       else  /*If it wasn't found*/
  304.       {
  305.      strcpy(parameters.Search,preservation);
  306.      if(!arexx)  /*If this wasn't an ARexx command*/
  307.         TitleError("Wasn't found!!!");
  308.      return(FALSE);
  309.       }
  310.    }
  311. }
  312.  
  313. void ModifyParams(search,replace,case_s,partial,s_repl)
  314. char *search,*replace;
  315. BYTE case_s,partial,s_repl;
  316. {
  317.    if(search[0]!=NULL)
  318.       strcpy(parameters.Search,search);
  319.    if(replace[0]!=NULL)
  320.       strcpy(parameters.Replace,replace);
  321.    if(case_s!=100)
  322.       parameters.cse=case_s;
  323.    if(partial!=100)
  324.       parameters.partial=partial;
  325.    if(s_repl!=100)
  326.       parameters.rep=s_repl;
  327. }
  328.  
  329. void ReplaceAll(verify) /*Search/replace entire document at once*/
  330. BYTE verify;
  331. {
  332.    BYTE stat;
  333.  
  334.    if(verify)
  335.    {
  336.       ModifyParams("","",100,100,FALSE);
  337.       while(DoSearch(TRUE,TRUE)) /*Search for text*/
  338.       {
  339.      if(stat=AskChange()) /*Ask user what to do*/
  340.      {
  341.         if(stat==TRUE) /*Replace*/
  342.         {
  343.            ModifyParams("","",100,100,TRUE);
  344.            DoSearch(100,TRUE);
  345.            ModifyParams("","",100,100,FALSE);
  346.         } /*Else goto next*/
  347.      }
  348.      else
  349.         return;  /*Else cancel*/
  350.       }
  351.       TitleError("No more found");
  352.    }
  353.    else   /*Do all without verification*/
  354.    {
  355.       ModifyParams("","",100,100,TRUE);
  356.       while(DoSearch(TRUE,TRUE));
  357.    }
  358. }
  359.  
  360. BYTE AskChange() /*Ask user if he wants to do replace*/
  361. {
  362.    struct Window *ReplAllWdw;
  363.    struct IntuiMessage *mesg;
  364.    struct Gadget junkgad,*gadg;
  365.    BYTE ID;
  366.  
  367.    MakeButtonGadgets(&junkgad,VerifyButtons,VisInfo,&Topaz,VERIFYBUTTONS,0);
  368.  
  369.       /*Position the window so that it's right under the text, no matter*/
  370.       /*what the point size*/
  371.    NewWindowStructure2.TopEdge=3+2*Screen->Font->ta_YSize;
  372.    NewWindowStructure2.FirstGadget=(struct Gadget *)junkgad.NextGadget;
  373.  
  374.    NewWindowStructure2.Screen=(struct Screen *)Screen; /*'Liner screen*/
  375.    if((ReplAllWdw=(struct Window *)OpenWindow(&NewWindowStructure2))==NULL)
  376.       return(FALSE); /*Open the window*/
  377.  
  378.    PrintIText(ReplAllWdw->RPort,&IntuiTextList2,5,1);
  379.    Wait(1<<ReplAllWdw->UserPort->mp_SigBit); /*Wait for gadget press*/
  380.  
  381.    if((mesg=(struct IntuiMessage *)GetMsg(ReplAllWdw->UserPort))==NULL)
  382.    {
  383.       CloseWindow(ReplAllWdw);
  384.       FreeGadgets(junkgad.NextGadget);
  385.       return(FALSE); /*Get the message*/
  386.    }
  387.  
  388.    gadg=(struct Gadget *)mesg->IAddress;/*Get the gadget structure's addr*/
  389.  
  390.    ReplyMsg(mesg); /*Reply to it*/
  391.  
  392.    ID=gadg->GadgetID;
  393.    CloseWindow(ReplAllWdw); /*Close the window*/
  394.    FreeGadgets(junkgad.NextGadget);
  395.    return(ID); /*Return the gadget ID*/
  396. }
  397.  
  398. void ModSearchWdw()
  399. {
  400.    CheckStates[0]=!parameters.partial;
  401.    CheckStates[1]=parameters.cse;
  402.    CheckStates[2]=parameters.rep;
  403. }
  404.  
  405.  
  406. /*~~~End of Search.c*/
  407.