cleaned all trailing white space from source files.
[sdk] / ecere / src / gui / dialogs / ReplaceDialog.ec
1 namespace gui::dialogs;
2
3 import "Window"
4
5 #define ID_REPLACE   1
6
7 public class ReplaceDialog : Window
8 {
9    hasClose = true;
10    tabCycle = true;
11    borderStyle = fixed;
12    background = formColor;
13    minClientSize = { 432, 144 };
14    text = $"Replace";
15
16 public:
17    property EditBox editBox
18    {
19       set
20       {
21          int x1, y1, x2, y2;
22
23          editBox = value;
24
25          // Selection Only Default Check / Disabled
26          if(value)
27             value.GetSelPos(null, &y1, &x1, null, &y2, &x2, true);
28          if(!editBox || (x1 == x2 && y1 == y2))
29             selection.disabled = true;
30          if(y1 == y2 || !editBox)
31             wholeFile.checked = true;
32          else
33             selection.checked = true;
34
35          if(value && y1 == y2 && x1 != x2)
36          {
37             char * selection = new char[value.SelSize() + 1];
38             value.GetSel(selection, false);
39             findWhat.contents = selection;
40
41             findNext.disabled = !selection[0];
42             replace.disabled = !selection[0];
43             replaceAll.disabled = !selection[0];
44
45             delete selection;
46             replace.isDefault = true;
47          }
48       }
49    };
50    property char * searchString
51    {
52       set
53       {
54          findWhat.contents = value;
55          findNext.disabled = !value || !value[0];
56          replace.disabled = !value || !value[0];
57          replaceAll.disabled = !value || !value[0];
58       }
59       get { return findWhat.contents; }
60    };
61    property char * replaceString { set { replaceWith.contents = replaceString; } get { return replaceWith.contents; } }
62    property bool wholeWord { set { wholeWord.checked = value; } get { return wholeWord.checked; } };
63    property bool matchCase { set { matchCase.checked = value; } get { return matchCase.checked; } };
64
65 private:
66
67    bool FindClicked(Button control, int x, int y, Modifiers mods)
68    {
69       EditBoxFindResult findResult;
70       int lastX, lastY;
71       EditLine lastLine;
72       EditLine line1, line2;
73       int sel1X, sel1Y, sel2X, sel2Y;
74
75       bool selectionOnly = selection.checked;
76       bool wholeWord = this.wholeWord.checked;
77       bool matchCase = this.matchCase.checked;
78       char * searchString = findWhat.contents;
79       char * replaceString = replaceWith.contents;
80
81       if(!editBox) return false;
82       if(!continued)
83       {
84          wrapped = 0;
85          entriesReplaced = entriesFound = 0;
86
87          // If in selection mode, the end of the selection is the end point of the replace
88          if(selectionOnly)
89             editBox.GetSelPos(null, null, null,
90                &line, &this.y, &this.x, true);
91          // If in whole file mode, the starting position is the end of the replace
92          else
93             editBox.GetSelPos(
94                null, &this.y, &this.x,
95                null, null, null, true);
96       }
97
98       editBox.GetSelPos(&line1, &sel1Y, &sel1X, &line2, &sel2Y, &sel2X, true);
99       // Invert Selection
100       if(sel1X != sel2X || sel1Y != sel2Y)
101          editBox.Select(line2, sel2Y, sel2X, line1, sel1Y, sel1X);
102
103       lastX = editBox.column;
104       lastY = editBox.lineNumber;
105       lastLine = editBox.line;
106
107       if(selectionOnly)
108          findResult = editBox.FindInSelection(searchString, wholeWord, matchCase, line, this.y, this.x);
109       else
110          findResult = editBox.Find(searchString, wholeWord, matchCase, true);
111
112       if(findResult)
113       {
114          int newSel1X, newSel1Y, newSel2X, newSel2Y;
115          editBox.GetSelPos(null, &newSel1Y, &newSel1X, null, &newSel2Y, &newSel2X, true);
116          if(newSel1X == sel1X && newSel1Y == sel1Y && newSel2X == sel2X && newSel2Y == sel2Y)
117          {
118             if(control.id == ID_REPLACE)   // Replace
119             {
120                if(this.y == sel1Y && sel1X <= this.x)
121                   this.x += strlen(replaceString) - (newSel2X - newSel1X);
122                editBox.PutS(replaceString);
123                editBox.UpdateDisplay();
124
125                entriesReplaced++;
126             }
127             if(selectionOnly)
128                findResult = editBox.FindInSelection(searchString, wholeWord, matchCase, line, this.y, this.x);
129             else
130                findResult = editBox.Find(searchString, wholeWord, matchCase, true);
131
132             entriesFound++;
133          }
134       }
135       // Reselect text in proper order if no search result
136       else if(sel1X != sel2X || sel1Y != sel2Y)
137          editBox.Select(line1, sel1Y, sel1X, line2, sel2Y, sel2X);
138
139       // Only for whole file search...
140       if(findResult == wrapped) wrapped++;
141       if(findResult != notFound && wrapped)
142       {
143          int curX, curY;
144          editBox.GetSelPos(null, &curY, &curX, null, null, null, true);
145          if(wrapped == 2 ||
146             curY > this.y || (curY == this.y && curX >= this.x))
147          {
148             editBox.GoToPosition(lastLine, lastY, lastX);
149             findResult = notFound;
150          }
151       }
152
153       if(findResult == notFound)
154       {
155          if(entriesFound)
156          {
157             char contents[1024];
158             sprintf(contents, $"%d occurences found, %d replaced", entriesFound, entriesReplaced);
159             MessageBox { type = ok, master = this, text = $"Search Finished", contents = contents }.Modal();
160          }
161          else
162             MessageBox { type = ok, master = this, text = $"Search Finished", contents = $"Search string not found." }.Modal();
163          continued = false;
164
165          selection.disabled = true;
166          wholeFile.checked = true;
167          findNext.isDefault = true;
168       }
169       else
170       {
171          continued = true;
172          replace.isDefault = true;
173       }
174       // findWhat.Activate();
175       return false; //true;
176    }
177
178    // Any      UNUSED CODE???
179    bool EditBoxChanged(EditBox control)
180    {
181       if(continued)
182       {
183          selection.disabled = true;
184          wholeFile.checked = true;
185          continued = false;
186          findNext.isDefault = true;
187       }
188       return true;
189    }
190
191    // Find what only
192    bool OtherClicked(Button control, int x, int y, Modifiers mods)
193    {
194       if(continued)
195       {
196          selection.disabled = true;
197          wholeFile.checked = true;
198          continued = false;
199          findNext.isDefault = true;
200       }
201       return true;
202    }
203
204    EditBox editBox;
205    int x,y;
206    EditLine line;
207    int wrapped;
208    bool continued;
209    int entriesFound, entriesReplaced;
210
211    EditBox replaceWith
212    {
213       this, text = $"Replace with:", anchor = { left = 124, top = 35, right = 120 }, size.h = 20, hotKey = altP;
214    };
215
216    Label replaceWithLabel
217    {
218       this, position = { 10, 35 }, labeledWindow = replaceWith
219    };
220
221    Button wholeWord
222    {
223       this, isCheckbox = true, text = $"Whole word only", position = { 10, 65 }, hotKey = altW;
224       NotifyClicked = OtherClicked;
225    };
226
227    Button matchCase
228    {
229       this, isCheckbox = true, text = $"Match case", position = { 10, 85 }, hotKey = altC;
230       NotifyClicked = OtherClicked;
231    };
232
233    Button selection
234    {
235       this, isRadio = true, text = $"Selection", position = { 180, 85 }, hotKey = altS;
236       NotifyClicked = OtherClicked;
237    };
238
239    Button wholeFile
240    {
241       this, isRadio = true, text = $"Whole File", position = { 180, 105 }, hotKey = altH, checked = true;
242       NotifyClicked = OtherClicked;
243    };
244
245    Label replaceInLabel
246    {
247       this, text = $"Replace In", position = { 180, 65 }
248    };
249
250    Button findNext
251    {
252       this, isDefault = true, keyRepeat = true, text = $"Find Next", anchor = { top = 10, right = 10 }, size = { 100 }, hotKey = altF, disabled = true;
253       NotifyClicked = FindClicked;
254    };
255
256    Button replace
257    {
258       this, keyRepeat = true, text = $"Replace", anchor = { top = 42, right = 10 }, size = { 100 }, hotKey = altR, id = ID_REPLACE, disabled = true;
259       NotifyClicked = FindClicked;
260    };
261
262    Button replaceAll
263    {
264       this, text = $"Replace All", anchor = { top = 75, right = 10 }, size = { 100 }, hotKey = altA, disabled = true;
265
266       bool NotifyClicked(Button control, int x, int y, Modifiers mods)
267       {
268          int searchLen, replaceLen;
269          EditLine line1, line2;
270          int sel1X, sel1Y, sel2X, sel2Y;
271
272          EditLine bakLine1, bakLine2;
273          int bakSel1X, bakSel1Y, bakSel2X, bakSel2Y;
274
275          bool selectionOnly = selection.checked;
276          bool wholeWord = this.wholeWord.checked;
277          bool matchCase = this.matchCase.checked;
278          char * searchString = findWhat.contents;
279          char * replaceString = replaceWith.contents;
280
281          if(!editBox) return false;
282          if(!continued)
283          {
284             wrapped = 0;
285             entriesReplaced = entriesFound = 0;
286
287             editBox.GetSelPos(&bakLine1, &bakSel1Y, &bakSel1X, &bakLine2, &bakSel2Y, &bakSel2X, true);
288
289             // If in selection mode, the end of the selection is the end point of the replace
290             if(selectionOnly)
291                editBox.GetSelPos(null, null, null,
292                   &line, &this.y, &this.x, true);
293             // If in whole file mode, the starting position is the end of the replace
294             else
295                editBox.GetSelPos(
296                   null, &this.y, &this.x,
297                   null, null, null, true);
298          }
299
300          // Invert Selection to find the word again
301          editBox.GetSelPos(
302             &line1, &sel1Y, &sel1X, &line2, &sel2Y, &sel2X, true);
303          if(sel1X != sel2X || sel1Y != sel2Y)
304             editBox.Select(line2, sel2Y, sel2X, line1, sel1Y, sel1X);
305
306          searchLen = strlen(searchString);
307          replaceLen = strlen(replaceString);
308
309          for(;;)
310          {
311             int lastX = editBox.column;
312             int lastY = editBox.lineNumber;
313             int curX, curY;
314             EditLine lastLine = editBox.line;
315             EditBoxFindResult findResult;
316
317             if(selectionOnly)
318                findResult = editBox.FindInSelection(searchString,
319                                wholeWord, matchCase,
320                                line, this.y, this.x);
321             else
322                findResult = editBox.Find(searchString, wholeWord, matchCase, true);
323
324             if(findResult == notFound) break;
325             if(findResult == wrapped) wrapped++;
326
327             editBox.GetSelPos(null, &curY, &curX, null, null, null, true);
328
329             if(wrapped)
330             {
331                if(wrapped == 2 || curY > this.y || (curY == this.y && curX >= this.x))
332                {
333                   editBox.GoToPosition(lastLine, lastY, lastX);
334                   break;
335                }
336             }
337             if(this.y == curY && curX <= this.x)
338                this.x += replaceLen - searchLen;
339             editBox.PutS(replaceString);
340
341             entriesReplaced++;
342             entriesFound++;
343          }
344          if(!entriesFound)
345          {
346             MessageBox { type = ok, master = this, text = $"Search Finished", contents = $"Search string not found." }.Modal();
347
348             // Reselect text in proper order if no search result
349             if(selectionOnly && (sel1X != sel2X || sel1Y != sel2Y))
350                editBox.Select(line1, sel1Y, sel1X, line2, sel2Y, sel2X);
351          }
352          else
353          {
354             char contents[1024];
355             sprintf(contents, $"%d occurences found, %d replaced", entriesFound, entriesReplaced);
356             MessageBox { type = ok, master = this, text = $"Search Finished", contents = contents }.Modal();
357          }
358
359          if(!continued)
360             editBox.Select(bakLine2, bakSel2Y, bakSel2X, bakLine1, bakSel1Y, bakSel1X);
361          else
362          {
363             selection.disabled = true;
364             wholeFile.checked = true;
365             continued = false;
366          }
367          findNext.isDefault = true;
368          return true;
369       }
370    };
371
372    Button cancel
373    {
374       this, text = $"Cancel", anchor = { top = 106, right = 10 }, size = { 100 }, hotKey = escape, NotifyClicked = ButtonCloseDialog;
375    };
376
377    EditBox findWhat
378    {
379       this, text = $"Find what:", anchor = { left = 124, top = 10, right = 120 }, size.h = 20, hotKey = altN;
380
381       void NotifyUpdate(EditBox control)
382       {
383          bool disabled = findWhat.contents[0] ? false : true;
384          findNext.disabled = disabled;
385          replace.disabled = disabled;
386          replaceAll.disabled = disabled;
387       }
388    };
389
390    Label findWhatLabel { this, labeledWindow = findWhat, position = { 10, 10 } };
391
392    bool OnKeyHit(Key key, unichar ch)
393    {
394       if(ch)
395       {
396          findWhat.Activate();
397          return findWhat.OnKeyHit(key, ch);
398       }
399       return true;
400    }
401 }