]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/mixins/inspect.py
The inspect module is now a widget browser plus a shell.
[wxWidgets.git] / wxPython / wx / lib / mixins / inspect.py
1 #----------------------------------------------------------------------------
2 # Name: wx.lib.mixins.inspect
3 # Purpose: A mix-in class that can add PyCrust-based inspection of the
4 # app's widgets and sizers.
5 #
6 # Author: Robin Dunn
7 #
8 # Created: 21-Nov-2006
9 # RCS-ID: $Id$
10 # Copyright: (c) 2006 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------------
13
14 # NOTE: This class was originally based on ideas sent to the
15 # wxPython-users mail list by Dan Eloff.
16
17 import wx
18 import wx.py
19 import wx.stc
20 import sys
21
22
23 class InspectionMixin(object):
24 """
25 This class is intended to be used as a mix-in with the wx.App
26 class. When used it will add the ability to popup a
27 InspectionFrame window where the widget under the mouse cursor
28 will be selected in the tree and loaded into the shell's namespace
29 as 'obj'. The default key sequence to activate the inspector is
30 Ctrl-Alt-I (or Cmd-Alt-I on Mac) but this can be changed via
31 parameters to the `Init` method, or the application can call
32 `ShowInspectionTool` from other event handlers if desired.
33
34 To use this class simply derive a class from wx.App and
35 InspectionMixin and then call the `Init` method from the app's
36 OnInit.
37 """
38 def Init(self, pos=(-1, -1), size=(850,700), config=None, locals=None,
39 alt=True, cmd=True, shift=False, keyCode=ord('I')):
40 """
41 Make the event binding that will activate the InspectionFrame window.
42 """
43 self.Bind(wx.EVT_KEY_DOWN, self._OnKeyPress)
44 self._tool = None
45 self._pos = pos
46 self._size = size
47 self._config = config
48 self._locals = locals
49 self._alt = alt
50 self._cmd = cmd
51 self._shift = shift
52 self._keyCode = keyCode
53
54
55 def _OnKeyPress(self, evt):
56 """
57 Event handler, check for our hot-key. Normally it is
58 Ctrl-Alt-I but that can be changed by what is passed to the
59 Init method.
60 """
61 if evt.AltDown() == self._alt and \
62 evt.CmdDown() == self._cmd and \
63 evt.ShiftDown() == self._shift and \
64 evt.GetKeyCode() == self._keyCode:
65 self.ShowInspectionTool()
66 else:
67 evt.Skip()
68
69
70 def ShowInspectionTool(self):
71 """
72 Show the Inspection tool, creating it if neccesary.
73 """
74 if not self._tool:
75 self._tool = InspectionFrame(parent=self.GetTopWindow(),
76 pos=self._pos,
77 size=self._size,
78 config=self._config,
79 locals=self._locals,
80 app=self)
81 # get the current widget under the mouse
82 wnd = wx.FindWindowAtPointer()
83 self._tool.SetObj(wnd)
84
85 self._tool.Show()
86 self._tool.Raise()
87
88
89 #---------------------------------------------------------------------------
90
91 class InspectionFrame(wx.Frame):
92 """
93 This class is the frame that holds the wxPython inspection tools.
94 The toolbar and splitter windows are also managed here. The
95 contents of the splitter windows are handled by other classes.
96 """
97 def __init__(self, wnd=None, locals=None, config=None,
98 app=None, title="wxPython Widget Inspection Tool",
99 *args, **kw):
100 kw['title'] = title
101 wx.Frame.__init__(self, *args, **kw)
102
103 self.includeSizers = False
104 self.started = False
105
106 self.MakeToolBar()
107
108 self.outerSplitter = wx.SplitterWindow(self,style=wx.SP_3D|wx.SP_LIVE_UPDATE)
109 self.innerSplitter = wx.SplitterWindow(self.outerSplitter,style=wx.SP_3D|wx.SP_LIVE_UPDATE)
110 self.tree = InspectionTree(self.outerSplitter)
111 self.info = InspectionInfoPanel(self.innerSplitter)
112
113 if not locals:
114 locals = {}
115 myIntroText = (
116 "Python %s on %s\nNOTE: The 'obj' variable refers to the selected object."
117 % (sys.version.split()[0], sys.platform))
118 self.crust = wx.py.crust.Crust(self.innerSplitter, locals=locals,
119 intro=myIntroText,
120 showInterpIntro=False,
121 )
122 self.locals = self.crust.shell.interp.locals
123 self.crust.shell.interp.introText = ''
124 self.locals['obj'] = self.obj = wnd
125 self.locals['app'] = app
126 self.locals['wx'] = wx
127 wx.CallAfter(self._postStartup)
128
129 self.innerSplitter.SplitHorizontally(self.info, self.crust, -225)
130 self.outerSplitter.SplitVertically(self.tree, self.innerSplitter, 280)
131 self.outerSplitter.SetMinimumPaneSize(20)
132 self.innerSplitter.SetMinimumPaneSize(20)
133
134
135 def MakeToolBar(self):
136 tbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.TB_FLAT | wx.TB_TEXT | wx.NO_BORDER )
137 tbar.SetToolBitmapSize((20,20))
138
139 refreshBmp = getRefreshBitmap()
140 findWidgetBmp = getFindBitmap()
141 showSizersBmp = getShowSizersBitmap()
142 toggleFillingBmp = getShowFillingBitmap()
143
144 refreshTool = tbar.AddLabelTool(-1, 'Refresh', refreshBmp,
145 shortHelp = 'Refresh widget tree')
146 findWidgetTool = tbar.AddLabelTool(-1, 'Find', findWidgetBmp,
147 shortHelp='Find new target widget. Click here and\nthen on another widget in the app.')
148 showSizersTool = tbar.AddLabelTool(-1, 'Sizers', showSizersBmp,
149 shortHelp='Include sizers in widget tree',
150 kind=wx.ITEM_CHECK)
151 toggleFillingTool = tbar.AddLabelTool(-1, 'Filling', toggleFillingBmp,
152 shortHelp='Show PyCrust \'filling\'',
153 kind=wx.ITEM_CHECK)
154 tbar.Realize()
155
156 self.Bind(wx.EVT_TOOL, self.OnRefreshTree, refreshTool)
157 self.Bind(wx.EVT_TOOL, self.OnFindWidget, findWidgetTool)
158 self.Bind(wx.EVT_TOOL, self.OnShowSizers, showSizersTool)
159 self.Bind(wx.EVT_TOOL, self.OnToggleFilling, toggleFillingTool)
160 self.Bind(wx.EVT_UPDATE_UI, self.OnShowSizersUI, showSizersTool)
161 self.Bind(wx.EVT_UPDATE_UI, self.OnToggleFillingUI, toggleFillingTool)
162
163
164
165 def _postStartup(self):
166 if self.crust.ToolsShown():
167 self.crust.ToggleTools()
168 self.UpdateInfo()
169 self.started = True
170
171 def UpdateInfo(self):
172 self.info.Update(self.obj)
173
174 def SetObj(self, obj):
175 if self.obj is obj:
176 return
177 self.locals['obj'] = self.obj = obj
178 self.UpdateInfo()
179 if not self.tree.built:
180 self.tree.BuildTree(obj, includeSizers=self.includeSizers)
181 else:
182 self.tree.SelectObj(obj)
183
184
185 def RefreshTree(self):
186 self.tree.BuildTree(self.obj, includeSizers=self.includeSizers)
187
188
189 def OnRefreshTree(self, evt):
190 self.RefreshTree()
191
192
193 def OnFindWidget(self, evt):
194 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
195 self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnCaptureLost)
196 self.CaptureMouse()
197 self.finding = wx.BusyInfo("Click on any widget in the app...")
198
199 def OnCaptureLost(self, evt):
200 self.Unbind(wx.EVT_LEFT_DOWN)
201 self.Unbind(wx.EVT_MOUSE_CAPTURE_LOST)
202 del self.finding
203
204 def OnLeftDown(self, evt):
205 self.ReleaseMouse()
206 wnd = wx.FindWindowAtPointer()
207 if wnd is not None:
208 self.SetObj(wnd)
209 else:
210 wx.Bell()
211 self.OnCaptureLost(evt)
212
213
214 def OnShowSizers(self, evt):
215 self.includeSizers = not self.includeSizers
216 self.RefreshTree()
217
218
219 def OnToggleFilling(self, evt):
220 self.crust.ToggleTools()
221
222
223 def OnShowSizersUI(self, evt):
224 evt.Check(self.includeSizers)
225
226
227 def OnToggleFillingUI(self, evt):
228 if self.started:
229 evt.Check(self.crust.ToolsShown())
230
231
232
233 #---------------------------------------------------------------------------
234
235 # should inspection frame (and children) be includeed in the tree?
236 INCLUDE_INSPECTOR = True
237
238 class InspectionTree(wx.TreeCtrl):
239 """
240 All of the widgets in the app, and optionally their sizers, are
241 loaded into this tree.
242 """
243 def __init__(self, *args, **kw):
244 #s = kw.get('style', 0)
245 #kw['style'] = s | wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT
246 wx.TreeCtrl.__init__(self, *args, **kw)
247 self.roots = []
248 self.built = False
249 self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelectionChanged)
250
251
252 def BuildTree(self, startWidget, includeSizers=False):
253 if self.GetCount():
254 self.DeleteAllItems()
255 self.roots = []
256 self.built = False
257
258 realRoot = self.AddRoot('Top-level Windows')
259
260 for w in wx.GetTopLevelWindows():
261 if w is wx.GetTopLevelParent(self) and not INCLUDE_INSPECTOR:
262 continue
263 root = self._AddWidget(realRoot, w, includeSizers)
264 self.roots.append(root)
265
266 # Expand the subtree containing the startWidget, and select it.
267 if not startWidget or not isinstance(startWidget, wx.Window):
268 startWidget = wx.GetApp().GetTopWindow()
269 top = wx.GetTopLevelParent(startWidget)
270 topItem = self.FindWidgetItem(top)
271 if topItem:
272 self.ExpandAllChildren(topItem)
273 self.SelectObj(startWidget)
274 self.built = True
275
276
277 def _AddWidget(self, parentItem, widget, includeSizers):
278 text = self.GetTextForWidget(widget)
279 item = self.AppendItem(parentItem, text)
280 self.SetItemPyData(item, widget)
281
282 # Add the sizer and widgets in the sizer, if we're showing them
283 widgetsInSizer = []
284 if includeSizers and widget.GetSizer() is not None:
285 widgetsInSizer = self._AddSizer(item, widget.GetSizer())
286
287 # Add any children not in the sizer, or all children if we're
288 # not showing the sizers
289 for child in widget.GetChildren():
290 if not child in widgetsInSizer and not child.IsTopLevel():
291 self._AddWidget(item, child, includeSizers)
292
293 return item
294
295
296 def _AddSizer(self, parentItem, sizer):
297 widgets = []
298 text = self.GetTextForSizer(sizer)
299 item = self.AppendItem(parentItem, text)
300 self.SetItemPyData(item, sizer)
301 self.SetItemTextColour(item, "blue")
302
303 for si in sizer.GetChildren():
304 if si.IsWindow():
305 w = si.GetWindow()
306 self._AddWidget(item, w, True)
307 widgets.append(w)
308 elif si.IsSizer():
309 widgets += self._AddSizer(item, si.GetSizer())
310 else:
311 i = self.AppendItem(item, "Spacer")
312 self.SetItemPyData(i, si)
313 self.SetItemTextColour(i, "blue")
314 return widgets
315
316
317 def FindWidgetItem(self, widget):
318 """
319 Find the tree item for a widget.
320 """
321 for item in self.roots:
322 found = self._FindWidgetItem(widget, item)
323 if found:
324 return found
325 return None
326
327 def _FindWidgetItem(self, widget, item):
328 if self.GetItemPyData(item) is widget:
329 return item
330 child, cookie = self.GetFirstChild(item)
331 while child:
332 found = self._FindWidgetItem(widget, child)
333 if found:
334 return found
335 child, cookie = self.GetNextChild(item, cookie)
336 return None
337
338
339 def GetTextForWidget(self, widget):
340 """
341 Returns the string to be used in the tree for a widget
342 """
343 return "%s (\"%s\")" % (widget.__class__.__name__, widget.GetName())
344
345 def GetTextForSizer(self, sizer):
346 """
347 Returns the string to be used in the tree for a sizer
348 """
349 return "%s" % sizer.__class__.__name__
350
351
352 def SelectObj(self, obj):
353 item = self.FindWidgetItem(obj)
354 if item:
355 self.EnsureVisible(item)
356 self.SelectItem(item)
357
358
359 def OnSelectionChanged(self, evt):
360 obj = self.GetItemPyData(evt.GetItem())
361 toolFrm = wx.GetTopLevelParent(self)
362 toolFrm.SetObj(obj)
363
364
365 #---------------------------------------------------------------------------
366
367 class InspectionInfoPanel(wx.stc.StyledTextCtrl):
368 """
369 Used to display information about the currently selected items.
370 Currently just a read-only wx.stc.StyledTextCtrl with some plain
371 text. Should probably add some styles to make things easier to
372 read.
373 """
374 def __init__(self, *args, **kw):
375 wx.stc.StyledTextCtrl.__init__(self, *args, **kw)
376
377 from wx.py.editwindow import FACES
378 self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT,
379 "face:%(mono)s,size:%(size)d,back:%(backcol)s" % FACES)
380 self.StyleClearAll()
381 self.SetReadOnly(True)
382
383
384 def Update(self, obj):
385 st = []
386 if not obj:
387 st.append("Item is None or has been destroyed.")
388
389 elif isinstance(obj, wx.Window):
390 st += self.FmtWidget(obj)
391
392 elif isinstance(obj, wx.Sizer):
393 st += self.FmtSizer(obj)
394
395 elif isinstance(obj, wx.SizerItem):
396 st += self.FmtSizerItem(obj)
397
398 #self.SetValue('\n'.join(st))
399 self.SetReadOnly(False)
400 self.SetText('\n'.join(st))
401 self.SetReadOnly(True)
402
403
404 def Fmt(self, name, value):
405 if isinstance(value, (str, unicode)):
406 return " %s = '%s'" % (name, value)
407 else:
408 return " %s = %s" % (name, value)
409
410
411 def FmtWidget(self, obj):
412 st = ["Widget:"]
413 st.append(self.Fmt('name', obj.GetName()))
414 st.append(self.Fmt('class', obj.__class__))
415 st.append(self.Fmt('bases', obj.__class__.__bases__))
416 st.append(self.Fmt('id', obj.GetId()))
417 st.append(self.Fmt('style', obj.GetWindowStyle()))
418 st.append(self.Fmt('pos', obj.GetPosition()))
419 st.append(self.Fmt('size', obj.GetSize()))
420 st.append(self.Fmt('minsize', obj.GetMinSize()))
421 st.append(self.Fmt('bestsize', obj.GetBestSize()))
422 st.append(self.Fmt('client size',obj.GetClientSize()))
423 st.append(self.Fmt('IsEnabled', obj.IsEnabled()))
424 st.append(self.Fmt('IsShown', obj.IsShown()))
425 st.append(self.Fmt('fg color', obj.GetForegroundColour()))
426 st.append(self.Fmt('bg color', obj.GetBackgroundColour()))
427 st.append(self.Fmt('label', obj.GetLabel()))
428 if hasattr(obj, 'GetTitle'):
429 st.append(self.Fmt('title', obj.GetTitle()))
430 if hasattr(obj, 'GetValue'):
431 st.append(self.Fmt('value', obj.GetValue()))
432 if obj.GetContainingSizer() is not None:
433 st.append('')
434 sizer = obj.GetContainingSizer()
435 st += self.FmtSizerItem(sizer.GetItem(obj))
436 return st
437
438
439 def FmtSizerItem(self, obj):
440 st = ['SizerItem:']
441 st.append(self.Fmt('proportion', obj.GetProportion()))
442 st.append(self.Fmt('flag',
443 FlagsFormatter(itemFlags, obj.GetFlag())))
444 st.append(self.Fmt('border', obj.GetBorder()))
445 st.append(self.Fmt('pos', obj.GetPosition()))
446 st.append(self.Fmt('size', obj.GetSize()))
447 st.append(self.Fmt('minsize', obj.GetMinSize()))
448 st.append(self.Fmt('ratio', obj.GetRatio()))
449 st.append(self.Fmt('IsWindow', obj.IsWindow()))
450 st.append(self.Fmt('IsSizer', obj.IsSizer()))
451 st.append(self.Fmt('IsSpacer', obj.IsSpacer()))
452 st.append(self.Fmt('IsShown', obj.IsShown()))
453 if isinstance(obj, wx.GBSizerItem):
454 st.append(self.Fmt('cellpos', obj.GetPos()))
455 st.append(self.Fmt('cellspan', obj.GetSpan()))
456 st.append(self.Fmt('endpos', obj.GetEndPos()))
457 return st
458
459
460 def FmtSizer(self, obj):
461 st = ['Sizer:']
462 st.append(self.Fmt('class', obj.__class__))
463 st.append(self.Fmt('pos', obj.GetPosition()))
464 st.append(self.Fmt('size', obj.GetSize()))
465 st.append(self.Fmt('minsize', obj.GetMinSize()))
466 if isinstance(obj, wx.BoxSizer):
467 st.append(self.Fmt('orientation',
468 FlagsFormatter(orientFlags, obj.GetOrientation())))
469 if isinstance(obj, wx.GridSizer):
470 st.append(self.Fmt('cols', obj.GetCols()))
471 st.append(self.Fmt('rows', obj.GetRows()))
472 st.append(self.Fmt('vgap', obj.GetVGap()))
473 st.append(self.Fmt('hgap', obj.GetHGap()))
474 if isinstance(obj, wx.FlexGridSizer):
475 st.append(self.Fmt('rowheights', obj.GetRowHeights()))
476 st.append(self.Fmt('colwidths', obj.GetColWidths()))
477 st.append(self.Fmt('flexdir',
478 FlagsFormatter(orientFlags, obj.GetFlexibleDirection())))
479 st.append(self.Fmt('nonflexmode',
480 FlagsFormatter(flexmodeFlags, obj.GetNonFlexibleGrowMode())))
481 if isinstance(obj, wx.GridBagSizer):
482 st.append(self.Fmt('emptycell', obj.GetEmptyCellSize()))
483
484 if obj.GetContainingWindow():
485 si = obj.GetContainingWindow().GetSizer().GetItem(obj)
486 if si:
487 st.append('')
488 st += self.FmtSizerItem(si)
489 return st
490
491
492 class FlagsFormatter(object):
493 def __init__(self, d, val):
494 self.d = d
495 self.val = val
496
497 def __str__(self):
498 st = []
499 for k in self.d.keys():
500 if self.val & k:
501 st.append(self.d[k])
502 if st:
503 return '|'.join(st)
504 else:
505 return '0'
506
507 orientFlags = {
508 wx.HORIZONTAL : 'wx.HORIZONTAL',
509 wx.VERTICAL : 'wx.VERTICAL',
510 }
511
512 itemFlags = {
513 wx.TOP : 'wx.TOP',
514 wx.BOTTOM : 'wx.BOTTOM',
515 wx.LEFT : 'wx.LEFT',
516 wx.RIGHT : 'wx.RIGHT',
517 # wx.ALL : 'wx.ALL',
518 wx.EXPAND : 'wx.EXPAND',
519 # wx.GROW : 'wx.GROW',
520 wx.SHAPED : 'wx.SHAPED',
521 wx.STRETCH_NOT : 'wx.STRETCH_NOT',
522 wx.ALIGN_CENTER : 'wx.ALIGN_CENTER',
523 wx.ALIGN_LEFT : 'wx.ALIGN_LEFT',
524 wx.ALIGN_RIGHT : 'wx.ALIGN_RIGHT',
525 wx.ALIGN_TOP : 'wx.ALIGN_TOP',
526 wx.ALIGN_BOTTOM : 'wx.ALIGN_BOTTOM',
527 wx.ALIGN_CENTER_VERTICAL : 'wx.ALIGN_CENTER_VERTICAL',
528 wx.ALIGN_CENTER_HORIZONTAL : 'wx.ALIGN_CENTER_HORIZONTAL',
529 wx.ADJUST_MINSIZE : 'wx.ADJUST_MINSIZE',
530 wx.FIXED_MINSIZE : 'wx.FIXED_MINSIZE',
531 }
532
533 flexmodeFlags = {
534 wx.FLEX_GROWMODE_NONE : 'wx.FLEX_GROWMODE_NONE',
535 wx.FLEX_GROWMODE_SPECIFIED : 'wx.FLEX_GROWMODE_SPECIFIED',
536 wx.FLEX_GROWMODE_ALL : 'wx.FLEX_GROWMODE_ALL',
537 }
538
539 #---------------------------------------------------------------------------
540 from wx import ImageFromStream, BitmapFromImage
541 import cStringIO
542
543
544 def getRefreshData():
545 return \
546 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\x08\x06\
547 \x00\x00\x00\x8d\x89\x1d\r\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
548 \x00\x02TIDAT8\x8d\x9d\x95\xbfk\xdbP\x10\xc7?\xaaC\'\xa3%\x85d\n\x1c\x04\xba\
549 \x96[:\x14\x8aK;\xe6O\xc8\x90\xc1\xde\r\x9d\x0b\xfa\x13\x84\x97\x0c\xf5\x98\
550 \xc9c\xe9\xd0%i\xe2\xad\x14D\x97\x0c\x15\x86\x83\x0c\xc2\x01\x17\xc3CK\x83\
551 \xcd\xeb\xa0\x1f\x95\x9c\x1f\r=\x10z\xe8\xee\xbe\xef\xbd\xef\xdd}\x15D\xdco\
552 \x11\x0c\x80C\xe0Y\xf9i\x01\x9cD\xf0\xf1\x8e\xf0\x00`\xeb\x1e\x90+\xe0\x1a\
553 \xd8\x01^\xab*\x00I\x92 "\xdf#\xb3\x17\xa5o\xaf\x01\xee\x81\xe0\xc9\x06\xd8)\
554 p,"_\xaao\xaaJ\x1c\xc7\xc4qL\x05\x0c "\x9f\x80\xe32\xa72OT\x00A\xe1\xf0\x8dg\
555 \x01\xacT\xd5\xa7i\xea\xb3,\xf3\xaa\xea\x81\x95\x88\xfc\xde\x88=\xadqJ\xb0\
556 \x01\xb0\x02\xfcd2\xf1I\x92T\xc9\xde9\xe7\x9ds>\xcb2\x9fe\x99\x07\xbc\xaa\
557 \xfa$I\xfcd2\xa9\x00W\xc0 jpx%"k3\xeb\xec\xef\xef\xb3\xbb\xbb\xcb\xf9\xf9y\
558 \x8b\xdbn\xb7\x0b\x80s\x0e\x80<\xcf\x9b\xd7\xef\x98\xd9\x15@\xc5\xe1\xb5\x99\
559 \xbd\x14\x91\x9b~\xbf_\'?d\xddn\x97~\xbf\x0f\xf0\xcb\xcc\x94\xa2\x88\x04\xc0\
560 @D\x9e\x03\x98\xd9\x10\xe8T\xa7\xf8\x97\x85a\x08\xb0\xa6f\xae\x00\xbd\xa0\
561 \xe4EU}\x96e5o\xce9?\x1a\x8dj\xdfh4j\xf9\x9cs\xb5\x8f\x82\xcb\x0b\x80KU\xf5\
562 \xd3\xe9\xb4&~3\xa1\x0c\xf6\xaaz\x0b0MS?\x9dN\xab\xb8\xcbV\x1f\xe6y\xfe(\xfe\
563 \x1e\x8a\xdf\x02\x16I\x920\x1c\x0e\x01nU\xf7\xe8\xe8\xe8\xceue\x07\x07\x07@1\
564 E\xc0"\x00\xde\x00\xafJ\x7f\xc4\x7f\x14EDb\x003\xfb\xb9\x15\xc1\xd7\x08\x96\
565 \x14\x15\x1f\xaa\xea\xf6\xa3\xd0(\xc6r\xb9\\\xae\xcd\xec\xa4<\xcd\x8f\x8a\
566 \xc3\x1d\x11I\x80\xed\xf1x\xdcj\xda\xfb,\xcfs\xc6\xe31f\xf6TD\xbeQ\x88E-\x0e\
567 {f\xb6\x06\x98\xcdf\xcc\xe7sz\xbd\x1ea\x18\x92\xe7yk\x830\x0c\xe9\xf5z\xcc\
568 \xe7sf\xb3\x19\xe5U;\xc0\x1e\xa58\x04Qq\xdd\x968\x94\x02\xb0\xaaz3M\xd3Z\x1c\
569 (\x84\xe3Nq\xa8\xdb&\x82\xb7\xc0\x19\x05\xc97\xe5(\xc6\xcdS\xff\r\xe5\x9d\
570 \x88@1%ge.@\x10D\x05h\xb5SK`E\xe4\xd0\xcc\xde7\x05\x16\xf8\x00|\xe6\xb6\xc0\
571 \xb6\x00\xa9\x00\x1b\xef\xc7\xfe\x02\x82\xc6\x9a?\xea\xc8x\xd8\xb0\t\xb9\xf6\
572 \x00\x00\x00\x00IEND\xaeB`\x82'
573
574 def getRefreshBitmap():
575 return BitmapFromImage(getRefreshImage())
576
577 def getRefreshImage():
578 stream = cStringIO.StringIO(getRefreshData())
579 return ImageFromStream(stream)
580
581 #----------------------------------------------------------------------
582 def getFindData():
583 return \
584 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\x08\x06\
585 \x00\x00\x00\x8d\x89\x1d\r\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
586 \x00\x01\xe6IDAT8\x8d\xa5\xd3\xbdk\x13q\x1c\xc7\xf1W\x9a\x12t\xe8\x18\xcd\
587 \xd6\xa1\x17\x10\x8a\xa8\x8b\x83C\x0c\x9d\xae\x07R\x1d|@\x9d\x02\xa2 \xde\
588 \x1f\xe0t\x93\x7f@\xbb(\x82\xb8\xa4\xb8i;\xa47\xd6\x08\x0e\x1d\xdaB\xc7\\)\
589 \x05\x1fJ\x07\xff\x80\n\xe2pi\x9a\xda\xa6O~\xe0\x0b?\x8e\xef\xef}\xef\xdfS!\
590 \xb1\x97\x84\xeb\xb8\x81\xcb\xf6g\r_\x13\x96\x1c\x93b}\x0f\xf6\x08wq\x05\xf7\
591 p\xad\xaf\xfe\xe0\xd2"#\xf5\x1c>0\xc3}\xb0\x87\x88\xe28\x16\x86\xa1 \x08@\
592 \x96e\xd24\x8d\xa6\xa7\xa7\xa1\x92\xe4\xfd\xcdA\xc0\x82|\x99O\xd1h\xb5Z\x82 \
593 \xb0\xb3S\xdd\xd7T*udY&\x8a"x\x877\x83\x96?$\xdf\xb3J\x1c\xc7=\xd8\xf88\xeb\
594 \xeby\xc1\xceNU\x10\x04\xe28\x86Jw\xce\xa1\x19\x92\x1f@\x14\x86a\x0f\x06\x17\
595 \xba\xd5\x0f\r\xc3\x10"\x07\x0f\xad\x97\xe1\xddAn\xc7\xfc|\x0e\xda\xcd.tlLo_\
596 \x8f\xca\xd0\xb1\x1d\xa7L\x0f\x98e\x19r\x93\xed\xbe\x86\xed\xee\xb7\xfe\x1e\
597 \xfc<\n\xb8\x86V\x9a\xa6J\xa5\xce>h?\xacT\xeaH\xd3T\xadV\x83\xd5A\xc0\xb3\\\
598 \x1bh\'\xdc<\x0cXL\xf8\xbe\xc8\x08\xce5\x9b\xcdj\xa1PP.S.S,\xfe\xb2\xb1\xb1d\
599 vvV\x1c\xc7\xa2(R\xadvt:F\x17\x99\xa8\xf3\xfe\x80a\xd2\x1d$\xf9k\x99\x90\xdf\
600 \xb3\xa8\xbf\xa9V\xabi\xb7\xdb\x1a\rn]\xe5\xdb\x16/^\x1dn\xda{\xcbu\xd6\x16\
601 \xd9\xc2o\xfc\xc0J\xb7Z\x9b\x9b\x9b3\xa8\xac\xac\x18}0\xc9\xfd\xc7s.\x9e\xff\
602 `\xe1\xcbA\xd3\x9e\xe1I\x92\xf0\x19\xb5\x8f\xd3L\xde\x9e\xf3\xf6\xf5\xd4\x01\
603 \xd3S\xdd\xc3\xee\xa4\xf6\x9d\x98\x85OS\x9e<\x9b3\xf3\x12\xd4\xba?;\x9d\xe1I\
604 L\xcf\xf4R\x0e3m4r\xd33\x19\xfek\xdah\xb0\xba\xca\xf2\xb2\xf6\x7f\x01\xfb\
605 \xa1h\xe3\xf9_3n\xb4\xee\xba\xaf\xf1\xb8\x00\x00\x00\x00IEND\xaeB`\x82'
606
607 def getFindBitmap():
608 return BitmapFromImage(getFindImage())
609
610 def getFindImage():
611 stream = cStringIO.StringIO(getFindData())
612 return ImageFromStream(stream)
613
614 #----------------------------------------------------------------------
615 def getShowSizersData():
616 return \
617 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\x08\x06\
618 \x00\x00\x00\x8d\x89\x1d\r\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
619 \x00\x01-IDAT8\x8d\xad\x931N\xc3@\x10E\x9f!\x1dU\xba\x7f\x008\x00\x17@\xe9\
620 \x007\\\x81\x16\xc5\xe2\x0c{\x01\xba Qr\x85H\x89#Rr\r\xe2~\xbaH\xc8\xa2B2\
621 \x05^\xb3$v\xd6\x962\xd2Jc\xff\xd9\xb73;;\x89\xe3\xb86\xea\x12\x1c\xdcJ\xca\
622 \xda43\x9b9X\r\x02J\xca\xcc,\xed\xd0\xc0l\x18\xb0\xb1\xb7\xc0__\xc0\xd3\xc7\
623 \xc1\xf08\x10\xa0\xb8\xac\x9d2\x1a\xda\x13\x18\x07\xf5\x07^\x03\x1c.\xb3\x17\
624 \xd0\xccf\x92\xbc\x9f\x02H\xca\xbd\xd6\xb5\xef$v\xa2\x99\xa5\x92rIyW\xd7\xa3\
625 \x19\xba\xfa\rz\x98\xcfH\x92?\x00g\x86ky\x8b\xa7\x93\x1e0\x07\xab\tl\x16e\
626 \xb9\x954\xae\xb5\xf1\xa2,\xb7\x13\xd8t\x02\xbb`^\xef\x03\x1d\xb9`\xc4\x14\
627 \xdcY\xec\xae\xfc\x9dJ\xe2\x052\xa8\x9b%i\tTmK\xd2\xd2\xfdf\xde\xacX\xfc_S^\
628 \xab\xbb\xc6\xff,\xe6<\x9e\x1f\xcc\xb0\xe2\xea9\xfcNx\x9f\xc2n\x97\xbfy\x88\
629 \x95\x1aZ\xc1\xd9\x14`\x8d5\xff\xfe\x03\xbf\x8a\x9b!\xc0\x10\xb4\x0f\xbcO\
630 \xe6C`\xbe\xc4=`8b\xbb\xd66b\xb1\xf8\xc4\rI\xab\x87\xfd\x00>\xff\xa7/3u\xdc\
631 \xf3\x00\x00\x00\x00IEND\xaeB`\x82'
632
633 def getShowSizersBitmap():
634 return BitmapFromImage(getShowSizersImage())
635
636 def getShowSizersImage():
637 stream = cStringIO.StringIO(getShowSizersData())
638 return ImageFromStream(stream)
639
640 #----------------------------------------------------------------------
641 def getShowFillingData():
642 return \
643 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x14\x08\x06\
644 \x00\x00\x00\x8d\x89\x1d\r\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
645 \x00\x00\x99IDAT8\x8d\xd5\xd2\xb1\r\xc3 \x10\x85\xe1\xff"\xcf\x90\x89\xa0O\
646 \xe3\x19\\d\x89["\x8dWp\xe1\x01`"/q)\x12G\xc2r\n\xccEr^\x03\x08\xf4\xe9I\x87\
647 (\xbe\xb98{t\x00\n\x01\xe8\x1b\x9cI!\x7f@\xe0\x0e\xdc\x1a\xc0+\x1b\x10\x003c\
648 \x1c\xeb\xa4a\x90\xe2\xdc\x95\x97\x95\xda^\xf4\xb5\xcc\x80\x1d\t`\xc0\xaco\
649 \xcb}\xca\xbf\xf96kr\xce\xbe`\x8c\xd1\x17L)U\x03\xdb\x12\x05\x18B8R\xaa\xc8\
650 \x9fMYD\xbe\xbd\xab\x06\x1f\xc0\xd2\xe0L\xebF\xb4\xa5\xceN\xce?\x94\'\x9egM\
651 \xd2gvb\xb2\x00\x00\x00\x00IEND\xaeB`\x82'
652
653 def getShowFillingBitmap():
654 return BitmapFromImage(getShowFillingImage())
655
656 def getShowFillingImage():
657 stream = cStringIO.StringIO(getShowFillingData())
658 return ImageFromStream(stream)
659
660 #----------------------------------------------------------------------