1 /* ---------------- search.c ------------- */
4 extern DF_DBOX SearchTextDB
;
5 extern DF_DBOX ReplaceTextDB
;
6 static int CheckCase
= TRUE
;
7 static int Replacing
= FALSE
;
9 /* - case-insensitive, white-space-normalized char compare - */
10 static BOOL
SearchCmp(int a
, int b
)
16 return tolower(a
) != tolower(b
);
19 /* ----- replace a matching block of text ----- */
20 static void replacetext(DFWINDOW wnd
, char *cp1
, DF_DBOX
*db
)
22 char *cr
= DfGetEditBoxText(db
, DF_ID_REPLACEWITH
);
23 char *cp
= DfGetEditBoxText(db
, DF_ID_SEARCHFOR
);
24 int oldlen
= strlen(cp
); /* length of text being replaced */
25 int newlen
= strlen(cr
); /* length of replacing text */
27 if (oldlen
< newlen
) {
28 /* ---- new text expands text size ---- */
30 if (wnd
->textlen
< strlen(wnd
->text
)+dif
) {
31 /* ---- need to reallocate the text buffer ---- */
32 int offset
= (int)((int)cp1
-(int)wnd
->text
);
34 wnd
->text
= DfRealloc(wnd
->text
, wnd
->textlen
+2);
35 cp1
= wnd
->text
+ offset
;
37 memmove(cp1
+dif
, cp1
, strlen(cp1
)+1);
39 else if (oldlen
> newlen
) {
40 /* ---- new text collapses text size ---- */
42 memmove(cp1
, cp1
+dif
, strlen(cp1
)+1);
44 strncpy(cp1
, cr
, newlen
);
47 /* ------- search for the occurrance of a string ------- */
48 static void SearchTextBox(DFWINDOW wnd
, int incr
)
52 DF_DBOX
*db
= Replacing
? &ReplaceTextDB
: &SearchTextDB
;
53 char *cp
= DfGetEditBoxText(db
, DF_ID_SEARCHFOR
);
54 BOOL rpl
= TRUE
, FoundOne
= FALSE
;
56 while (rpl
== TRUE
&& cp
!= NULL
&& *cp
) {
58 DfCheckBoxSetting(&ReplaceTextDB
, DF_ID_REPLACEALL
) :
60 if (DfTextBlockMarked(wnd
)) {
61 DfClearTextBlock(wnd
);
62 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
64 /* search for a match starting at DfCursor position */
67 cp1
++; /* start past the last hit */
68 /* --- compare at each character position --- */
72 while (*s1
&& *s1
!= '\n') {
73 if (SearchCmp(*s1
, *s2
))
77 if (*s1
== '\0' || *s1
== '\n')
81 if (s1
!= NULL
&& (*s1
== 0 || *s1
== '\n')) {
82 /* ----- match at *cp1 ------- */
85 /* mark a block at beginning of matching text */
86 wnd
->BlkEndLine
= DfTextLineNumber(wnd
, s2
);
87 wnd
->BlkBegLine
= DfTextLineNumber(wnd
, cp1
);
88 if (wnd
->BlkEndLine
< wnd
->BlkBegLine
)
89 wnd
->BlkEndLine
= wnd
->BlkBegLine
;
91 (int)((int)s2
- (int)DfTextLine(wnd
, wnd
->BlkEndLine
));
93 (int)((int)cp1
- (int)DfTextLine(wnd
, wnd
->BlkBegLine
));
95 /* position the DfCursor at the matching text */
96 wnd
->CurrCol
= wnd
->BlkBegCol
;
97 wnd
->CurrLine
= wnd
->BlkBegLine
;
98 wnd
->WndRow
= wnd
->CurrLine
- wnd
->wtop
;
100 /* align the window scroll to matching text */
101 if (DfWndCol
> DfClientWidth(wnd
)-1)
102 wnd
->wleft
= wnd
->CurrCol
;
103 if (wnd
->WndRow
> DfClientHeight(wnd
)-1) {
104 wnd
->wtop
= wnd
->CurrLine
;
108 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
109 DfSendMessage(wnd
, DFM_KEYBOARD_CURSOR
,
110 DfWndCol
, wnd
->WndRow
);
113 if (rpl
|| DfYesNoBox("Replace the text?")) {
114 replacetext(wnd
, cp1
, db
);
115 wnd
->TextChanged
= TRUE
;
116 DfBuildTextPointers(wnd
);
122 DfClearTextBlock(wnd
);
123 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
130 DfMessageBox("Search/Replace Text", "No match found");
133 /* ------- search for the occurrance of a string,
134 replace it with a specified string ------- */
135 void DfReplaceText(DFWINDOW wnd
)
139 DfSetCheckBox(&ReplaceTextDB
, DF_ID_MATCHCASE
);
140 if (DfDialogBox(NULL
, &ReplaceTextDB
, TRUE
, NULL
)) {
141 CheckCase
=DfCheckBoxSetting(&ReplaceTextDB
,DF_ID_MATCHCASE
);
142 SearchTextBox(wnd
, FALSE
);
146 /* ------- search for the first occurrance of a string ------ */
147 void DfSearchText(DFWINDOW wnd
)
151 DfSetCheckBox(&SearchTextDB
, DF_ID_MATCHCASE
);
152 if (DfDialogBox(NULL
, &SearchTextDB
, TRUE
, NULL
)) {
153 CheckCase
=DfCheckBoxSetting(&SearchTextDB
,DF_ID_MATCHCASE
);
154 SearchTextBox(wnd
, FALSE
);
158 /* ------- search for the next occurrance of a string ------- */
159 void DfSearchNext(DFWINDOW wnd
)
161 SearchTextBox(wnd
, TRUE
);