- Use a separate icon for minimizing windows.
[reactos.git] / rosapps / dflat32 / search.c
1 /* ---------------- search.c ------------- */
2 #include "dflat.h"
3
4 extern DF_DBOX SearchTextDB;
5 extern DF_DBOX ReplaceTextDB;
6 static int CheckCase = TRUE;
7 static int Replacing = FALSE;
8
9 /* - case-insensitive, white-space-normalized char compare - */
10 static BOOL SearchCmp(int a, int b)
11 {
12 if (b == '\n')
13 b = ' ';
14 if (CheckCase)
15 return a != b;
16 return tolower(a) != tolower(b);
17 }
18
19 /* ----- replace a matching block of text ----- */
20 static void replacetext(DFWINDOW wnd, char *cp1, DF_DBOX *db)
21 {
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 */
26 int dif;
27 if (oldlen < newlen) {
28 /* ---- new text expands text size ---- */
29 dif = newlen-oldlen;
30 if (wnd->textlen < strlen(wnd->text)+dif) {
31 /* ---- need to reallocate the text buffer ---- */
32 int offset = (int)((int)cp1-(int)wnd->text);
33 wnd->textlen += dif;
34 wnd->text = DfRealloc(wnd->text, wnd->textlen+2);
35 cp1 = wnd->text + offset;
36 }
37 memmove(cp1+dif, cp1, strlen(cp1)+1);
38 }
39 else if (oldlen > newlen) {
40 /* ---- new text collapses text size ---- */
41 dif = oldlen-newlen;
42 memmove(cp1, cp1+dif, strlen(cp1)+1);
43 }
44 strncpy(cp1, cr, newlen);
45 }
46
47 /* ------- search for the occurrance of a string ------- */
48 static void SearchTextBox(DFWINDOW wnd, int incr)
49 {
50 char *s1 , *s2, *cp1;
51 s1 = s2 = cp1 = NULL;
52 DF_DBOX *db = Replacing ? &ReplaceTextDB : &SearchTextDB;
53 char *cp = DfGetEditBoxText(db, DF_ID_SEARCHFOR);
54 BOOL rpl = TRUE, FoundOne = FALSE;
55
56 while (rpl == TRUE && cp != NULL && *cp) {
57 rpl = Replacing ?
58 DfCheckBoxSetting(&ReplaceTextDB, DF_ID_REPLACEALL) :
59 FALSE;
60 if (DfTextBlockMarked(wnd)) {
61 DfClearTextBlock(wnd);
62 DfSendMessage(wnd, DFM_PAINT, 0, 0);
63 }
64 /* search for a match starting at DfCursor position */
65 cp1 = DfCurrChar;
66 if (incr)
67 cp1++; /* start past the last hit */
68 /* --- compare at each character position --- */
69 while (*cp1) {
70 s1 = cp;
71 s2 = cp1;
72 while (*s1 && *s1 != '\n') {
73 if (SearchCmp(*s1, *s2))
74 break;
75 s1++, s2++;
76 }
77 if (*s1 == '\0' || *s1 == '\n')
78 break;
79 cp1++;
80 }
81 if (s1 != NULL && (*s1 == 0 || *s1 == '\n')) {
82 /* ----- match at *cp1 ------- */
83 FoundOne = TRUE;
84
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;
90 wnd->BlkEndCol =
91 (int)((int)s2 - (int)DfTextLine(wnd, wnd->BlkEndLine));
92 wnd->BlkBegCol =
93 (int)((int)cp1 - (int)DfTextLine(wnd, wnd->BlkBegLine));
94
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;
99
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;
105 wnd->WndRow = 0;
106 }
107
108 DfSendMessage(wnd, DFM_PAINT, 0, 0);
109 DfSendMessage(wnd, DFM_KEYBOARD_CURSOR,
110 DfWndCol, wnd->WndRow);
111
112 if (Replacing) {
113 if (rpl || DfYesNoBox("Replace the text?")) {
114 replacetext(wnd, cp1, db);
115 wnd->TextChanged = TRUE;
116 DfBuildTextPointers(wnd);
117 }
118 if (rpl) {
119 incr = TRUE;
120 continue;
121 }
122 DfClearTextBlock(wnd);
123 DfSendMessage(wnd, DFM_PAINT, 0, 0);
124 }
125 return;
126 }
127 break;
128 }
129 if (!FoundOne)
130 DfMessageBox("Search/Replace Text", "No match found");
131 }
132
133 /* ------- search for the occurrance of a string,
134 replace it with a specified string ------- */
135 void DfReplaceText(DFWINDOW wnd)
136 {
137 Replacing = TRUE;
138 if (CheckCase)
139 DfSetCheckBox(&ReplaceTextDB, DF_ID_MATCHCASE);
140 if (DfDialogBox(NULL, &ReplaceTextDB, TRUE, NULL)) {
141 CheckCase=DfCheckBoxSetting(&ReplaceTextDB,DF_ID_MATCHCASE);
142 SearchTextBox(wnd, FALSE);
143 }
144 }
145
146 /* ------- search for the first occurrance of a string ------ */
147 void DfSearchText(DFWINDOW wnd)
148 {
149 Replacing = FALSE;
150 if (CheckCase)
151 DfSetCheckBox(&SearchTextDB, DF_ID_MATCHCASE);
152 if (DfDialogBox(NULL, &SearchTextDB, TRUE, NULL)) {
153 CheckCase=DfCheckBoxSetting(&SearchTextDB,DF_ID_MATCHCASE);
154 SearchTextBox(wnd, FALSE);
155 }
156 }
157
158 /* ------- search for the next occurrance of a string ------- */
159 void DfSearchNext(DFWINDOW wnd)
160 {
161 SearchTextBox(wnd, TRUE);
162 }
163
164 /* EOF */