]>
Commit | Line | Data |
---|---|---|
1f780e48 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$ | |
9 | # Copyright: (c) 2003-2005 ActiveGrid, Inc. | |
10 | # License: wxWindows License | |
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() | |
100 | if id == FindService.FIND_ID: | |
101 | event.Enable(False) | |
102 | return True | |
103 | elif id == FindService.FIND_PREVIOUS_ID: | |
104 | event.Enable(False) | |
105 | return True | |
106 | elif id == FindService.FIND_NEXT_ID: | |
107 | event.Enable(False) | |
108 | return True | |
109 | elif id == FindService.REPLACE_ID: | |
110 | event.Enable(False) | |
111 | return True | |
112 | elif id == FindService.GOTO_LINE_ID: | |
113 | event.Enable(False) | |
114 | return True | |
115 | else: | |
116 | return False | |
117 | ||
118 | ||
119 | def ShowFindReplaceDialog(self, findString="", replace = False): | |
120 | """ Display find/replace dialog box. | |
121 | ||
122 | Parameters: findString is the default value shown in the find/replace dialog input field. | |
123 | If replace is True, the replace dialog box is shown, otherwise only the find dialog box is shown. | |
124 | """ | |
125 | if replace: | |
126 | if self._findDialog != None: | |
127 | # No reason to have both find and replace dialogs up at the same time | |
128 | self._findDialog.DoClose() | |
129 | self._findDialog = None | |
130 | ||
131 | self._replaceDialog = FindReplaceDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Replace"), size=(320,200), findString=findString) | |
132 | self._replaceDialog.Show(True) | |
133 | else: | |
134 | if self._replaceDialog != None: | |
135 | # No reason to have both find and replace dialogs up at the same time | |
136 | self._replaceDialog.DoClose() | |
137 | self._replaceDialog = None | |
138 | ||
139 | self._findDialog = FindDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Find"), size=(320,200), findString=findString) | |
140 | self._findDialog.Show(True) | |
141 | ||
142 | ||
143 | ||
144 | def OnFindClose(self, event): | |
145 | """ Cleanup handles when find/replace dialog is closed """ | |
146 | if self._findDialog != None: | |
147 | self._findDialog = None | |
148 | elif self._replaceDialog != None: | |
149 | self._replaceDialog = None | |
150 | ||
151 | ||
152 | def GetCurrentDialog(self): | |
153 | """ return handle to either the find or replace dialog """ | |
154 | if self._findDialog != None: | |
155 | return self._findDialog | |
156 | return self._replaceDialog | |
157 | ||
158 | ||
159 | def GetLineNumber(self, parent): | |
160 | """ Display Goto Line Number dialog box """ | |
161 | line = -1 | |
162 | dialog = wx.TextEntryDialog(parent, _("Enter line number to go to:"), _("Go to Line")) | |
163 | if dialog.ShowModal() == wx.ID_OK: | |
164 | try: | |
165 | line = int(dialog.GetValue()) | |
166 | if line > 65535: | |
167 | line = 65535 | |
168 | except: | |
169 | pass | |
170 | dialog.Destroy() | |
171 | # This one is ugly: wx.GetNumberFromUser("", _("Enter line number to go to:"), _("Go to Line"), 1, min = 1, max = 65535, parent = parent) | |
172 | return line | |
173 | ||
174 | ||
175 | def DoFind(self, findString, replaceString, text, startLoc, endLoc, down, matchCase, wholeWord, regExpr = False, replace = False, replaceAll = False, wrap = False): | |
176 | """ Do the actual work of the find/replace. | |
177 | ||
178 | Returns the tuple (count, start, end, newText). | |
179 | count = number of string replacements | |
180 | start = start position of found string | |
181 | end = end position of found string | |
182 | newText = new replaced text | |
183 | """ | |
184 | flags = 0 | |
185 | if regExpr: | |
186 | pattern = findString | |
187 | else: | |
188 | pattern = re.escape(findString) # Treat the strings as a literal string | |
189 | if not matchCase: | |
190 | flags = re.IGNORECASE | |
191 | if wholeWord: | |
192 | pattern = r"\b%s\b" % pattern | |
193 | ||
194 | try: | |
195 | reg = re.compile(pattern, flags) | |
196 | except: | |
197 | # syntax error of some sort | |
198 | import sys | |
199 | msgTitle = wx.GetApp().GetAppName() | |
200 | if not msgTitle: | |
201 | msgTitle = _("Regular Expression Search") | |
202 | wx.MessageBox(_("Invalid regular expression \"%s\". %s") % (pattern, sys.exc_value), | |
203 | msgTitle, | |
204 | wx.OK | wx.ICON_EXCLAMATION, | |
205 | self.GetView()) | |
206 | return FIND_SYNTAXERROR, None, None, None | |
207 | ||
208 | if replaceAll: | |
209 | newText, count = reg.subn(replaceString, text) | |
210 | if count == 0: | |
211 | return -1, None, None, None | |
212 | else: | |
213 | return count, None, None, newText | |
214 | ||
215 | start = -1 | |
216 | if down: | |
217 | match = reg.search(text, endLoc) | |
218 | if match == None: | |
219 | if wrap: # try again, but this time from top of file | |
220 | match = reg.search(text, 0) | |
221 | if match == None: | |
222 | return -1, None, None, None | |
223 | else: | |
224 | return -1, None, None, None | |
225 | start = match.start() | |
226 | end = match.end() | |
227 | else: | |
228 | match = reg.search(text) | |
229 | if match == None: | |
230 | return -1, None, None, None | |
231 | found = None | |
232 | i, j = match.span() | |
233 | while i < startLoc and j <= startLoc: | |
234 | found = match | |
235 | if i == j: | |
236 | j = j + 1 | |
237 | match = reg.search(text, j) | |
238 | if match == None: | |
239 | break | |
240 | i, j = match.span() | |
241 | if found == None: | |
242 | if wrap: # try again, but this time from bottom of file | |
243 | match = reg.search(text, startLoc) | |
244 | if match == None: | |
245 | return -1, None, None, None | |
246 | found = None | |
247 | i, j = match.span() | |
248 | end = len(text) | |
249 | while i < end and j <= end: | |
250 | found = match | |
251 | if i == j: | |
252 | j = j + 1 | |
253 | match = reg.search(text, j) | |
254 | if match == None: | |
255 | break | |
256 | i, j = match.span() | |
257 | if found == None: | |
258 | return -1, None, None, None | |
259 | else: | |
260 | return -1, None, None, None | |
261 | start = found.start() | |
262 | end = found.end() | |
263 | ||
264 | if replace and start != -1: | |
265 | newText, count = reg.subn(replaceString, text, 1) | |
266 | return count, start, end, newText | |
267 | ||
268 | return 0, start, end, None | |
269 | ||
270 | ||
271 | def SaveFindConfig(self, findString, wholeWord, matchCase, regExpr = None, wrap = None, upDown = None, replaceString = None): | |
272 | """ Save find/replace patterns and search flags to registry. | |
273 | ||
274 | findString = search pattern | |
275 | wholeWord = match whole word only | |
276 | matchCase = match case | |
277 | regExpr = use regular expressions in search pattern | |
278 | wrap = return to top/bottom of file on search | |
279 | upDown = search up or down from current cursor position | |
280 | replaceString = replace string | |
281 | """ | |
282 | config = wx.ConfigBase_Get() | |
283 | ||
284 | config.Write(FIND_MATCHPATTERN, findString) | |
285 | config.WriteInt(FIND_MATCHCASE, matchCase) | |
286 | config.WriteInt(FIND_MATCHWHOLEWORD, wholeWord) | |
287 | if replaceString != None: | |
288 | config.Write(FIND_MATCHREPLACE, replaceString) | |
289 | if regExpr != None: | |
290 | config.WriteInt(FIND_MATCHREGEXPR, regExpr) | |
291 | if wrap != None: | |
292 | config.WriteInt(FIND_MATCHWRAP, wrap) | |
293 | if upDown != None: | |
294 | config.WriteInt(FIND_MATCHUPDOWN, upDown) | |
295 | ||
296 | ||
297 | def GetFindString(self): | |
298 | """ Load the search pattern from registry """ | |
299 | return wx.ConfigBase_Get().Read(FIND_MATCHPATTERN, "") | |
300 | ||
301 | ||
302 | def GetReplaceString(self): | |
303 | """ Load the replace pattern from registry """ | |
304 | return wx.ConfigBase_Get().Read(FIND_MATCHREPLACE, "") | |
305 | ||
306 | ||
307 | def GetFlags(self): | |
308 | """ Load search parameters from registry """ | |
309 | config = wx.ConfigBase_Get() | |
310 | ||
311 | flags = 0 | |
312 | if config.ReadInt(FIND_MATCHWHOLEWORD, False): | |
313 | flags = flags | wx.FR_WHOLEWORD | |
314 | if config.ReadInt(FIND_MATCHCASE, False): | |
315 | flags = flags | wx.FR_MATCHCASE | |
316 | if config.ReadInt(FIND_MATCHUPDOWN, False): | |
317 | flags = flags | wx.FR_DOWN | |
318 | if config.ReadInt(FIND_MATCHREGEXPR, False): | |
319 | flags = flags | FindService.FR_REGEXP | |
320 | if config.ReadInt(FIND_MATCHWRAP, False): | |
321 | flags = flags | FindService.FR_WRAP | |
322 | return flags | |
323 | ||
324 | ||
325 | class FindDialog(wx.Dialog): | |
326 | """ Find Dialog with regular expression matching and wrap to top/bottom of file. """ | |
327 | ||
328 | def __init__(self, parent, id, title, size, findString=None): | |
329 | wx.Dialog.__init__(self, parent, id, title, size=size) | |
330 | ||
331 | config = wx.ConfigBase_Get() | |
332 | borderSizer = wx.BoxSizer(wx.VERTICAL) | |
333 | gridSizer = wx.GridBagSizer(SPACE, SPACE) | |
334 | ||
335 | lineSizer = wx.BoxSizer(wx.HORIZONTAL) | |
336 | lineSizer.Add(wx.StaticText(self, -1, _("Find what:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, SPACE) | |
337 | if not findString: | |
338 | findString = config.Read(FIND_MATCHPATTERN, "") | |
339 | self._findCtrl = wx.TextCtrl(self, -1, findString, size=(200,-1)) | |
340 | lineSizer.Add(self._findCtrl, 0) | |
341 | gridSizer.Add(lineSizer, pos=(0,0), span=(1,2)) | |
342 | choiceSizer = wx.BoxSizer(wx.VERTICAL) | |
343 | self._wholeWordCtrl = wx.CheckBox(self, -1, _("Match whole word only")) | |
344 | self._wholeWordCtrl.SetValue(config.ReadInt(FIND_MATCHWHOLEWORD, False)) | |
345 | self._matchCaseCtrl = wx.CheckBox(self, -1, _("Match case")) | |
346 | self._matchCaseCtrl.SetValue(config.ReadInt(FIND_MATCHCASE, False)) | |
347 | self._regExprCtrl = wx.CheckBox(self, -1, _("Regular expression")) | |
348 | self._regExprCtrl.SetValue(config.ReadInt(FIND_MATCHREGEXPR, False)) | |
349 | self._wrapCtrl = wx.CheckBox(self, -1, _("Wrap")) | |
350 | self._wrapCtrl.SetValue(config.ReadInt(FIND_MATCHWRAP, False)) | |
351 | choiceSizer.Add(self._wholeWordCtrl, 0, wx.BOTTOM, SPACE) | |
352 | choiceSizer.Add(self._matchCaseCtrl, 0, wx.BOTTOM, SPACE) | |
353 | choiceSizer.Add(self._regExprCtrl, 0, wx.BOTTOM, SPACE) | |
354 | choiceSizer.Add(self._wrapCtrl, 0) | |
355 | gridSizer.Add(choiceSizer, pos=(1,0), span=(2,1)) | |
356 | ||
357 | self._radioBox = wx.RadioBox(self, -1, _("Direction"), choices = ["Up", "Down"]) | |
358 | self._radioBox.SetSelection(config.ReadInt(FIND_MATCHUPDOWN, 1)) | |
359 | gridSizer.Add(self._radioBox, pos=(1,1), span=(2,1)) | |
360 | ||
361 | buttonSizer = wx.BoxSizer(wx.VERTICAL) | |
362 | findBtn = wx.Button(self, FindService.FINDONE_ID, _("Find Next")) | |
363 | findBtn.SetDefault() | |
364 | wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent) | |
365 | cancelBtn = wx.Button(self, wx.ID_CANCEL, _("Cancel")) | |
366 | wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnClose) | |
367 | buttonSizer.Add(findBtn, 0, wx.BOTTOM, HALF_SPACE) | |
368 | buttonSizer.Add(cancelBtn, 0) | |
369 | gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1)) | |
370 | ||
371 | borderSizer.Add(gridSizer, 0, wx.ALL, SPACE) | |
372 | ||
373 | self.Bind(wx.EVT_CLOSE, self.OnClose) | |
374 | ||
375 | self.SetSizer(borderSizer) | |
376 | self.Fit() | |
377 | self._findCtrl.SetFocus() | |
378 | ||
379 | def SaveConfig(self): | |
380 | """ Save find patterns and search flags to registry. """ | |
381 | findService = wx.GetApp().GetService(FindService) | |
382 | if findService: | |
383 | findService.SaveFindConfig(self._findCtrl.GetValue(), | |
384 | self._wholeWordCtrl.IsChecked(), | |
385 | self._matchCaseCtrl.IsChecked(), | |
386 | self._regExprCtrl.IsChecked(), | |
387 | self._wrapCtrl.IsChecked(), | |
388 | self._radioBox.GetSelection(), | |
389 | ) | |
390 | ||
391 | ||
392 | def DoClose(self): | |
393 | self.SaveConfig() | |
394 | self.Destroy() | |
395 | ||
396 | ||
397 | def OnClose(self, event): | |
398 | findService = wx.GetApp().GetService(FindService) | |
399 | if findService: | |
400 | findService.OnFindClose(event) | |
401 | self.DoClose() | |
402 | ||
403 | ||
404 | def OnActionEvent(self, event): | |
405 | self.SaveConfig() | |
406 | ||
407 | if wx.GetApp().GetDocumentManager().GetFlags() & wx.lib.docview.DOC_MDI: | |
408 | if wx.GetApp().GetTopWindow().ProcessEvent(event): | |
409 | return True | |
410 | else: | |
411 | view = wx.GetApp().GetDocumentManager().GetLastActiveView() | |
412 | if view and view.ProcessEvent(event): | |
413 | return True | |
414 | return False | |
415 | ||
416 | ||
417 | class FindReplaceDialog(FindDialog): | |
418 | """ Find/Replace Dialog with regular expression matching and wrap to top/bottom of file. """ | |
419 | ||
420 | def __init__(self, parent, id, title, size, findString=None): | |
421 | wx.Dialog.__init__(self, parent, id, title, size=size) | |
422 | ||
423 | config = wx.ConfigBase_Get() | |
424 | borderSizer = wx.BoxSizer(wx.VERTICAL) | |
425 | gridSizer = wx.GridBagSizer(SPACE, SPACE) | |
426 | ||
427 | gridSizer2 = wx.GridBagSizer(SPACE, SPACE) | |
428 | gridSizer2.Add(wx.StaticText(self, -1, _("Find what:")), flag=wx.ALIGN_CENTER_VERTICAL, pos=(0,0)) | |
429 | if not findString: | |
430 | findString = config.Read(FIND_MATCHPATTERN, "") | |
431 | self._findCtrl = wx.TextCtrl(self, -1, findString, size=(200,-1)) | |
432 | gridSizer2.Add(self._findCtrl, pos=(0,1)) | |
433 | gridSizer2.Add(wx.StaticText(self, -1, _("Replace with:")), flag=wx.ALIGN_CENTER_VERTICAL, pos=(1,0)) | |
434 | self._replaceCtrl = wx.TextCtrl(self, -1, config.Read(FIND_MATCHREPLACE, ""), size=(200,-1)) | |
435 | gridSizer2.Add(self._replaceCtrl, pos=(1,1)) | |
436 | gridSizer.Add(gridSizer2, pos=(0,0), span=(1,2)) | |
437 | choiceSizer = wx.BoxSizer(wx.VERTICAL) | |
438 | self._wholeWordCtrl = wx.CheckBox(self, -1, _("Match whole word only")) | |
439 | self._wholeWordCtrl.SetValue(config.ReadInt(FIND_MATCHWHOLEWORD, False)) | |
440 | self._matchCaseCtrl = wx.CheckBox(self, -1, _("Match case")) | |
441 | self._matchCaseCtrl.SetValue(config.ReadInt(FIND_MATCHCASE, False)) | |
442 | self._regExprCtrl = wx.CheckBox(self, -1, _("Regular expression")) | |
443 | self._regExprCtrl.SetValue(config.ReadInt(FIND_MATCHREGEXPR, False)) | |
444 | self._wrapCtrl = wx.CheckBox(self, -1, _("Wrap")) | |
445 | self._wrapCtrl.SetValue(config.ReadInt(FIND_MATCHWRAP, False)) | |
446 | choiceSizer.Add(self._wholeWordCtrl, 0, wx.BOTTOM, SPACE) | |
447 | choiceSizer.Add(self._matchCaseCtrl, 0, wx.BOTTOM, SPACE) | |
448 | choiceSizer.Add(self._regExprCtrl, 0, wx.BOTTOM, SPACE) | |
449 | choiceSizer.Add(self._wrapCtrl, 0) | |
450 | gridSizer.Add(choiceSizer, pos=(1,0), span=(2,1)) | |
451 | ||
452 | self._radioBox = wx.RadioBox(self, -1, _("Direction"), choices = ["Up", "Down"]) | |
453 | self._radioBox.SetSelection(config.ReadInt(FIND_MATCHUPDOWN, 1)) | |
454 | gridSizer.Add(self._radioBox, pos=(1,1), span=(2,1)) | |
455 | ||
456 | buttonSizer = wx.BoxSizer(wx.VERTICAL) | |
457 | findBtn = wx.Button(self, FindService.FINDONE_ID, _("Find Next")) | |
458 | findBtn.SetDefault() | |
459 | wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent) | |
460 | cancelBtn = wx.Button(self, wx.ID_CANCEL, _("Cancel")) | |
461 | wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnClose) | |
462 | replaceBtn = wx.Button(self, FindService.REPLACEONE_ID, _("Replace")) | |
463 | wx.EVT_BUTTON(self, FindService.REPLACEONE_ID, self.OnActionEvent) | |
464 | replaceAllBtn = wx.Button(self, FindService.REPLACEALL_ID, _("Replace All")) | |
465 | wx.EVT_BUTTON(self, FindService.REPLACEALL_ID, self.OnActionEvent) | |
466 | buttonSizer.Add(findBtn, 0, wx.BOTTOM, HALF_SPACE) | |
467 | buttonSizer.Add(replaceBtn, 0, wx.BOTTOM, HALF_SPACE) | |
468 | buttonSizer.Add(replaceAllBtn, 0, wx.BOTTOM, HALF_SPACE) | |
469 | buttonSizer.Add(cancelBtn, 0) | |
470 | gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1)) | |
471 | ||
472 | borderSizer.Add(gridSizer, 0, wx.ALL, SPACE) | |
473 | ||
474 | self.Bind(wx.EVT_CLOSE, self.OnClose) | |
475 | ||
476 | self.SetSizer(borderSizer) | |
477 | self.Fit() | |
478 | self._findCtrl.SetFocus() | |
479 | ||
480 | ||
481 | def SaveConfig(self): | |
482 | """ Save find/replace patterns and search flags to registry. """ | |
483 | findService = wx.GetApp().GetService(FindService) | |
484 | if findService: | |
485 | findService.SaveFindConfig(self._findCtrl.GetValue(), | |
486 | self._wholeWordCtrl.IsChecked(), | |
487 | self._matchCaseCtrl.IsChecked(), | |
488 | self._regExprCtrl.IsChecked(), | |
489 | self._wrapCtrl.IsChecked(), | |
490 | self._radioBox.GetSelection(), | |
491 | self._replaceCtrl.GetValue() | |
492 | ) | |
493 | ||
494 | ||
495 | #---------------------------------------------------------------------------- | |
496 | # Menu Bitmaps - generated by encode_bitmaps.py | |
497 | #---------------------------------------------------------------------------- | |
498 | from wx import ImageFromStream, BitmapFromImage | |
499 | import cStringIO | |
500 | ||
501 | ||
502 | def getFindData(): | |
503 | return \ | |
504 | '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ | |
505 | \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ | |
506 | \x00\x00\x81IDAT8\x8d\xa5S\xc1\x16\xc0\x10\x0ckk\xff\xff\xc7d\x87\xad^U\r\ | |
507 | \x93S\xe5U$\n\xb3$:\xc1e\x17(\x19Z\xb3$\x9e\xf1DD\xe2\x15\x01x\xea\x93\xef\ | |
508 | \x04\x989\xea\x1b\xf2U\xc0\xda\xb4\xeb\x11\x1f:\xd8\xb5\xff8\x93\xd4\xa9\xae\ | |
509 | @/S\xaaUwJ3\x85\xc0\x81\xee\xeb.q\x17C\x81\xd5XU \x1a\x93\xc6\x18\x8d\x90\ | |
510 | \xe8}\x89\x00\x9a&\x9b_k\x94\x0c\xdf\xd78\xf8\x0b\x99Y\xb4\x08c\x9e\xfe\xc6\ | |
511 | \xe3\x087\xf9\xd0D\x180\xf1#\x8e\x00\x00\x00\x00IEND\xaeB`\x82' | |
512 | ||
513 | ||
514 | def getFindBitmap(): | |
515 | return BitmapFromImage(getFindImage()) | |
516 | ||
517 | ||
518 | def getFindImage(): | |
519 | stream = cStringIO.StringIO(getFindData()) | |
520 | return ImageFromStream(stream) | |
521 |