home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
text
/
editors
/
'liner_451
/
source
/
search.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-06
|
12KB
|
407 lines
/* Search.c */
/*The routines in this module handle the search/replace functions of 'Liner*/
#include "Globals.h"
#include "SearchWdws.h"
#define MAYBE 2
#define NONONO 3
extern void ModSearchWdw();
struct SearchParameters
{
char Search[80],Replace[80];
BYTE rep,cse,partial;
};
struct SearchParameters parameters =
{
"","",FALSE,FALSE,TRUE
};
struct Window *SearchWdw,*ReplAllWdw;
char *SearchStr,*ReplaceStr;
struct Gadget *SearchFor,*ReplaceWith;
GetSRParameters()/*Opens a window to get the parameters for Search/Replace*/
{
int status;
struct Gadget junkgad;
struct Gadget *SearchGadgets,*Cur,*Temp;
struct StringInfo *si;
ULONG add;
NewSearchWindow.Screen=(struct Screen *)Screen;
/*Get the difference between the screen font point size and the*/
/*Topaz point size (8). Used to properly position the screen*/
/*stuff when a different default font is being used*/
add=Screen->Font->ta_YSize-Topaz.ta_YSize;
Temp=Cur=(struct Gadget *)MakeButtonGadgets(&junkgad,SearchButtons,VisInfo,
&Topaz,SEARCHBUTTONS,add);
Cur=(struct Gadget *)MakeStringGadgets(Cur,SearchStrings,VisInfo,&Topaz,
SEARCHSTRINGS,StringData,add);
/*Get buffers for Search/Replace*/
si=(SearchFor=(struct Gadget *)Temp->NextGadget)->SpecialInfo;
SearchStr=si->Buffer;
si=(ReplaceWith=(struct Gadget *)Temp->NextGadget->NextGadget)
->SpecialInfo;
ReplaceStr=si->Buffer;
strcpy(SearchStr,parameters.Search);
strcpy(ReplaceStr,parameters.Replace);
Cur=(struct Gadget *)MakeCheckGadgets(Cur,SearchCheck,VisInfo,&Topaz,
SEARCHCHECK,CheckStates,add);
NewSearchWindow.FirstGadget=SearchGadgets=
junkgad.NextGadget;
/*If a non-topaz screen font is in use, increase the window height*/
/*accordingly (to make room for the extra space the title bar will*/
/*take up*/
NewSearchWindow.Height+=add;
SearchWdw=(struct Window *)OpenWindow(&NewSearchWindow);
if(SearchWdw==NULL)
{
Leave(0,"Can't open the search/replace window!");
return(FALSE);
}
/*Draw a bevel (raised 3D) box around OK, CANCEL, WAIT*/
DrawBevelBoxA(SearchWdw->RPort,9,13+add,193,65,&beveltag[0]);
/*Around Case sensitive, etc...*/
DrawBevelBoxA(SearchWdw->RPort,28,81+add,155,42,&beveltag[0]);
/*And around the text gadgets*/
DrawBevelBoxA(SearchWdw->RPort,9,126+add,193,17,&beveltag[0]);
NewSearchWindow.Height-=add; /*Return the height to its original value*/
ActivateGadget(SearchFor,SearchWdw,NULL);
/*Activate the Search for... text gadget*/
while((status=MonitorButtons())==NONONO); /*Let user enter info*/
if(status) /*Copy users's choices into parameters structure*/
{ /*And store them for future use in Search gadgets*/
strcpy(parameters.Search,SearchStr);
strcpy(parameters.Replace,ReplaceStr);
CheckStates[0]=!parameters.partial;
CheckStates[1]=parameters.cse;
CheckStates[2]=parameters.rep;
if(status==MAYBE) /*If Wait, then change to Cancel*/
status=FALSE;
}
else /*Pressed cancel, so restore gadgets*/
{
strcpy(SearchStr,parameters.Search);
strcpy(ReplaceStr,parameters.Replace);
parameters.rep=CheckStates[2];
parameters.cse=CheckStates[1];
parameters.partial=!CheckStates[0];
}
CloseWindow(SearchWdw);
FreeGadgets(SearchGadgets);
return(status);
}
MonitorButtons() /*Monitor the IDCMP port*/
{
ULONG Class;
struct Gadget *gadg;
struct IntuiMessage *mesg;
for(;;)
{
Wait(1<<SearchWdw->UserPort->mp_SigBit);
while((mesg=(struct IntuiMessage *)GetMsg(SearchWdw->UserPort))!=NULL)
{
Class=mesg->Class; /*Get the information*/
gadg=mesg->IAddress;
ReplyMsg(mesg); /*Reply to the message*/
switch(Class)
{
case CLOSEWINDOW: /*Close gadget == CANCEL*/
return(FALSE);
case GADGETUP:
switch(gadg->GadgetID)
{
case 8: /*Cancel*/
return(FALSE);
case 7: /*Wait*/
return(MAYBE);
case 6: /*OK*/
return(TRUE);
case 5: /*Replace*/
parameters.rep=!parameters.rep;
return(NONONO);
case 4:
parameters.partial=!parameters.partial;
return(NONONO);
case 3:
parameters.cse=!parameters.cse;
case 2:
return(NONONO);
case 1:
ActivateGadget(ReplaceWith,SearchWdw,NULL);
/*Activate the Replace with... string gadget when*/
/*the user presses RETURN in the Search for...*/
/*gadget*/
return(NONONO); /*Don't alter a flag :-) */
}
}
}
}
}
extern struct LineItem *SearchText(Item,Pos,string,scase,partial)
/*Search an outline for a particular string of characters*/
struct LineItem *Item; /*Item to start searching on*/
USHORT *Pos; /*Position in that item to start on*/
char *string; /*Search string*/
BYTE scase,partial; /*scase - TRUE if case matters, FALSE otherwise*/
/*partial-TRUE if it may be a part of a word*/
{
int c,found,start,thestart;
struct LineItem *cur,*theitem;
BYTE status=FALSE;
char chr,fchr;
if(!scase) /*If case sensitive, convert the string to all uppercase*/
for(c=0;c<strlen(string);c++)
string[c]=toupper(string[c]);
if(*Pos >= strlen(Item->Text)) /*If at the end of the line*/
{
start=0; /*Start of next line*/
Item=(struct LineItem *)Item->NextItem;
}
else
start=*Pos; /*Else, start at cursor position*/
for(cur=(struct LineItem *)Item;cur != NULL && !status;/*Search until end*/
cur=(struct LineItem *)cur->NextItem) /*or text is found*/
for(c=start;c<strlen(cur->Text) && !status ;++c)
{ /*Loop that searches each line: */
start=0;
if((partial) || ( (!partial) && ((c==0) || (cur->Text[c-1]==' ') )))
/*If partial words are OK, or if not, if the character*/
/*currently being checked is the first letter in a word*/
{
if(!scase) /*If case is important*/
chr=toupper(cur->Text[c]); /*Switch to uppercase (see above)*/
else
chr=cur->Text[c];
if(string[0]==chr) /*If first character matches...*/
{
status=TRUE;
theitem=(struct LineItem *)cur;
thestart=c;
for(found=1;found<strlen(string) && status ;found++)
{ /*see if the rest matches...*/
if(!scase)
fchr=toupper(cur->Text[c+found]);
else
fchr=cur->Text[c+found];
if(fchr!=string[found])
status=FALSE;
} /*If the word is a prefix of another word*/
if(cur->Text[c+found] != ' ' && cur->Text[c+found]!= NULL &&
!partial)
status = FALSE; /*return FALSE*/
}
}
}
if(status) /*If found...*/
{
*Pos=thestart; /*Return the position of the start of the text*/
return(theitem); /*And the item that it is found in*/
} /*(so that the cursor can be moved accordingly)*/
else
return(NULL); /*Otherwise, nothing*/
}
DoSearch(again,arexx) /*Main entry point for 'Search/Replace' and 'Next'*/
BYTE again,arexx; /*Again: TRUE if 'Next', FALSE if 'Search/Replace'*/
{
char Buffer[8],reslt[160],preservation[80];
int status;
UBYTE TempY;
struct LineItem *tempitem,*result;
struct LineItem *firstitem=(struct LineItem *)CurrentItem;
USHORT Pos=(again && again != 100) ? CurX-MinX(CurrentItem)+1 :
CurX-MinX(CurrentItem);
status = (again) ? TRUE : GetSRParameters();
/*If 'Next', search no matter what. Otherwise, depends on user*/
CancelInvs(); /*Cancel text highlighting*/
if(ErrorInTitle) /*Cancel any errors in the title bar*/
TitleErrorCancel();
if(status) /*If it's OK to search*/
{
strcpy(preservation,parameters.Search); /*Store the search string*/
/*so if SearchText turns it to all caps, we'll still have the*/
/*original*/
result=(struct LineItem *) /*Search the text*/
SearchText(CurrentItem,&Pos,parameters.Search,parameters.cse,
parameters.partial);
if(result!=NULL) /*If found...*/
{
/*Place the cursor at the start of the word*/
if(result!=FirstScrnItem || result!=firstitem)
{
FirstScrnItem=CurrentItem=(struct LineItem *)result;
PrintItemList(CurrentItem,1);
}
PlotCursor(MinX(CurrentItem)+Pos,1);
if(parameters.rep) /*If a search and replace*/
{ /*Replace!!!!*/
strcpy(reslt,&(CurrentItem->Text[Pos+strlen(parameters.Search)]));
strins(reslt,parameters.Replace);
CurrentItem->Text[Pos]=NULL;
strins(reslt,CurrentItem->Text);
/*Break the line apart if necessary*/
tempitem=(struct LineItem *)BreakLineApart(CurrentItem,
CurrentItem->NextItem,reslt);
PlotCursor(1,CurY);
Buffer[0]=CSI;
Buffer[1]=0x4b;
WriteConsole(Buffer,2);
TempY=CurY;
if(tempitem==CurrentItem)
PrintItem(CurrentItem);
else
PrintItemList(CurrentItem,CurY);
PlotCursor(MinX(CurrentItem)+Pos,TempY);
CheckModified(); /*Text has been modified*/
}
strcpy(parameters.Search,preservation);
return(TRUE);
}
else /*If it wasn't found*/
{
strcpy(parameters.Search,preservation);
if(!arexx) /*If this wasn't an ARexx command*/
TitleError("Wasn't found!!!");
return(FALSE);
}
}
}
void ModifyParams(search,replace,case_s,partial,s_repl)
char *search,*replace;
BYTE case_s,partial,s_repl;
{
if(search[0]!=NULL)
strcpy(parameters.Search,search);
if(replace[0]!=NULL)
strcpy(parameters.Replace,replace);
if(case_s!=100)
parameters.cse=case_s;
if(partial!=100)
parameters.partial=partial;
if(s_repl!=100)
parameters.rep=s_repl;
}
void ReplaceAll(verify) /*Search/replace entire document at once*/
BYTE verify;
{
BYTE stat;
if(verify)
{
ModifyParams("","",100,100,FALSE);
while(DoSearch(TRUE,TRUE)) /*Search for text*/
{
if(stat=AskChange()) /*Ask user what to do*/
{
if(stat==TRUE) /*Replace*/
{
ModifyParams("","",100,100,TRUE);
DoSearch(100,TRUE);
ModifyParams("","",100,100,FALSE);
} /*Else goto next*/
}
else
return; /*Else cancel*/
}
TitleError("No more found");
}
else /*Do all without verification*/
{
ModifyParams("","",100,100,TRUE);
while(DoSearch(TRUE,TRUE));
}
}
BYTE AskChange() /*Ask user if he wants to do replace*/
{
struct Window *ReplAllWdw;
struct IntuiMessage *mesg;
struct Gadget junkgad,*gadg;
BYTE ID;
MakeButtonGadgets(&junkgad,VerifyButtons,VisInfo,&Topaz,VERIFYBUTTONS,0);
/*Position the window so that it's right under the text, no matter*/
/*what the point size*/
NewWindowStructure2.TopEdge=3+2*Screen->Font->ta_YSize;
NewWindowStructure2.FirstGadget=(struct Gadget *)junkgad.NextGadget;
NewWindowStructure2.Screen=(struct Screen *)Screen; /*'Liner screen*/
if((ReplAllWdw=(struct Window *)OpenWindow(&NewWindowStructure2))==NULL)
return(FALSE); /*Open the window*/
PrintIText(ReplAllWdw->RPort,&IntuiTextList2,5,1);
Wait(1<<ReplAllWdw->UserPort->mp_SigBit); /*Wait for gadget press*/
if((mesg=(struct IntuiMessage *)GetMsg(ReplAllWdw->UserPort))==NULL)
{
CloseWindow(ReplAllWdw);
FreeGadgets(junkgad.NextGadget);
return(FALSE); /*Get the message*/
}
gadg=(struct Gadget *)mesg->IAddress;/*Get the gadget structure's addr*/
ReplyMsg(mesg); /*Reply to it*/
ID=gadg->GadgetID;
CloseWindow(ReplAllWdw); /*Close the window*/
FreeGadgets(junkgad.NextGadget);
return(ID); /*Return the gadget ID*/
}
void ModSearchWdw()
{
CheckStates[0]=!parameters.partial;
CheckStates[1]=parameters.cse;
CheckStates[2]=parameters.rep;
}
/*~~~End of Search.c*/