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