reactos/rosapps/dflat32/search.c
2005-09-16 18:00:49 +00:00

165 lines
5.3 KiB
C

/* ---------------- search.c ------------- */
#include "dflat.h"
extern DF_DBOX SearchTextDB;
extern DF_DBOX ReplaceTextDB;
static int CheckCase = TRUE;
static int Replacing = FALSE;
/* - case-insensitive, white-space-normalized char compare - */
static BOOL SearchCmp(int a, int b)
{
if (b == '\n')
b = ' ';
if (CheckCase)
return a != b;
return tolower(a) != tolower(b);
}
/* ----- replace a matching block of text ----- */
static void replacetext(DFWINDOW wnd, char *cp1, DF_DBOX *db)
{
char *cr = DfGetEditBoxText(db, DF_ID_REPLACEWITH);
char *cp = DfGetEditBoxText(db, DF_ID_SEARCHFOR);
int oldlen = strlen(cp); /* length of text being replaced */
int newlen = strlen(cr); /* length of replacing text */
int dif;
if (oldlen < newlen) {
/* ---- new text expands text size ---- */
dif = newlen-oldlen;
if (wnd->textlen < strlen(wnd->text)+dif) {
/* ---- need to reallocate the text buffer ---- */
int offset = (int)((int)cp1-(int)wnd->text);
wnd->textlen += dif;
wnd->text = DfRealloc(wnd->text, wnd->textlen+2);
cp1 = wnd->text + offset;
}
memmove(cp1+dif, cp1, strlen(cp1)+1);
}
else if (oldlen > newlen) {
/* ---- new text collapses text size ---- */
dif = oldlen-newlen;
memmove(cp1, cp1+dif, strlen(cp1)+1);
}
strncpy(cp1, cr, newlen);
}
/* ------- search for the occurrance of a string ------- */
static void SearchTextBox(DFWINDOW wnd, int incr)
{
char *s1 , *s2, *cp1;
s1 = s2 = cp1 = NULL;
DF_DBOX *db = Replacing ? &ReplaceTextDB : &SearchTextDB;
char *cp = DfGetEditBoxText(db, DF_ID_SEARCHFOR);
BOOL rpl = TRUE, FoundOne = FALSE;
while (rpl == TRUE && cp != NULL && *cp) {
rpl = Replacing ?
DfCheckBoxSetting(&ReplaceTextDB, DF_ID_REPLACEALL) :
FALSE;
if (DfTextBlockMarked(wnd)) {
DfClearTextBlock(wnd);
DfSendMessage(wnd, DFM_PAINT, 0, 0);
}
/* search for a match starting at DfCursor position */
cp1 = DfCurrChar;
if (incr)
cp1++; /* start past the last hit */
/* --- compare at each character position --- */
while (*cp1) {
s1 = cp;
s2 = cp1;
while (*s1 && *s1 != '\n') {
if (SearchCmp(*s1, *s2))
break;
s1++, s2++;
}
if (*s1 == '\0' || *s1 == '\n')
break;
cp1++;
}
if (s1 != NULL && (*s1 == 0 || *s1 == '\n')) {
/* ----- match at *cp1 ------- */
FoundOne = TRUE;
/* mark a block at beginning of matching text */
wnd->BlkEndLine = DfTextLineNumber(wnd, s2);
wnd->BlkBegLine = DfTextLineNumber(wnd, cp1);
if (wnd->BlkEndLine < wnd->BlkBegLine)
wnd->BlkEndLine = wnd->BlkBegLine;
wnd->BlkEndCol =
(int)((int)s2 - (int)DfTextLine(wnd, wnd->BlkEndLine));
wnd->BlkBegCol =
(int)((int)cp1 - (int)DfTextLine(wnd, wnd->BlkBegLine));
/* position the DfCursor at the matching text */
wnd->CurrCol = wnd->BlkBegCol;
wnd->CurrLine = wnd->BlkBegLine;
wnd->WndRow = wnd->CurrLine - wnd->wtop;
/* align the window scroll to matching text */
if (DfWndCol > DfClientWidth(wnd)-1)
wnd->wleft = wnd->CurrCol;
if (wnd->WndRow > DfClientHeight(wnd)-1) {
wnd->wtop = wnd->CurrLine;
wnd->WndRow = 0;
}
DfSendMessage(wnd, DFM_PAINT, 0, 0);
DfSendMessage(wnd, DFM_KEYBOARD_CURSOR,
DfWndCol, wnd->WndRow);
if (Replacing) {
if (rpl || DfYesNoBox("Replace the text?")) {
replacetext(wnd, cp1, db);
wnd->TextChanged = TRUE;
DfBuildTextPointers(wnd);
}
if (rpl) {
incr = TRUE;
continue;
}
DfClearTextBlock(wnd);
DfSendMessage(wnd, DFM_PAINT, 0, 0);
}
return;
}
break;
}
if (!FoundOne)
DfMessageBox("Search/Replace Text", "No match found");
}
/* ------- search for the occurrance of a string,
replace it with a specified string ------- */
void DfReplaceText(DFWINDOW wnd)
{
Replacing = TRUE;
if (CheckCase)
DfSetCheckBox(&ReplaceTextDB, DF_ID_MATCHCASE);
if (DfDialogBox(NULL, &ReplaceTextDB, TRUE, NULL)) {
CheckCase=DfCheckBoxSetting(&ReplaceTextDB,DF_ID_MATCHCASE);
SearchTextBox(wnd, FALSE);
}
}
/* ------- search for the first occurrance of a string ------ */
void DfSearchText(DFWINDOW wnd)
{
Replacing = FALSE;
if (CheckCase)
DfSetCheckBox(&SearchTextDB, DF_ID_MATCHCASE);
if (DfDialogBox(NULL, &SearchTextDB, TRUE, NULL)) {
CheckCase=DfCheckBoxSetting(&SearchTextDB,DF_ID_MATCHCASE);
SearchTextBox(wnd, FALSE);
}
}
/* ------- search for the next occurrance of a string ------- */
void DfSearchNext(DFWINDOW wnd)
{
SearchTextBox(wnd, TRUE);
}
/* EOF */