mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
5.7 KiB
240 lines
5.7 KiB
/*
|
|
Enhanced NCSA Mosaic from Spyglass
|
|
"Guitar"
|
|
|
|
Copyright 1994 Spyglass, Inc.
|
|
All Rights Reserved
|
|
|
|
Author(s):
|
|
Jim Seidman [email protected]
|
|
*/
|
|
|
|
/* GUITFIND.C - Code to find text string in a WWW document.
|
|
Author: Jim Seidman 6/94
|
|
*/
|
|
|
|
#include "all.h"
|
|
|
|
/* Increment the position, and return TRUE if we are still in the same block of text. */
|
|
static BOOL x_IncrementPosition(struct _www *pdoc, struct _position *ppos)
|
|
{
|
|
BOOL bResult = TRUE;
|
|
int i;
|
|
|
|
#ifdef FEATURE_INTL
|
|
if(IsFECodePage(GETMIMECP(pdoc)) && IsDBCSLeadByteEx(GETMIMECP(pdoc), pdoc->pool[pdoc->aElements[ppos->elementIndex].textOffset + ppos->offset]))
|
|
ppos->offset += 2;
|
|
else
|
|
#endif
|
|
ppos->offset++;
|
|
|
|
if (ppos->offset >= pdoc->aElements[ppos->elementIndex].textLen)
|
|
{
|
|
ppos->offset = 0;
|
|
for (i = pdoc->aElements[ppos->elementIndex].next; i >= 0; i = pdoc->aElements[i].next)
|
|
{
|
|
if (pdoc->aElements[i].type == ELE_TEXT)
|
|
break;
|
|
}
|
|
|
|
if (i != pdoc->aElements[ppos->elementIndex].next || i == -1)
|
|
bResult = FALSE;
|
|
ppos->elementIndex = i;
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
/* Find a string in the given document starting at the specified location and working down.
|
|
It returns TRUE if successful. */
|
|
static BOOL TW_FindText(struct _www * pdoc, const char *pStr, BOOL bCaseSensitive, const struct _position * pposStart, struct _position * pposResult)
|
|
{
|
|
struct _position posCandidate, posOngoing;
|
|
int nInStr, nStrLen;
|
|
#ifdef FEATURE_INTL
|
|
BOOL fDBCS;
|
|
#endif
|
|
|
|
posCandidate = *pposStart;
|
|
|
|
if (posCandidate.elementIndex == -1)
|
|
{
|
|
int i;
|
|
|
|
/* Find the first text element */
|
|
for (i = 0; i >= 0; i = pdoc->aElements[i].next)
|
|
{
|
|
if (pdoc->aElements[i].type == ELE_TEXT)
|
|
break;
|
|
}
|
|
posCandidate.elementIndex = i;
|
|
posCandidate.offset = 0;
|
|
}
|
|
|
|
nStrLen = strlen(pStr);
|
|
|
|
while (posCandidate.elementIndex != -1)
|
|
{
|
|
posOngoing = posCandidate;
|
|
for (nInStr = 0; nInStr < nStrLen; nInStr++)
|
|
{
|
|
char c1, c2;
|
|
|
|
c1 = pdoc->pool[pdoc->aElements[posOngoing.elementIndex].textOffset + posOngoing.offset];
|
|
c2 = pStr[nInStr];
|
|
#ifdef FEATURE_INTL
|
|
if (IsFECodePage(GETMIMECP(pdoc)))
|
|
fDBCS = IsDBCSLeadByteEx(GETMIMECP(pdoc), c2);
|
|
|
|
else
|
|
fDBCS = FALSE;
|
|
|
|
if(!fDBCS && !bCaseSensitive)
|
|
{
|
|
if (IsFECodePage(GETMIMECP(pdoc)))
|
|
{
|
|
if ((c1 >=0x41 && c1 <= 0x5a) && !IsDBCSLeadByteEx(GETMIMECP(pdoc), c1))
|
|
c1 = tolower(c1);
|
|
if (c2 >=0x41 && c2 <= 0x5a)
|
|
c2 = tolower(c2);
|
|
}
|
|
else
|
|
{
|
|
if (isupper(c1))
|
|
c1 = tolower(c1);
|
|
if (isupper(c2))
|
|
c2 = tolower(c2);
|
|
}
|
|
}
|
|
#else
|
|
if (!bCaseSensitive)
|
|
{
|
|
if (isupper(c1))
|
|
c1 = tolower(c1);
|
|
if (isupper(c2))
|
|
c2 = tolower(c2);
|
|
}
|
|
#endif
|
|
if (c1 == c2)
|
|
{
|
|
#ifdef FEATURE_INTL
|
|
if (fDBCS){
|
|
/* Now, both c1 and c2 are DBCS Primary byte */
|
|
/* check DBCS Secondary byte */
|
|
char c1, c2;
|
|
|
|
c1 = pdoc->pool[pdoc->aElements[posOngoing.elementIndex].textOffset + posOngoing.offset + 1];
|
|
c2 = pStr[++nInStr];
|
|
|
|
if(c1 == c2){
|
|
if ((nInStr != nStrLen - 1) && !x_IncrementPosition(pdoc, &posOngoing)){
|
|
posCandidate = posOngoing;
|
|
break;
|
|
}
|
|
} else {
|
|
x_IncrementPosition(pdoc, &posCandidate);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
if ((nInStr != nStrLen - 1) && !x_IncrementPosition(pdoc, &posOngoing))
|
|
{
|
|
/* We've jumped to a new block of text. We therefore know the old block
|
|
doesn't have a match. */
|
|
posCandidate = posOngoing;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* The character didn't match. */
|
|
x_IncrementPosition(pdoc, &posCandidate);
|
|
break;
|
|
}
|
|
}
|
|
/* Did the for loop find a match? */
|
|
if (nInStr == nStrLen)
|
|
break;
|
|
}
|
|
|
|
*pposResult = posCandidate;
|
|
|
|
return (posCandidate.elementIndex != -1);
|
|
}
|
|
|
|
/* This function really belongs in the same file that does the find dialog, but it's so
|
|
easily sharable I couldn't resist. */
|
|
BOOL TW_dofindagain(struct Mwin * tw)
|
|
{
|
|
struct _position posResult, posStart;
|
|
#ifdef FEATURE_INTL
|
|
BOOL fIndexIsAbove0;
|
|
#endif
|
|
|
|
if (tw->szSearch[0] == '\0')
|
|
{
|
|
#ifdef MAC
|
|
SysBeep(3);
|
|
#endif
|
|
#ifdef WIN32
|
|
MessageBeep(MB_ICONEXCLAMATION);
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
posStart = tw->w3doc->selStart;
|
|
if (posStart.elementIndex != -1)
|
|
x_IncrementPosition(tw->w3doc, &posStart);
|
|
|
|
#ifdef FEATURE_INTL
|
|
if (IsFECodePage(GETMIMECP(tw->w3doc)))
|
|
{
|
|
if (posStart.elementIndex == -1 && !posStart.offset){
|
|
/* now selecting character is last one of this document */
|
|
/* there isn't text below to search */
|
|
return FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (TW_FindText(tw->w3doc, tw->szSearch, tw->bSearchCase, &posStart, &posResult))
|
|
{
|
|
/* Make the search string the selected text */
|
|
tw->w3doc->selStart = posResult;
|
|
/* Find end of selection */
|
|
tw->w3doc->selEnd = posResult;
|
|
tw->w3doc->selEnd.offset += strlen(tw->szSearch);
|
|
|
|
#ifdef FEATURE_INTL
|
|
if (IsFECodePage(GETMIMECP(tw->w3doc)))
|
|
fIndexIsAbove0 = (tw->w3doc->selEnd.elementIndex >= 0);
|
|
else
|
|
fIndexIsAbove0 = TRUE;
|
|
|
|
while (fIndexIsAbove0 && tw->w3doc->selEnd.offset >= tw->w3doc->aElements[tw->w3doc->selEnd.elementIndex].textLen)
|
|
#else
|
|
while (tw->w3doc->selEnd.offset >= tw->w3doc->aElements[tw->w3doc->selEnd.elementIndex].textLen)
|
|
#endif
|
|
{
|
|
/* In this situation we know we're looking at a contiguous block of ELE_TEXT
|
|
elements, so we don't need to check the type or anything. */
|
|
tw->w3doc->selEnd.offset -= tw->w3doc->aElements[tw->w3doc->selEnd.elementIndex].textLen;
|
|
tw->w3doc->selEnd.elementIndex = tw->w3doc->aElements[tw->w3doc->selEnd.elementIndex].next;
|
|
tw->w3doc->bStartIsAnchor = TRUE;
|
|
}
|
|
|
|
/* Now update display */
|
|
TW_ScrollToElement(tw, tw->w3doc->selStart.elementIndex);
|
|
#ifdef MAC
|
|
MENU_UpdateEditMenu(tw);
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* Text wasn't found */
|
|
//ERR_ReportError(tw, errLocalFindFailed, tw->szSearch, NULL);
|
|
return FALSE;
|
|
}
|
|
}
|