]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/pydocview/FindService.py
1 #----------------------------------------------------------------------------
3 # Purpose: Find Service for pydocview
5 # Author: Peter Yared, Morgan Hua
9 # Copyright: (c) 2003-2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
15 import wx
.lib
.pydocview
20 #----------------------------------------------------------------------------
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"
37 #----------------------------------------------------------------------------
39 #----------------------------------------------------------------------------
41 class FindService(wx
.lib
.pydocview
.DocService
):
43 #----------------------------------------------------------------------------
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
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
61 self
._replaceDialog
= None
62 self
._findDialog
= None
63 self
._findReplaceData
= wx
.FindReplaceData()
64 self
._findReplaceData
.SetFlags(wx
.FR_DOWN
)
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
)
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)
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
)
98 def ProcessUpdateUIEvent(self
, event
):
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
):
111 def ShowFindReplaceDialog(self
, findString
="", replace
= False):
112 """ Display find/replace dialog box.
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.
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
123 self
._replaceDialog
= FindReplaceDialog(self
.GetDocumentManager().FindSuitableParent(), -1, _("Replace"), size
=(320,200), findString
=findString
)
124 self
._replaceDialog
.CenterOnParent()
125 self
._replaceDialog
.Show(True)
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
132 self
._findDialog
= FindDialog(self
.GetDocumentManager().FindSuitableParent(), -1, _("Find"), size
=(320,200), findString
=findString
)
133 self
._findDialog
.CenterOnParent()
134 self
._findDialog
.Show(True)
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
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
153 def GetLineNumber(self
, parent
):
154 """ Display Goto Line Number dialog box """
156 dialog
= wx
.TextEntryDialog(parent
, _("Enter line number to go to:"), _("Go to Line"))
157 dialog
.CenterOnParent()
158 if dialog
.ShowModal() == wx
.ID_OK
:
160 line
= int(dialog
.GetValue())
166 # This one is ugly: wx.GetNumberFromUser("", _("Enter line number to go to:"), _("Go to Line"), 1, min = 1, max = 65535, parent = parent)
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.
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
183 pattern
= re
.escape(findString
) # Treat the strings as a literal string
185 flags
= re
.IGNORECASE
187 pattern
= r
"\b%s\b" % pattern
190 reg
= re
.compile(pattern
, flags
)
192 # syntax error of some sort
194 msgTitle
= wx
.GetApp().GetAppName()
196 msgTitle
= _("Regular Expression Search")
197 wx
.MessageBox(_("Invalid regular expression \"%s\". %s") % (pattern
, sys
.exc_value
),
199 wx
.OK | wx
.ICON_EXCLAMATION
,
201 return FIND_SYNTAXERROR
, None, None, None
204 newText
, count
= reg
.subn(replaceString
, text
)
206 return -1, None, None, None
208 return count
, None, None, newText
212 match
= reg
.search(text
, endLoc
)
214 if wrap
: # try again, but this time from top of file
215 match
= reg
.search(text
, 0)
217 return -1, None, None, None
219 return -1, None, None, None
220 start
= match
.start()
223 match
= reg
.search(text
)
225 return -1, None, None, None
228 while i
< startLoc
and j
<= startLoc
:
232 match
= reg
.search(text
, j
)
237 if wrap
: # try again, but this time from bottom of file
238 match
= reg
.search(text
, startLoc
)
240 return -1, None, None, None
244 while i
< end
and j
<= end
:
248 match
= reg
.search(text
, j
)
253 return -1, None, None, None
255 return -1, None, None, None
256 start
= found
.start()
259 if replace
and start
!= -1:
260 newText
, count
= reg
.subn(replaceString
, text
, 1)
261 return count
, start
, end
, newText
263 return 0, start
, end
, None
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.
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
277 config
= wx
.ConfigBase_Get()
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
)
285 config
.WriteInt(FIND_MATCHREGEXPR
, regExpr
)
287 config
.WriteInt(FIND_MATCHWRAP
, wrap
)
289 config
.WriteInt(FIND_MATCHUPDOWN
, upDown
)
292 def GetFindString(self
):
293 """ Load the search pattern from registry """
294 return wx
.ConfigBase_Get().Read(FIND_MATCHPATTERN
, "")
297 def GetReplaceString(self
):
298 """ Load the replace pattern from registry """
299 return wx
.ConfigBase_Get().Read(FIND_MATCHREPLACE
, "")
303 """ Load search parameters from registry """
304 config
= wx
.ConfigBase_Get()
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
320 class FindDialog(wx
.Dialog
):
321 """ Find Dialog with regular expression matching and wrap to top/bottom of file. """
323 def __init__(self
, parent
, id, title
, size
, findString
=None):
324 wx
.Dialog
.__init
__(self
, parent
, id, title
, size
=size
)
326 config
= wx
.ConfigBase_Get()
327 borderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
328 gridSizer
= wx
.GridBagSizer(SPACE
, SPACE
)
330 lineSizer
= wx
.BoxSizer(wx
.HORIZONTAL
)
331 lineSizer
.Add(wx
.StaticText(self
, -1, _("Find what:")), 0, wx
.ALIGN_CENTER_VERTICAL|wx
.RIGHT
, SPACE
)
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))
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))
356 buttonSizer
= wx
.BoxSizer(wx
.VERTICAL
)
357 findBtn
= wx
.Button(self
, FindService
.FINDONE_ID
, _("Find Next"))
359 wx
.EVT_BUTTON(self
, FindService
.FINDONE_ID
, self
.OnActionEvent
)
360 cancelBtn
= wx
.Button(self
, wx
.ID_CANCEL
)
361 wx
.EVT_BUTTON(self
, wx
.ID_CANCEL
, self
.OnClose
)
362 BTM_SPACE
= HALF_SPACE
363 if wx
.Platform
== "__WXMAC__":
365 buttonSizer
.Add(findBtn
, 0, wx
.BOTTOM
, BTM_SPACE
)
366 buttonSizer
.Add(cancelBtn
, 0)
367 gridSizer
.Add(buttonSizer
, pos
=(0,2), span
=(3,1))
369 borderSizer
.Add(gridSizer
, 0, wx
.ALL
, SPACE
)
371 self
.Bind(wx
.EVT_CLOSE
, self
.OnClose
)
373 self
.SetSizer(borderSizer
)
375 self
._findCtrl
.SetFocus()
377 def SaveConfig(self
):
378 """ Save find patterns and search flags to registry. """
379 findService
= wx
.GetApp().GetService(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(),
395 def OnClose(self
, event
):
396 findService
= wx
.GetApp().GetService(FindService
)
398 findService
.OnFindClose(event
)
402 def OnActionEvent(self
, event
):
405 if wx
.GetApp().GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_MDI
:
406 if wx
.GetApp().GetTopWindow().ProcessEvent(event
):
409 view
= wx
.GetApp().GetDocumentManager().GetLastActiveView()
410 if view
and view
.ProcessEvent(event
):
415 class FindReplaceDialog(FindDialog
):
416 """ Find/Replace Dialog with regular expression matching and wrap to top/bottom of file. """
418 def __init__(self
, parent
, id, title
, size
, findString
=None):
419 wx
.Dialog
.__init
__(self
, parent
, id, title
, size
=size
)
421 config
= wx
.ConfigBase_Get()
422 borderSizer
= wx
.BoxSizer(wx
.VERTICAL
)
423 gridSizer
= wx
.GridBagSizer(SPACE
, SPACE
)
425 gridSizer2
= wx
.GridBagSizer(SPACE
, SPACE
)
426 gridSizer2
.Add(wx
.StaticText(self
, -1, _("Find what:")), flag
=wx
.ALIGN_CENTER_VERTICAL
, pos
=(0,0))
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))
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))
454 buttonSizer
= wx
.BoxSizer(wx
.VERTICAL
)
455 findBtn
= wx
.Button(self
, FindService
.FINDONE_ID
, _("Find Next"))
457 wx
.EVT_BUTTON(self
, FindService
.FINDONE_ID
, self
.OnActionEvent
)
458 cancelBtn
= wx
.Button(self
, wx
.ID_CANCEL
)
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
)
465 BTM_SPACE
= HALF_SPACE
466 if wx
.Platform
== "__WXMAC__":
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
)
472 buttonSizer
.Add(cancelBtn
, 0)
473 gridSizer
.Add(buttonSizer
, pos
=(0,2), span
=(3,1))
475 borderSizer
.Add(gridSizer
, 0, wx
.ALL
, SPACE
)
477 self
.Bind(wx
.EVT_CLOSE
, self
.OnClose
)
479 self
.SetSizer(borderSizer
)
481 self
._findCtrl
.SetFocus()
484 def SaveConfig(self
):
485 """ Save find/replace patterns and search flags to registry. """
486 findService
= wx
.GetApp().GetService(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()
498 #----------------------------------------------------------------------------
499 # Menu Bitmaps - generated by encode_bitmaps.py
500 #----------------------------------------------------------------------------
501 from wx
import ImageFromStream
, BitmapFromImage
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\
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'
530 return BitmapFromImage(getFindImage())
534 stream
= cStringIO
.StringIO(getFindData())
535 return ImageFromStream(stream
)