]>
Commit | Line | Data |
---|---|---|
d1dc2b32 RD |
1 | #---------------------------------------------------------------------------- |
2 | # Name: FindService.py | |
3 | # Purpose: Find Service for pydocview | |
4 | # | |
5 | # Author: Peter Yared, Morgan Hua | |
6 | # | |
7 | # Created: 8/15/03 | |
8 | # CVS-ID: $Id$ | |
3fa8f722 | 9 | # Copyright: (c) 2003-2005 ActiveGrid, Inc. |
bbf7159c | 10 | # License: wxWindows License |
d1dc2b32 RD |
11 | #---------------------------------------------------------------------------- |
12 | ||
13 | import wx | |
14 | import wx.lib.docview | |
15 | import wx.lib.pydocview | |
16 | import re | |
17 | _ = wx.GetTranslation | |
18 | ||
19 | ||
20 | #---------------------------------------------------------------------------- | |
21 | # Constants | |
22 | #---------------------------------------------------------------------------- | |
23 | FIND_MATCHPATTERN = "FindMatchPattern" | |
24 | FIND_MATCHREPLACE = "FindMatchReplace" | |
25 | FIND_MATCHCASE = "FindMatchCase" | |
26 | FIND_MATCHWHOLEWORD = "FindMatchWholeWordOnly" | |
27 | FIND_MATCHREGEXPR = "FindMatchRegularExpr" | |
28 | FIND_MATCHWRAP = "FindMatchWrap" | |
29 | FIND_MATCHUPDOWN = "FindMatchUpDown" | |
30 | ||
31 | FIND_SYNTAXERROR = -2 | |
32 | ||
33 | SPACE = 10 | |
34 | HALF_SPACE = 5 | |
35 | ||
36 | ||
37 | #---------------------------------------------------------------------------- | |
38 | # Classes | |
39 | #---------------------------------------------------------------------------- | |
40 | ||
41 | class FindService(wx.lib.pydocview.DocService): | |
42 | ||
43 | #---------------------------------------------------------------------------- | |
44 | # Constants | |
45 | #---------------------------------------------------------------------------- | |
46 | FIND_ID = wx.NewId() # for bringing up Find dialog box | |
47 | FINDONE_ID = wx.NewId() # for doing Find | |
48 | FIND_PREVIOUS_ID = wx.NewId() # for doing Find Next | |
49 | FIND_NEXT_ID = wx.NewId() # for doing Find Prev | |
50 | REPLACE_ID = wx.NewId() # for bringing up Replace dialog box | |
51 | REPLACEONE_ID = wx.NewId() # for doing a Replace | |
52 | REPLACEALL_ID = wx.NewId() # for doing Replace All | |
53 | GOTO_LINE_ID = wx.NewId() # for bringing up Goto dialog box | |
54 | ||
55 | # Extending bitmasks: wx.FR_WHOLEWORD, wx.FR_MATCHCASE, and wx.FR_DOWN | |
56 | FR_REGEXP = max([wx.FR_WHOLEWORD, wx.FR_MATCHCASE, wx.FR_DOWN]) << 1 | |
57 | FR_WRAP = FR_REGEXP << 1 | |
58 | ||
59 | ||
60 | def __init__(self): | |
61 | self._replaceDialog = None | |
62 | self._findDialog = None | |
63 | self._findReplaceData = wx.FindReplaceData() | |
64 | self._findReplaceData.SetFlags(wx.FR_DOWN) | |
65 | ||
66 | ||
67 | def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None): | |
68 | """ Install Find Service Menu Items """ | |
69 | editMenu = menuBar.GetMenu(menuBar.FindMenu(_("&Edit"))) | |
70 | editMenu.AppendSeparator() | |
71 | editMenu.Append(FindService.FIND_ID, _("&Find...\tCtrl+F"), _("Finds the specified text")) | |
72 | wx.EVT_MENU(frame, FindService.FIND_ID, frame.ProcessEvent) | |
73 | wx.EVT_UPDATE_UI(frame, FindService.FIND_ID, frame.ProcessUpdateUIEvent) | |
74 | editMenu.Append(FindService.FIND_PREVIOUS_ID, _("Find &Previous\tShift+F3"), _("Finds the specified text")) | |
75 | wx.EVT_MENU(frame, FindService.FIND_PREVIOUS_ID, frame.ProcessEvent) | |
76 | wx.EVT_UPDATE_UI(frame, FindService.FIND_PREVIOUS_ID, frame.ProcessUpdateUIEvent) | |
77 | editMenu.Append(FindService.FIND_NEXT_ID, _("Find &Next\tF3"), _("Finds the specified text")) | |
78 | wx.EVT_MENU(frame, FindService.FIND_NEXT_ID, frame.ProcessEvent) | |
79 | wx.EVT_UPDATE_UI(frame, FindService.FIND_NEXT_ID, frame.ProcessUpdateUIEvent) | |
80 | editMenu.Append(FindService.REPLACE_ID, _("R&eplace...\tCtrl+H"), _("Replaces specific text with different text")) | |
81 | wx.EVT_MENU(frame, FindService.REPLACE_ID, frame.ProcessEvent) | |
82 | wx.EVT_UPDATE_UI(frame, FindService.REPLACE_ID, frame.ProcessUpdateUIEvent) | |
83 | editMenu.Append(FindService.GOTO_LINE_ID, _("&Go to Line...\tCtrl+G"), _("Goes to a certain line in the file")) | |
84 | wx.EVT_MENU(frame, FindService.GOTO_LINE_ID, frame.ProcessEvent) | |
85 | wx.EVT_UPDATE_UI(frame, FindService.GOTO_LINE_ID, frame.ProcessUpdateUIEvent) | |
86 | ||
87 | # wxBug: wxToolBar::GetToolPos doesn't exist, need it to find cut tool and then insert find in front of it. | |
88 | toolBar.InsertTool(6, FindService.FIND_ID, getFindBitmap(), shortHelpString = _("Find"), longHelpString = _("Finds the specified text")) | |
89 | toolBar.InsertSeparator(6) | |
90 | toolBar.Realize() | |
91 | ||
92 | frame.Bind(wx.EVT_FIND, frame.ProcessEvent) | |
93 | frame.Bind(wx.EVT_FIND_NEXT, frame.ProcessEvent) | |
94 | frame.Bind(wx.EVT_FIND_REPLACE, frame.ProcessEvent) | |
95 | frame.Bind(wx.EVT_FIND_REPLACE_ALL, frame.ProcessEvent) | |
96 | ||
97 | ||
98 | def ProcessUpdateUIEvent(self, event): | |
99 | id = event.GetId() | |
b792147d RD |
100 | if (id == FindService.FIND_ID |
101 | or id == FindService.FIND_PREVIOUS_ID | |
102 | or id == FindService.FIND_NEXT_ID | |
103 | or id == FindService.REPLACE_ID | |
104 | or id == FindService.GOTO_LINE_ID): | |
d1dc2b32 RD |
105 | event.Enable(False) |
106 | return True | |
107 | else: | |
108 | return False | |
109 | ||
110 | ||
111 | def ShowFindReplaceDialog(self, findString="", replace = False): | |
112 | """ Display find/replace dialog box. | |
113 | ||
114 | Parameters: findString is the default value shown in the find/replace dialog input field. | |
115 | If replace is True, the replace dialog box is shown, otherwise only the find dialog box is shown. | |
116 | """ | |
117 | if replace: | |
118 | if self._findDialog != None: | |
119 | # No reason to have both find and replace dialogs up at the same time | |
120 | self._findDialog.DoClose() | |
121 | self._findDialog = None | |
122 | ||
123 | self._replaceDialog = FindReplaceDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Replace"), size=(320,200), findString=findString) | |
aca310e5 | 124 | self._replaceDialog.CenterOnParent() |
d1dc2b32 RD |
125 | self._replaceDialog.Show(True) |
126 | else: | |
127 | if self._replaceDialog != None: | |
128 | # No reason to have both find and replace dialogs up at the same time | |
129 | self._replaceDialog.DoClose() | |
130 | self._replaceDialog = None | |
131 | ||
132 | self._findDialog = FindDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Find"), size=(320,200), findString=findString) | |
aca310e5 | 133 | self._findDialog.CenterOnParent() |
d1dc2b32 RD |
134 | self._findDialog.Show(True) |
135 | ||
136 | ||
137 | ||
138 | def OnFindClose(self, event): | |
139 | """ Cleanup handles when find/replace dialog is closed """ | |
140 | if self._findDialog != None: | |
141 | self._findDialog = None | |
142 | elif self._replaceDialog != None: | |
143 | self._replaceDialog = None | |
144 | ||
145 | ||
146 | def GetCurrentDialog(self): | |
147 | """ return handle to either the find or replace dialog """ | |
148 | if self._findDialog != None: | |
149 | return self._findDialog | |
150 | return self._replaceDialog | |
151 | ||
152 | ||
153 | def GetLineNumber(self, parent): | |
154 | """ Display Goto Line Number dialog box """ | |
155 | line = -1 | |
156 | dialog = wx.TextEntryDialog(parent, _("Enter line number to go to:"), _("Go to Line")) | |
aca310e5 | 157 | dialog.CenterOnParent() |
d1dc2b32 RD |
158 | if dialog.ShowModal() == wx.ID_OK: |
159 | try: | |
160 | line = int(dialog.GetValue()) | |
161 | if line > 65535: | |
162 | line = 65535 | |
163 | except: | |
164 | pass | |
165 | dialog.Destroy() | |
166 | # This one is ugly: wx.GetNumberFromUser("", _("Enter line number to go to:"), _("Go to Line"), 1, min = 1, max = 65535, parent = parent) | |
167 | return line | |
168 | ||
169 | ||
170 | def DoFind(self, findString, replaceString, text, startLoc, endLoc, down, matchCase, wholeWord, regExpr = False, replace = False, replaceAll = False, wrap = False): | |
171 | """ Do the actual work of the find/replace. | |
172 | ||
173 | Returns the tuple (count, start, end, newText). | |
174 | count = number of string replacements | |
175 | start = start position of found string | |
176 | end = end position of found string | |
177 | newText = new replaced text | |
178 | """ | |
179 | flags = 0 | |
180 | if regExpr: | |
181 | pattern = findString | |
182 | else: | |
183 | pattern = re.escape(findString) # Treat the strings as a literal string | |
184 | if not matchCase: | |
185 | flags = re.IGNORECASE | |
186 | if wholeWord: | |
187 | pattern = r"\b%s\b" % pattern | |
188 | ||
189 | try: | |
190 | reg = re.compile(pattern, flags) | |
191 | except: | |
192 | # syntax error of some sort | |
193 | import sys | |
194 | msgTitle = wx.GetApp().GetAppName() | |
195 | if not msgTitle: | |
196 | msgTitle = _("Regular Expression Search") | |
197 | wx.MessageBox(_("Invalid regular expression \"%s\". %s") % (pattern, sys.exc_value), | |
198 | msgTitle, | |
199 | wx.OK | wx.ICON_EXCLAMATION, | |
200 | self.GetView()) | |
201 | return FIND_SYNTAXERROR, None, None, None | |
202 | ||
203 | if replaceAll: | |
204 | newText, count = reg.subn(replaceString, text) | |
205 | if count == 0: | |
206 | return -1, None, None, None | |
207 | else: | |
208 | return count, None, None, newText | |
209 | ||
210 | start = -1 | |
211 | if down: | |
212 | match = reg.search(text, endLoc) | |
213 | if match == None: | |
214 | if wrap: # try again, but this time from top of file | |
215 | match = reg.search(text, 0) | |
216 | if match == None: | |
217 | return -1, None, None, None | |
218 | else: | |
219 | return -1, None, None, None | |
220 | start = match.start() | |
221 | end = match.end() | |
222 | else: | |
223 | match = reg.search(text) | |
224 | if match == None: | |
225 | return -1, None, None, None | |
226 | found = None | |
227 | i, j = match.span() | |
228 | while i < startLoc and j <= startLoc: | |
229 | found = match | |
230 | if i == j: | |
231 | j = j + 1 | |
232 | match = reg.search(text, j) | |
233 | if match == None: | |
234 | break | |
235 | i, j = match.span() | |
236 | if found == None: | |
237 | if wrap: # try again, but this time from bottom of file | |
238 | match = reg.search(text, startLoc) | |
239 | if match == None: | |
240 | return -1, None, None, None | |
241 | found = None | |
242 | i, j = match.span() | |
243 | end = len(text) | |
244 | while i < end and j <= end: | |
245 | found = match | |
246 | if i == j: | |
247 | j = j + 1 | |
248 | match = reg.search(text, j) | |
249 | if match == None: | |
250 | break | |
251 | i, j = match.span() | |
252 | if found == None: | |
253 | return -1, None, None, None | |
254 | else: | |
255 | return -1, None, None, None | |
256 | start = found.start() | |
257 | end = found.end() | |
258 | ||
259 | if replace and start != -1: | |
260 | newText, count = reg.subn(replaceString, text, 1) | |
261 | return count, start, end, newText | |
262 | ||
263 | return 0, start, end, None | |
264 | ||
265 | ||
266 | def SaveFindConfig(self, findString, wholeWord, matchCase, regExpr = None, wrap = None, upDown = None, replaceString = None): | |
267 | """ Save find/replace patterns and search flags to registry. | |
268 | ||
269 | findString = search pattern | |
270 | wholeWord = match whole word only | |
271 | matchCase = match case | |
272 | regExpr = use regular expressions in search pattern | |
273 | wrap = return to top/bottom of file on search | |
274 | upDown = search up or down from current cursor position | |
275 | replaceString = replace string | |
276 | """ | |
277 | config = wx.ConfigBase_Get() | |
278 | ||
279 | config.Write(FIND_MATCHPATTERN, findString) | |
280 | config.WriteInt(FIND_MATCHCASE, matchCase) | |
281 | config.WriteInt(FIND_MATCHWHOLEWORD, wholeWord) | |
282 | if replaceString != None: | |
283 | config.Write(FIND_MATCHREPLACE, replaceString) | |
284 | if regExpr != None: | |
285 | config.WriteInt(FIND_MATCHREGEXPR, regExpr) | |
286 | if wrap != None: | |
287 | config.WriteInt(FIND_MATCHWRAP, wrap) | |
288 | if upDown != None: | |
289 | config.WriteInt(FIND_MATCHUPDOWN, upDown) | |
290 | ||
291 | ||
292 | def GetFindString(self): | |
293 | """ Load the search pattern from registry """ | |
294 | return wx.ConfigBase_Get().Read(FIND_MATCHPATTERN, "") | |
295 | ||
296 | ||
297 | def GetReplaceString(self): | |
298 | """ Load the replace pattern from registry """ | |
299 | return wx.ConfigBase_Get().Read(FIND_MATCHREPLACE, "") | |
300 | ||
301 | ||
302 | def GetFlags(self): | |
303 | """ Load search parameters from registry """ | |
304 | config = wx.ConfigBase_Get() | |
305 | ||
306 | flags = 0 | |
307 | if config.ReadInt(FIND_MATCHWHOLEWORD, False): | |
308 | flags = flags | wx.FR_WHOLEWORD | |
309 | if config.ReadInt(FIND_MATCHCASE, False): | |
310 | flags = flags | wx.FR_MATCHCASE | |
311 | if config.ReadInt(FIND_MATCHUPDOWN, False): | |
312 | flags = flags | wx.FR_DOWN | |
313 | if config.ReadInt(FIND_MATCHREGEXPR, False): | |
314 | flags = flags | FindService.FR_REGEXP | |
315 | if config.ReadInt(FIND_MATCHWRAP, False): | |
316 | flags = flags | FindService.FR_WRAP | |
317 | return flags | |
318 | ||
319 | ||
320 | class FindDialog(wx.Dialog): | |
321 | """ Find Dialog with regular expression matching and wrap to top/bottom of file. """ | |
322 | ||
323 | def __init__(self, parent, id, title, size, findString=None): | |
324 | wx.Dialog.__init__(self, parent, id, title, size=size) | |
325 | ||
326 | config = wx.ConfigBase_Get() | |
327 | borderSizer = wx.BoxSizer(wx.VERTICAL) | |
328 | gridSizer = wx.GridBagSizer(SPACE, SPACE) | |
329 | ||
330 | lineSizer = wx.BoxSizer(wx.HORIZONTAL) | |
331 | lineSizer.Add(wx.StaticText(self, -1, _("Find what:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, SPACE) | |
332 | if not findString: | |
333 | findString = config.Read(FIND_MATCHPATTERN, "") | |
334 | self._findCtrl = wx.TextCtrl(self, -1, findString, size=(200,-1)) | |
335 | lineSizer.Add(self._findCtrl, 0) | |
336 | gridSizer.Add(lineSizer, pos=(0,0), span=(1,2)) | |
337 | choiceSizer = wx.BoxSizer(wx.VERTICAL) | |
338 | self._wholeWordCtrl = wx.CheckBox(self, -1, _("Match whole word only")) | |
339 | self._wholeWordCtrl.SetValue(config.ReadInt(FIND_MATCHWHOLEWORD, False)) | |
340 | self._matchCaseCtrl = wx.CheckBox(self, -1, _("Match case")) | |
341 | self._matchCaseCtrl.SetValue(config.ReadInt(FIND_MATCHCASE, False)) | |
342 | self._regExprCtrl = wx.CheckBox(self, -1, _("Regular expression")) | |
343 | self._regExprCtrl.SetValue(config.ReadInt(FIND_MATCHREGEXPR, False)) | |
344 | self._wrapCtrl = wx.CheckBox(self, -1, _("Wrap")) | |
345 | self._wrapCtrl.SetValue(config.ReadInt(FIND_MATCHWRAP, False)) | |
346 | choiceSizer.Add(self._wholeWordCtrl, 0, wx.BOTTOM, SPACE) | |
347 | choiceSizer.Add(self._matchCaseCtrl, 0, wx.BOTTOM, SPACE) | |
348 | choiceSizer.Add(self._regExprCtrl, 0, wx.BOTTOM, SPACE) | |
349 | choiceSizer.Add(self._wrapCtrl, 0) | |
350 | gridSizer.Add(choiceSizer, pos=(1,0), span=(2,1)) | |
351 | ||
352 | self._radioBox = wx.RadioBox(self, -1, _("Direction"), choices = ["Up", "Down"]) | |
353 | self._radioBox.SetSelection(config.ReadInt(FIND_MATCHUPDOWN, 1)) | |
354 | gridSizer.Add(self._radioBox, pos=(1,1), span=(2,1)) | |
355 | ||
356 | buttonSizer = wx.BoxSizer(wx.VERTICAL) | |
357 | findBtn = wx.Button(self, FindService.FINDONE_ID, _("Find Next")) | |
358 | findBtn.SetDefault() | |
359 | wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent) | |
b792147d | 360 | cancelBtn = wx.Button(self, wx.ID_CANCEL) |
d1dc2b32 | 361 | wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnClose) |
aca310e5 RD |
362 | BTM_SPACE = HALF_SPACE |
363 | if wx.Platform == "__WXMAC__": | |
364 | BTM_SPACE = SPACE | |
365 | buttonSizer.Add(findBtn, 0, wx.BOTTOM, BTM_SPACE) | |
d1dc2b32 RD |
366 | buttonSizer.Add(cancelBtn, 0) |
367 | gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1)) | |
368 | ||
369 | borderSizer.Add(gridSizer, 0, wx.ALL, SPACE) | |
370 | ||
371 | self.Bind(wx.EVT_CLOSE, self.OnClose) | |
372 | ||
373 | self.SetSizer(borderSizer) | |
374 | self.Fit() | |
375 | self._findCtrl.SetFocus() | |
376 | ||
377 | def SaveConfig(self): | |
378 | """ Save find patterns and search flags to registry. """ | |
379 | findService = wx.GetApp().GetService(FindService) | |
380 | if findService: | |
381 | findService.SaveFindConfig(self._findCtrl.GetValue(), | |
382 | self._wholeWordCtrl.IsChecked(), | |
383 | self._matchCaseCtrl.IsChecked(), | |
384 | self._regExprCtrl.IsChecked(), | |
385 | self._wrapCtrl.IsChecked(), | |
386 | self._radioBox.GetSelection(), | |
387 | ) | |
388 | ||
389 | ||
390 | def DoClose(self): | |
391 | self.SaveConfig() | |
392 | self.Destroy() | |
393 | ||
394 | ||
395 | def OnClose(self, event): | |
396 | findService = wx.GetApp().GetService(FindService) | |
397 | if findService: | |
398 | findService.OnFindClose(event) | |
399 | self.DoClose() | |
400 | ||
401 | ||
402 | def OnActionEvent(self, event): | |
403 | self.SaveConfig() | |
404 | ||
405 | if wx.GetApp().GetDocumentManager().GetFlags() & wx.lib.docview.DOC_MDI: | |
406 | if wx.GetApp().GetTopWindow().ProcessEvent(event): | |
407 | return True | |
408 | else: | |
409 | view = wx.GetApp().GetDocumentManager().GetLastActiveView() | |
410 | if view and view.ProcessEvent(event): | |
411 | return True | |
412 | return False | |
413 | ||
414 | ||
415 | class FindReplaceDialog(FindDialog): | |
416 | """ Find/Replace Dialog with regular expression matching and wrap to top/bottom of file. """ | |
417 | ||
418 | def __init__(self, parent, id, title, size, findString=None): | |
419 | wx.Dialog.__init__(self, parent, id, title, size=size) | |
420 | ||
421 | config = wx.ConfigBase_Get() | |
422 | borderSizer = wx.BoxSizer(wx.VERTICAL) | |
423 | gridSizer = wx.GridBagSizer(SPACE, SPACE) | |
424 | ||
425 | gridSizer2 = wx.GridBagSizer(SPACE, SPACE) | |
426 | gridSizer2.Add(wx.StaticText(self, -1, _("Find what:")), flag=wx.ALIGN_CENTER_VERTICAL, pos=(0,0)) | |
427 | if not findString: | |
428 | findString = config.Read(FIND_MATCHPATTERN, "") | |
429 | self._findCtrl = wx.TextCtrl(self, -1, findString, size=(200,-1)) | |
430 | gridSizer2.Add(self._findCtrl, pos=(0,1)) | |
431 | gridSizer2.Add(wx.StaticText(self, -1, _("Replace with:")), flag=wx.ALIGN_CENTER_VERTICAL, pos=(1,0)) | |
432 | self._replaceCtrl = wx.TextCtrl(self, -1, config.Read(FIND_MATCHREPLACE, ""), size=(200,-1)) | |
433 | gridSizer2.Add(self._replaceCtrl, pos=(1,1)) | |
434 | gridSizer.Add(gridSizer2, pos=(0,0), span=(1,2)) | |
435 | choiceSizer = wx.BoxSizer(wx.VERTICAL) | |
436 | self._wholeWordCtrl = wx.CheckBox(self, -1, _("Match whole word only")) | |
437 | self._wholeWordCtrl.SetValue(config.ReadInt(FIND_MATCHWHOLEWORD, False)) | |
438 | self._matchCaseCtrl = wx.CheckBox(self, -1, _("Match case")) | |
439 | self._matchCaseCtrl.SetValue(config.ReadInt(FIND_MATCHCASE, False)) | |
440 | self._regExprCtrl = wx.CheckBox(self, -1, _("Regular expression")) | |
441 | self._regExprCtrl.SetValue(config.ReadInt(FIND_MATCHREGEXPR, False)) | |
442 | self._wrapCtrl = wx.CheckBox(self, -1, _("Wrap")) | |
443 | self._wrapCtrl.SetValue(config.ReadInt(FIND_MATCHWRAP, False)) | |
444 | choiceSizer.Add(self._wholeWordCtrl, 0, wx.BOTTOM, SPACE) | |
445 | choiceSizer.Add(self._matchCaseCtrl, 0, wx.BOTTOM, SPACE) | |
446 | choiceSizer.Add(self._regExprCtrl, 0, wx.BOTTOM, SPACE) | |
447 | choiceSizer.Add(self._wrapCtrl, 0) | |
448 | gridSizer.Add(choiceSizer, pos=(1,0), span=(2,1)) | |
449 | ||
450 | self._radioBox = wx.RadioBox(self, -1, _("Direction"), choices = ["Up", "Down"]) | |
451 | self._radioBox.SetSelection(config.ReadInt(FIND_MATCHUPDOWN, 1)) | |
452 | gridSizer.Add(self._radioBox, pos=(1,1), span=(2,1)) | |
453 | ||
454 | buttonSizer = wx.BoxSizer(wx.VERTICAL) | |
455 | findBtn = wx.Button(self, FindService.FINDONE_ID, _("Find Next")) | |
456 | findBtn.SetDefault() | |
457 | wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent) | |
b792147d | 458 | cancelBtn = wx.Button(self, wx.ID_CANCEL) |
d1dc2b32 RD |
459 | wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnClose) |
460 | replaceBtn = wx.Button(self, FindService.REPLACEONE_ID, _("Replace")) | |
461 | wx.EVT_BUTTON(self, FindService.REPLACEONE_ID, self.OnActionEvent) | |
462 | replaceAllBtn = wx.Button(self, FindService.REPLACEALL_ID, _("Replace All")) | |
463 | wx.EVT_BUTTON(self, FindService.REPLACEALL_ID, self.OnActionEvent) | |
aca310e5 RD |
464 | |
465 | BTM_SPACE = HALF_SPACE | |
466 | if wx.Platform == "__WXMAC__": | |
467 | BTM_SPACE = SPACE | |
468 | ||
469 | buttonSizer.Add(findBtn, 0, wx.BOTTOM, BTM_SPACE) | |
470 | buttonSizer.Add(replaceBtn, 0, wx.BOTTOM, BTM_SPACE) | |
471 | buttonSizer.Add(replaceAllBtn, 0, wx.BOTTOM, BTM_SPACE) | |
d1dc2b32 RD |
472 | buttonSizer.Add(cancelBtn, 0) |
473 | gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1)) | |
474 | ||
475 | borderSizer.Add(gridSizer, 0, wx.ALL, SPACE) | |
476 | ||
477 | self.Bind(wx.EVT_CLOSE, self.OnClose) | |
478 | ||
479 | self.SetSizer(borderSizer) | |
480 | self.Fit() | |
481 | self._findCtrl.SetFocus() | |
482 | ||
483 | ||
484 | def SaveConfig(self): | |
485 | """ Save find/replace patterns and search flags to registry. """ | |
486 | findService = wx.GetApp().GetService(FindService) | |
487 | if findService: | |
488 | findService.SaveFindConfig(self._findCtrl.GetValue(), | |
489 | self._wholeWordCtrl.IsChecked(), | |
490 | self._matchCaseCtrl.IsChecked(), | |
491 | self._regExprCtrl.IsChecked(), | |
492 | self._wrapCtrl.IsChecked(), | |
493 | self._radioBox.GetSelection(), | |
494 | self._replaceCtrl.GetValue() | |
495 | ) | |
496 | ||
497 | ||
498 | #---------------------------------------------------------------------------- | |
499 | # Menu Bitmaps - generated by encode_bitmaps.py | |
500 | #---------------------------------------------------------------------------- | |
501 | from wx import ImageFromStream, BitmapFromImage | |
502 | import cStringIO | |
503 | ||
504 | ||
505 | def getFindData(): | |
506 | return \ | |
507 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ | |
508 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ | |
aca310e5 RD |
509 | \x00\x01\xb1IDAT8\x8d\xa5\x93=o\xd3P\x14\x86\x1f\xa7\x11\x95<\xdc\xc6\xecN+5\ |
510 | [\x86B\x99\xacLQ2Zr[\x89\xa1\xfd\x0b%\x95\x90\x00\xf1\x03\x80\x01\x98\x80\ | |
511 | \x19G\xac\x0cm\xff@Y\xd9:\xd9Ck\x94\xd6\xddb\x94\x9b\x98\xc8\xd2e1C\xe5\x8b\ | |
512 | \xdd\x14\x96\xbe\xdb=\x1f\xefy\xef\xf90\x8c\xda\x12wA\xbd\xfc\x18\xfa\x9fs\ | |
513 | \x80\xf9|\x0e\xc0\x93\xc1\x81\x01\xf0\xe6\xf5\xab\x1c`:\x9d\x02\xf0\xf6\xdd{\ | |
514 | \xa3\xc8\xa9\xddd\xec\xf5z\xb4Z\xeb\x00\x1c\x1f\x1d\xe6\x85\xdd\xf3<\x06\x83\ | |
515 | \xc1\x82\xbd\xa2 \x0cCL\xd3d<\x1e\x13\xc71\xb6m\x030\x1a\x8d\x08\x82\x00\x80\ | |
516 | \xb3\xb3s:\x9d\x8e\xce\xa9(h6\x9b8\x8e\x83m\xdb4\x1a\r\x82 \xe0\xc5\xf3g\xb9\ | |
517 | eY\xb4\xdbm\x1c\xc7Y\xe8\x81&\xf8\xf4\xf1C\xde\xedv+\xce\x97Owx\xfc\xe8k\xc5\ | |
518 | \xb6\xb7\xb7\x8b\xef\x0foW \x84\xe0\xea\xea\x02\xa5\x94n\x18\x80\x94\x92\xd9\ | |
519 | l\x02@\x96e\x95>\xd4nVO\xd3\xb9\x0e\xba\r\xa6i\xd2\xef\xf7\xf0\xfd!\xc7G\x87\ | |
520 | y\xed:)\xd5\x01J\xfd\xd6c\xfc~\x9a\xfc\x93\xe8\xf2\xf2\x02(Ma6\x9b \x84@)\ | |
521 | \xa5\t}\xff\x0b\xd0\'I~R\x14\xca\xb2L\xfb\x97\x97\xef-\xeeA!_J\x89\xeb\xba\ | |
522 | \xb8\xae\xab\xbf\x06\x7f\x97\xacP[\x87\xeb9\x0b!H\x92\ta\x18"\xa5\xd4U\xbd\ | |
523 | \xadm\xe3\xe1\x83\x8d<\x8a~\x90\xa6\xbf\x88\xe3\x18)\xa5&\xa9\x03X\x96E\xab\ | |
524 | \xb5\x8em7\xf5\xc2\x94\xb1\xba\xba\xc6\xe6\xe6\x06++\xf7\x89\xa2\xa8\xe2\xd3\ | |
525 | =89\xf9Va.\x14\x14\xd8\xdf?X VJa\x14\xd7X\xde\xef2\xbc\xadm\xe3\x7f~\xe3\xae\ | |
526 | \xe7\xfc\x07\x84;\xc5\x82\xa1m&\x95\x00\x00\x00\x00IEND\xaeB`\x82' | |
d1dc2b32 RD |
527 | |
528 | ||
529 | def getFindBitmap(): | |
530 | return BitmapFromImage(getFindImage()) | |
531 | ||
532 | ||
533 | def getFindImage(): | |
534 | stream = cStringIO.StringIO(getFindData()) | |
535 | return ImageFromStream(stream) | |
536 |