wxPython 4.3.2__cp315-cp315-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. wx/WebView2Loader.dll +0 -0
  2. wx/__init__.py +22 -0
  3. wx/__init__.pyi +10 -0
  4. wx/__version__.py +9 -0
  5. wx/__version__.pyi +15 -0
  6. wx/_adv.cp315-win_amd64.pyd +0 -0
  7. wx/_aui.cp315-win_amd64.pyd +0 -0
  8. wx/_core.cp315-win_amd64.pyd +0 -0
  9. wx/_dataview.cp315-win_amd64.pyd +0 -0
  10. wx/_glcanvas.cp315-win_amd64.pyd +0 -0
  11. wx/_grid.cp315-win_amd64.pyd +0 -0
  12. wx/_html.cp315-win_amd64.pyd +0 -0
  13. wx/_html2.cp315-win_amd64.pyd +0 -0
  14. wx/_media.cp315-win_amd64.pyd +0 -0
  15. wx/_msw.cp315-win_amd64.pyd +0 -0
  16. wx/_propgrid.cp315-win_amd64.pyd +0 -0
  17. wx/_ribbon.cp315-win_amd64.pyd +0 -0
  18. wx/_richtext.cp315-win_amd64.pyd +0 -0
  19. wx/_stc.cp315-win_amd64.pyd +0 -0
  20. wx/_xml.cp315-win_amd64.pyd +0 -0
  21. wx/_xrc.cp315-win_amd64.pyd +0 -0
  22. wx/adv.py +127 -0
  23. wx/adv.pyi +5931 -0
  24. wx/aui.py +70 -0
  25. wx/aui.pyi +4805 -0
  26. wx/core.py +3417 -0
  27. wx/core.pyi +62949 -0
  28. wx/dataview.py +176 -0
  29. wx/dataview.pyi +3828 -0
  30. wx/gizmos.py +18 -0
  31. wx/glcanvas.py +13 -0
  32. wx/glcanvas.pyi +544 -0
  33. wx/grid.py +237 -0
  34. wx/grid.pyi +5678 -0
  35. wx/html.py +38 -0
  36. wx/html.pyi +3283 -0
  37. wx/html2.py +46 -0
  38. wx/html2.pyi +1301 -0
  39. wx/include/wxPython/sip.h +1938 -0
  40. wx/include/wxPython/wxpy_api.h +418 -0
  41. wx/lib/CDate.py +201 -0
  42. wx/lib/ClickableHtmlWindow.py +57 -0
  43. wx/lib/__init__.py +0 -0
  44. wx/lib/activex.py +178 -0
  45. wx/lib/activexwrapper.py +153 -0
  46. wx/lib/agw/__init__.py +128 -0
  47. wx/lib/agw/advancedsplash.py +563 -0
  48. wx/lib/agw/aquabutton.py +1127 -0
  49. wx/lib/agw/artmanager.py +2110 -0
  50. wx/lib/agw/aui/__init__.py +295 -0
  51. wx/lib/agw/aui/aui_constants.py +2616 -0
  52. wx/lib/agw/aui/aui_switcherdialog.py +1232 -0
  53. wx/lib/agw/aui/aui_utilities.py +648 -0
  54. wx/lib/agw/aui/auibar.py +4045 -0
  55. wx/lib/agw/aui/auibook.py +6288 -0
  56. wx/lib/agw/aui/dockart.py +1198 -0
  57. wx/lib/agw/aui/framemanager.py +10485 -0
  58. wx/lib/agw/aui/tabart.py +2749 -0
  59. wx/lib/agw/aui/tabmdi.py +679 -0
  60. wx/lib/agw/balloontip.py +1157 -0
  61. wx/lib/agw/buttonpanel.py +2787 -0
  62. wx/lib/agw/cubecolourdialog.py +3529 -0
  63. wx/lib/agw/customtreectrl.py +9908 -0
  64. wx/lib/agw/data/ShortcutEditor_1.png +0 -0
  65. wx/lib/agw/data/ShortcutEditor_1_thumb.png +0 -0
  66. wx/lib/agw/data/ShortcutEditor_2.png +0 -0
  67. wx/lib/agw/data/ShortcutEditor_2_thumb.png +0 -0
  68. wx/lib/agw/data/ShortcutEditor_3.png +0 -0
  69. wx/lib/agw/data/ShortcutEditor_3_thumb.png +0 -0
  70. wx/lib/agw/data/ShortcutEditor_4.png +0 -0
  71. wx/lib/agw/data/ShortcutEditor_4_thumb.png +0 -0
  72. wx/lib/agw/data/default_help_text.html +105 -0
  73. wx/lib/agw/flatmenu.py +7392 -0
  74. wx/lib/agw/flatnotebook.py +6669 -0
  75. wx/lib/agw/floatspin.py +1820 -0
  76. wx/lib/agw/fmcustomizedlg.py +535 -0
  77. wx/lib/agw/fmresources.py +407 -0
  78. wx/lib/agw/foldpanelbar.py +2282 -0
  79. wx/lib/agw/fourwaysplitter.py +1130 -0
  80. wx/lib/agw/genericmessagedialog.py +1549 -0
  81. wx/lib/agw/gradientbutton.py +731 -0
  82. wx/lib/agw/hyperlink.py +664 -0
  83. wx/lib/agw/hypertreelist.py +5756 -0
  84. wx/lib/agw/infobar.py +885 -0
  85. wx/lib/agw/knobctrl.py +944 -0
  86. wx/lib/agw/labelbook.py +3028 -0
  87. wx/lib/agw/multidirdialog.py +581 -0
  88. wx/lib/agw/peakmeter.py +1028 -0
  89. wx/lib/agw/persist/__init__.py +188 -0
  90. wx/lib/agw/persist/persist_constants.py +283 -0
  91. wx/lib/agw/persist/persist_handlers.py +2614 -0
  92. wx/lib/agw/persist/persistencemanager.py +863 -0
  93. wx/lib/agw/piectrl.py +1082 -0
  94. wx/lib/agw/pybusyinfo.py +399 -0
  95. wx/lib/agw/pycollapsiblepane.py +940 -0
  96. wx/lib/agw/pygauge.py +570 -0
  97. wx/lib/agw/pyprogress.py +916 -0
  98. wx/lib/agw/ribbon/__init__.py +198 -0
  99. wx/lib/agw/ribbon/art.py +219 -0
  100. wx/lib/agw/ribbon/art_aui.py +1283 -0
  101. wx/lib/agw/ribbon/art_default.py +81 -0
  102. wx/lib/agw/ribbon/art_internal.py +248 -0
  103. wx/lib/agw/ribbon/art_msw.py +2735 -0
  104. wx/lib/agw/ribbon/art_osx.py +52 -0
  105. wx/lib/agw/ribbon/bar.py +1259 -0
  106. wx/lib/agw/ribbon/buttonbar.py +1317 -0
  107. wx/lib/agw/ribbon/control.py +205 -0
  108. wx/lib/agw/ribbon/gallery.py +973 -0
  109. wx/lib/agw/ribbon/page.py +946 -0
  110. wx/lib/agw/ribbon/panel.py +1170 -0
  111. wx/lib/agw/ribbon/toolbar.py +1441 -0
  112. wx/lib/agw/rulerctrl.py +1885 -0
  113. wx/lib/agw/scrolledthumbnail.py +2116 -0
  114. wx/lib/agw/shapedbutton.py +1809 -0
  115. wx/lib/agw/shortcuteditor.py +2642 -0
  116. wx/lib/agw/speedmeter.py +1800 -0
  117. wx/lib/agw/supertooltip.py +1443 -0
  118. wx/lib/agw/thumbnailctrl.py +529 -0
  119. wx/lib/agw/toasterbox.py +1327 -0
  120. wx/lib/agw/ultimatelistctrl.py +13671 -0
  121. wx/lib/agw/xlsgrid.py +2111 -0
  122. wx/lib/agw/zoombar.py +1336 -0
  123. wx/lib/analogclock/__init__.py +140 -0
  124. wx/lib/analogclock/analogclock.py +630 -0
  125. wx/lib/analogclock/helpers.py +986 -0
  126. wx/lib/analogclock/lib_setup/__init__.py +0 -0
  127. wx/lib/analogclock/lib_setup/buttontreectrlpanel.py +297 -0
  128. wx/lib/analogclock/lib_setup/fontselect.py +57 -0
  129. wx/lib/analogclock/setup.py +490 -0
  130. wx/lib/analogclock/styles.py +47 -0
  131. wx/lib/anchors.py +103 -0
  132. wx/lib/art/__init__.py +4 -0
  133. wx/lib/art/flagart.py +1583 -0
  134. wx/lib/art/img2pyartprov.py +56 -0
  135. wx/lib/busy.py +152 -0
  136. wx/lib/buttons.py +1140 -0
  137. wx/lib/calendar.py +1596 -0
  138. wx/lib/checkbox.py +837 -0
  139. wx/lib/colourchooser/__init__.py +36 -0
  140. wx/lib/colourchooser/canvas.py +145 -0
  141. wx/lib/colourchooser/intl.py +24 -0
  142. wx/lib/colourchooser/pycolourbox.py +89 -0
  143. wx/lib/colourchooser/pycolourchooser.py +626 -0
  144. wx/lib/colourchooser/pycolourslider.py +98 -0
  145. wx/lib/colourchooser/pypalette.py +208 -0
  146. wx/lib/colourdb.py +740 -0
  147. wx/lib/colourselect.py +385 -0
  148. wx/lib/colourutils.py +118 -0
  149. wx/lib/combotreebox.py +944 -0
  150. wx/lib/delayedresult.py +420 -0
  151. wx/lib/dialogs.py +510 -0
  152. wx/lib/docview.py +3210 -0
  153. wx/lib/dragscroller.py +79 -0
  154. wx/lib/editor/README.txt +77 -0
  155. wx/lib/editor/__init__.py +24 -0
  156. wx/lib/editor/editor.py +974 -0
  157. wx/lib/editor/images.py +15 -0
  158. wx/lib/editor/selection.py +44 -0
  159. wx/lib/embeddedimage.py +76 -0
  160. wx/lib/eventStack.py +136 -0
  161. wx/lib/eventwatcher.py +440 -0
  162. wx/lib/evtmgr.py +521 -0
  163. wx/lib/expando.py +393 -0
  164. wx/lib/fancytext.py +494 -0
  165. wx/lib/filebrowsebutton.py +461 -0
  166. wx/lib/flashwin.py +262 -0
  167. wx/lib/flashwin_old.py +651 -0
  168. wx/lib/floatcanvas/FCEvents.py +53 -0
  169. wx/lib/floatcanvas/FCObjects.py +2910 -0
  170. wx/lib/floatcanvas/FloatCanvas.py +1025 -0
  171. wx/lib/floatcanvas/GUIMode.py +396 -0
  172. wx/lib/floatcanvas/NavCanvas.py +162 -0
  173. wx/lib/floatcanvas/Resources.py +319 -0
  174. wx/lib/floatcanvas/ScreenShot.py +1788 -0
  175. wx/lib/floatcanvas/Utilities/BBox.py +313 -0
  176. wx/lib/floatcanvas/Utilities/Colors.py +137 -0
  177. wx/lib/floatcanvas/Utilities/GUI.py +91 -0
  178. wx/lib/floatcanvas/Utilities/__init__.py +7 -0
  179. wx/lib/floatcanvas/__init__.py +124 -0
  180. wx/lib/foldmenu.py +89 -0
  181. wx/lib/gestures.py +310 -0
  182. wx/lib/gizmos/__init__.py +18 -0
  183. wx/lib/gizmos/dynamicsash.py +1202 -0
  184. wx/lib/gizmos/ledctrl.py +299 -0
  185. wx/lib/gizmos/treelistctrl.py +87 -0
  186. wx/lib/graphics.py +1942 -0
  187. wx/lib/gridmovers.py +516 -0
  188. wx/lib/iewin.py +249 -0
  189. wx/lib/iewin_old.py +894 -0
  190. wx/lib/imagebrowser.py +853 -0
  191. wx/lib/imageutils.py +163 -0
  192. wx/lib/infoframe.py +490 -0
  193. wx/lib/inspection.py +1254 -0
  194. wx/lib/intctrl.py +990 -0
  195. wx/lib/itemspicker.py +256 -0
  196. wx/lib/langlistctrl.py +480 -0
  197. wx/lib/layoutf.py +271 -0
  198. wx/lib/masked/__init__.py +27 -0
  199. wx/lib/masked/combobox.py +839 -0
  200. wx/lib/masked/ctrl.py +108 -0
  201. wx/lib/masked/ipaddrctrl.py +241 -0
  202. wx/lib/masked/maskededit.py +7262 -0
  203. wx/lib/masked/numctrl.py +2000 -0
  204. wx/lib/masked/textctrl.py +465 -0
  205. wx/lib/masked/timectrl.py +1465 -0
  206. wx/lib/mixins/__init__.py +17 -0
  207. wx/lib/mixins/grid.py +47 -0
  208. wx/lib/mixins/gridlabelrenderer.py +277 -0
  209. wx/lib/mixins/imagelist.py +77 -0
  210. wx/lib/mixins/inspection.py +184 -0
  211. wx/lib/mixins/listctrl.py +893 -0
  212. wx/lib/mixins/rubberband.py +403 -0
  213. wx/lib/mixins/treemixin.py +678 -0
  214. wx/lib/msgpanel.py +95 -0
  215. wx/lib/multisash.py +746 -0
  216. wx/lib/myole4ax.idl +178 -0
  217. wx/lib/myole4ax.tlb +0 -0
  218. wx/lib/newevent.py +229 -0
  219. wx/lib/newevent.pyi +25 -0
  220. wx/lib/nvdlg.py +156 -0
  221. wx/lib/ogl/__init__.py +13 -0
  222. wx/lib/ogl/basic.py +3989 -0
  223. wx/lib/ogl/bmpshape.py +86 -0
  224. wx/lib/ogl/canvas.py +467 -0
  225. wx/lib/ogl/composit.py +1576 -0
  226. wx/lib/ogl/diagram.py +230 -0
  227. wx/lib/ogl/divided.py +482 -0
  228. wx/lib/ogl/drawn.py +898 -0
  229. wx/lib/ogl/lines.py +1809 -0
  230. wx/lib/ogl/oglmisc.py +607 -0
  231. wx/lib/pdfviewer/__init__.py +113 -0
  232. wx/lib/pdfviewer/bitmaps/ArrowLeft.png +0 -0
  233. wx/lib/pdfviewer/bitmaps/ArrowRight.png +0 -0
  234. wx/lib/pdfviewer/bitmaps/DirectionH.png +0 -0
  235. wx/lib/pdfviewer/bitmaps/DirectionV.png +0 -0
  236. wx/lib/pdfviewer/bitmaps/PlayerFirst.png +0 -0
  237. wx/lib/pdfviewer/bitmaps/PlayerLast.png +0 -0
  238. wx/lib/pdfviewer/bitmaps/PlayerNext.png +0 -0
  239. wx/lib/pdfviewer/bitmaps/PlayerPrev.png +0 -0
  240. wx/lib/pdfviewer/bitmaps/Printer.png +0 -0
  241. wx/lib/pdfviewer/bitmaps/ReadMe.txt +28 -0
  242. wx/lib/pdfviewer/bitmaps/Save.png +0 -0
  243. wx/lib/pdfviewer/bitmaps/ZoomIn.png +0 -0
  244. wx/lib/pdfviewer/bitmaps/ZoomOut.png +0 -0
  245. wx/lib/pdfviewer/bitmaps/encode_bitmaps.py +37 -0
  246. wx/lib/pdfviewer/buttonpanel.py +285 -0
  247. wx/lib/pdfviewer/images.py +240 -0
  248. wx/lib/pdfviewer/viewer.py +1118 -0
  249. wx/lib/pdfwin.py +295 -0
  250. wx/lib/pdfwin_old.py +789 -0
  251. wx/lib/platebtn.py +789 -0
  252. wx/lib/plot/CHANGELOG.md +150 -0
  253. wx/lib/plot/README.md +16 -0
  254. wx/lib/plot/__init__.py +46 -0
  255. wx/lib/plot/__main__.py +5 -0
  256. wx/lib/plot/examples/__init__.py +0 -0
  257. wx/lib/plot/examples/demo.py +1010 -0
  258. wx/lib/plot/examples/simple_example.py +56 -0
  259. wx/lib/plot/plotcanvas.py +2985 -0
  260. wx/lib/plot/polyobjects.py +1524 -0
  261. wx/lib/plot/utils.py +334 -0
  262. wx/lib/popupctl.py +251 -0
  263. wx/lib/printout.py +1155 -0
  264. wx/lib/progressindicator.py +151 -0
  265. wx/lib/pubsub/LICENSE_BSD_Simple.txt +23 -0
  266. wx/lib/pubsub/README_WxPython.txt +22 -0
  267. wx/lib/pubsub/RELEASE_NOTES.txt +71 -0
  268. wx/lib/pubsub/__init__.py +25 -0
  269. wx/lib/pubsub/core/__init__.py +92 -0
  270. wx/lib/pubsub/core/arg1/__init__.py +16 -0
  271. wx/lib/pubsub/core/arg1/listenerimpl.py +97 -0
  272. wx/lib/pubsub/core/arg1/publisher.py +40 -0
  273. wx/lib/pubsub/core/arg1/publishermixin.py +34 -0
  274. wx/lib/pubsub/core/arg1/topicargspecimpl.py +66 -0
  275. wx/lib/pubsub/core/arg1/topicmgrimpl.py +19 -0
  276. wx/lib/pubsub/core/callables.py +198 -0
  277. wx/lib/pubsub/core/imp2.py +62 -0
  278. wx/lib/pubsub/core/itopicdefnprovider.py +0 -0
  279. wx/lib/pubsub/core/kwargs/__init__.py +16 -0
  280. wx/lib/pubsub/core/kwargs/datamsg.py +27 -0
  281. wx/lib/pubsub/core/kwargs/listenerimpl.py +93 -0
  282. wx/lib/pubsub/core/kwargs/publisher.py +77 -0
  283. wx/lib/pubsub/core/kwargs/publishermixin.py +65 -0
  284. wx/lib/pubsub/core/kwargs/topicargspecimpl.py +216 -0
  285. wx/lib/pubsub/core/kwargs/topicmgrimpl.py +13 -0
  286. wx/lib/pubsub/core/listener.py +40 -0
  287. wx/lib/pubsub/core/listenerbase.py +185 -0
  288. wx/lib/pubsub/core/notificationmgr.py +185 -0
  289. wx/lib/pubsub/core/publisherbase.py +189 -0
  290. wx/lib/pubsub/core/topicargspec.py +77 -0
  291. wx/lib/pubsub/core/topicdefnprovider.py +631 -0
  292. wx/lib/pubsub/core/topicexc.py +72 -0
  293. wx/lib/pubsub/core/topicmgr.py +454 -0
  294. wx/lib/pubsub/core/topicobj.py +472 -0
  295. wx/lib/pubsub/core/topictreetraverser.py +143 -0
  296. wx/lib/pubsub/core/topicutils.py +119 -0
  297. wx/lib/pubsub/core/treeconfig.py +21 -0
  298. wx/lib/pubsub/core/validatedefnargs.py +29 -0
  299. wx/lib/pubsub/core/weakmethod.py +102 -0
  300. wx/lib/pubsub/policies.py +24 -0
  301. wx/lib/pubsub/pub.py +199 -0
  302. wx/lib/pubsub/setuparg1.py +47 -0
  303. wx/lib/pubsub/setupkwargs.py +29 -0
  304. wx/lib/pubsub/utils/__init__.py +27 -0
  305. wx/lib/pubsub/utils/exchandling.py +100 -0
  306. wx/lib/pubsub/utils/misc.py +99 -0
  307. wx/lib/pubsub/utils/notification.py +331 -0
  308. wx/lib/pubsub/utils/topictreeprinter.py +195 -0
  309. wx/lib/pubsub/utils/xmltopicdefnprovider.py +286 -0
  310. wx/lib/pydocview.py +3300 -0
  311. wx/lib/rcsizer.py +227 -0
  312. wx/lib/resizewidget.py +357 -0
  313. wx/lib/scrolledpanel.py +243 -0
  314. wx/lib/sheet.py +350 -0
  315. wx/lib/sized_controls.py +691 -0
  316. wx/lib/softwareupdate.py +355 -0
  317. wx/lib/splitter.py +925 -0
  318. wx/lib/statbmp.py +199 -0
  319. wx/lib/stattext.py +321 -0
  320. wx/lib/throbber.py +424 -0
  321. wx/lib/ticker.py +306 -0
  322. wx/lib/ticker_xrc.py +48 -0
  323. wx/lib/utils.py +89 -0
  324. wx/lib/wordwrap.py +97 -0
  325. wx/lib/wxcairo/__init__.py +139 -0
  326. wx/lib/wxcairo/wx_cairocffi.py +200 -0
  327. wx/lib/wxcairo/wx_pycairo.py +455 -0
  328. wx/lib/wxpTag.py +274 -0
  329. wx/libcairo-2.dll +0 -0
  330. wx/locale/af/LC_MESSAGES/wxstd.mo +0 -0
  331. wx/locale/an/LC_MESSAGES/wxstd.mo +0 -0
  332. wx/locale/ar/LC_MESSAGES/wxstd.mo +0 -0
  333. wx/locale/ca/LC_MESSAGES/wxstd.mo +0 -0
  334. wx/locale/ca@valencia/LC_MESSAGES/wxstd.mo +0 -0
  335. wx/locale/co/LC_MESSAGES/wxstd.mo +0 -0
  336. wx/locale/cs/LC_MESSAGES/wxstd.mo +0 -0
  337. wx/locale/da/LC_MESSAGES/wxstd.mo +0 -0
  338. wx/locale/de/LC_MESSAGES/wxstd.mo +0 -0
  339. wx/locale/el/LC_MESSAGES/wxstd.mo +0 -0
  340. wx/locale/es/LC_MESSAGES/wxstd.mo +0 -0
  341. wx/locale/eu/LC_MESSAGES/wxstd.mo +0 -0
  342. wx/locale/fa_IR/LC_MESSAGES/wxstd.mo +0 -0
  343. wx/locale/fi/LC_MESSAGES/wxstd.mo +0 -0
  344. wx/locale/fr/LC_MESSAGES/wxstd.mo +0 -0
  345. wx/locale/gl_ES/LC_MESSAGES/wxstd.mo +0 -0
  346. wx/locale/hi/LC_MESSAGES/wxstd.mo +0 -0
  347. wx/locale/hr/LC_MESSAGES/wxstd.mo +0 -0
  348. wx/locale/hu/LC_MESSAGES/wxstd.mo +0 -0
  349. wx/locale/id/LC_MESSAGES/wxstd.mo +0 -0
  350. wx/locale/it/LC_MESSAGES/wxstd.mo +0 -0
  351. wx/locale/ja/LC_MESSAGES/wxstd.mo +0 -0
  352. wx/locale/ka/LC_MESSAGES/wxstd.mo +0 -0
  353. wx/locale/ko_KR/LC_MESSAGES/wxstd.mo +0 -0
  354. wx/locale/lt/LC_MESSAGES/wxstd.mo +0 -0
  355. wx/locale/lv/LC_MESSAGES/wxstd.mo +0 -0
  356. wx/locale/ms/LC_MESSAGES/wxstd.mo +0 -0
  357. wx/locale/nb/LC_MESSAGES/wxstd.mo +0 -0
  358. wx/locale/ne/LC_MESSAGES/wxstd.mo +0 -0
  359. wx/locale/nl/LC_MESSAGES/wxstd.mo +0 -0
  360. wx/locale/pl/LC_MESSAGES/wxstd.mo +0 -0
  361. wx/locale/pt/LC_MESSAGES/wxstd.mo +0 -0
  362. wx/locale/pt_BR/LC_MESSAGES/wxstd.mo +0 -0
  363. wx/locale/ro/LC_MESSAGES/wxstd.mo +0 -0
  364. wx/locale/ru/LC_MESSAGES/wxstd.mo +0 -0
  365. wx/locale/sk/LC_MESSAGES/wxstd.mo +0 -0
  366. wx/locale/sl/LC_MESSAGES/wxstd.mo +0 -0
  367. wx/locale/sq/LC_MESSAGES/wxstd.mo +0 -0
  368. wx/locale/sr/LC_MESSAGES/wxstd.mo +0 -0
  369. wx/locale/sv/LC_MESSAGES/wxstd.mo +0 -0
  370. wx/locale/ta/LC_MESSAGES/wxstd.mo +0 -0
  371. wx/locale/tr/LC_MESSAGES/wxstd.mo +0 -0
  372. wx/locale/uk/LC_MESSAGES/wxstd.mo +0 -0
  373. wx/locale/vi/LC_MESSAGES/wxstd.mo +0 -0
  374. wx/locale/zh_CN/LC_MESSAGES/wxstd.mo +0 -0
  375. wx/locale/zh_TW/LC_MESSAGES/wxstd.mo +0 -0
  376. wx/media.py +30 -0
  377. wx/media.pyi +272 -0
  378. wx/msw.py +16 -0
  379. wx/msw.pyi +91 -0
  380. wx/propgrid.py +498 -0
  381. wx/propgrid.pyi +7427 -0
  382. wx/py/CHANGES.txt +796 -0
  383. wx/py/Py.ico +0 -0
  384. wx/py/PyAlaCarte.py +34 -0
  385. wx/py/PyAlaMode.py +34 -0
  386. wx/py/PyAlaModeTest.py +33 -0
  387. wx/py/PyCrust.ico +0 -0
  388. wx/py/PyCrust.py +78 -0
  389. wx/py/PyCrust_16.png +0 -0
  390. wx/py/PyCrust_32.png +0 -0
  391. wx/py/PyFilling.py +35 -0
  392. wx/py/PyShell.py +78 -0
  393. wx/py/PySlices.ico +0 -0
  394. wx/py/PySlices.py +98 -0
  395. wx/py/PySlicesShell.py +94 -0
  396. wx/py/PySlices_16.png +0 -0
  397. wx/py/PySlices_32.png +0 -0
  398. wx/py/PyWrap.py +52 -0
  399. wx/py/README.txt +77 -0
  400. wx/py/__init__.py +20 -0
  401. wx/py/buffer.py +136 -0
  402. wx/py/crust.py +403 -0
  403. wx/py/crustslices.py +403 -0
  404. wx/py/dispatcher.py +259 -0
  405. wx/py/document.py +37 -0
  406. wx/py/editor.py +844 -0
  407. wx/py/editwindow.py +316 -0
  408. wx/py/filling.py +358 -0
  409. wx/py/frame.py +976 -0
  410. wx/py/images.py +212 -0
  411. wx/py/interpreter.py +161 -0
  412. wx/py/introspect.py +402 -0
  413. wx/py/magic.py +98 -0
  414. wx/py/parse.py +134 -0
  415. wx/py/path.py +36 -0
  416. wx/py/pseudo.py +99 -0
  417. wx/py/shell.py +1579 -0
  418. wx/py/sliceshell.py +3805 -0
  419. wx/py/tests/test_interpreter.py +71 -0
  420. wx/py/tests/test_introspect.py +810 -0
  421. wx/py/tests/test_pseudo.py +70 -0
  422. wx/py/tests/test_version.py +36 -0
  423. wx/py/tests/testall.py +22 -0
  424. wx/py/version.py +7 -0
  425. wx/py.typed +0 -0
  426. wx/ribbon.py +48 -0
  427. wx/ribbon.pyi +3099 -0
  428. wx/richtext.py +141 -0
  429. wx/richtext.pyi +13581 -0
  430. wx/siplib.cp315-win_amd64.pyd +0 -0
  431. wx/siplib.pyi +19 -0
  432. wx/stc.py +59 -0
  433. wx/stc.pyi +9918 -0
  434. wx/svg/__init__.py +363 -0
  435. wx/svg/_nanosvg.cp315-win_amd64.pyd +0 -0
  436. wx/tools/__init__.py +18 -0
  437. wx/tools/dbg.py +268 -0
  438. wx/tools/genaxmodule.py +50 -0
  439. wx/tools/helpviewer.py +92 -0
  440. wx/tools/img2img.py +85 -0
  441. wx/tools/img2png.py +54 -0
  442. wx/tools/img2py.py +306 -0
  443. wx/tools/img2xpm.py +54 -0
  444. wx/tools/pywxrc.py +951 -0
  445. wx/tools/wxget.py +254 -0
  446. wx/tools/wxget_docs_demo.py +183 -0
  447. wx/wxbase334u_net_vc140_x64.dll +0 -0
  448. wx/wxbase334u_vc140_x64.dll +0 -0
  449. wx/wxbase334u_xml_vc140_x64.dll +0 -0
  450. wx/wxmsw334u_adv_vc140_x64.dll +0 -0
  451. wx/wxmsw334u_aui_vc140_x64.dll +0 -0
  452. wx/wxmsw334u_core_vc140_x64.dll +0 -0
  453. wx/wxmsw334u_gl_vc140_x64.dll +0 -0
  454. wx/wxmsw334u_html_vc140_x64.dll +0 -0
  455. wx/wxmsw334u_media_vc140_x64.dll +0 -0
  456. wx/wxmsw334u_propgrid_vc140_x64.dll +0 -0
  457. wx/wxmsw334u_qa_vc140_x64.dll +0 -0
  458. wx/wxmsw334u_ribbon_vc140_x64.dll +0 -0
  459. wx/wxmsw334u_richtext_vc140_x64.dll +0 -0
  460. wx/wxmsw334u_stc_vc140_x64.dll +0 -0
  461. wx/wxmsw334u_webview_vc140_x64.dll +0 -0
  462. wx/wxmsw334u_xrc_vc140_x64.dll +0 -0
  463. wx/xml.py +18 -0
  464. wx/xml.pyi +728 -0
  465. wx/xrc.py +68 -0
  466. wx/xrc.pyi +896 -0
  467. wxpython-4.3.2.dist-info/METADATA +71 -0
  468. wxpython-4.3.2.dist-info/RECORD +472 -0
  469. wxpython-4.3.2.dist-info/WHEEL +5 -0
  470. wxpython-4.3.2.dist-info/entry_points.txt +13 -0
  471. wxpython-4.3.2.dist-info/licenses/LICENSE.txt +610 -0
  472. wxpython-4.3.2.dist-info/top_level.txt +1 -0
wx/lib/inspection.py ADDED
@@ -0,0 +1,1254 @@
1
+ #----------------------------------------------------------------------------
2
+ # Name: wx.lib.inspection
3
+ # Purpose: A widget inspection tool that allows easy introspection of
4
+ # all the live widgets and sizers in an application.
5
+ #
6
+ # Author: Robin Dunn
7
+ #
8
+ # Created: 26-Jan-2007
9
+ # Copyright: (c) 2007-2020 by Total Control Software
10
+ # Licence: wxWindows license
11
+ #
12
+ # Tags: py3-port, phoenix-port, documented
13
+ #----------------------------------------------------------------------------
14
+
15
+ # NOTE: This class was originally based on ideas sent to the
16
+ # wxPython-users mail list by Dan Eloff. See also
17
+ # wx.lib.mixins.inspect for a class that can be mixed-in with wx.App
18
+ # to provide Hot-Key access to the inspection tool.
19
+
20
+ """
21
+ This modules provides the :class:`~wx.lib.inspection.InspectionTool` and
22
+ everything else needed to provide the Widget Inspection Tool (WIT).
23
+ """
24
+
25
+
26
+ import wx
27
+ import wx.py
28
+ import wx.stc
29
+ #import wx.aui as aui
30
+ import wx.lib.agw.aui as aui
31
+ import wx.lib.utils as utils
32
+ import sys
33
+ import inspect
34
+
35
+ #----------------------------------------------------------------------------
36
+
37
+ class InspectionTool:
38
+ """
39
+ The :class:`InspectionTool` is a singleton that manages creating and
40
+ showing an :class:`InspectionFrame`.
41
+ """
42
+
43
+ # Note: This is the Borg design pattern which ensures that all
44
+ # instances of this class are actually using the same set of
45
+ # instance data. See
46
+ # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531
47
+ __shared_state = None
48
+
49
+ def __init__(self):
50
+ if not InspectionTool.__shared_state:
51
+ InspectionTool.__shared_state = self.__dict__
52
+ else:
53
+ self.__dict__ = InspectionTool.__shared_state
54
+
55
+ if not hasattr(self, 'initialized'):
56
+ self.initialized = False
57
+
58
+
59
+ def Init(self, pos=wx.DefaultPosition, size=wx.Size(850,700),
60
+ config=None, locals=None, app=None):
61
+ """
62
+ Init is used to set some parameters that will be used later
63
+ when the inspection tool is shown. Suitable defaults will be
64
+ used for all of these parameters if they are not provided.
65
+
66
+ :param `pos`: The default position to show the frame at
67
+ :param `size`: The default size of the frame
68
+ :param `config`: A :class:`Config` object to be used to store layout
69
+ and other info to when the inspection frame is closed.
70
+ This info will be restored the next time the inspection
71
+ frame is used.
72
+ :param `locals`: A dictionary of names to be added to the PyCrust
73
+ namespace.
74
+ :param `app`: A reference to the :class:`App` object.
75
+ """
76
+ self._frame = None
77
+ self._pos = pos
78
+ self._size = size
79
+ self._config = config
80
+ self._locals = locals
81
+ self._app = app
82
+ if not self._app:
83
+ self._app = wx.GetApp()
84
+ self.initialized = True
85
+
86
+
87
+ def Show(self, selectObj=None, refreshTree=False):
88
+ """
89
+ Creates the inspection frame if it hasn't been already, and
90
+ raises it if necessary.
91
+
92
+ :param `selectObj`: Pass a widget or sizer to have that object be
93
+ preselected in widget tree.
94
+ :param boolean `refreshTree`: rebuild the widget tree, default False
95
+
96
+ """
97
+ if not self.initialized:
98
+ self.Init()
99
+
100
+ parent = self._app.GetTopWindow()
101
+ if not selectObj:
102
+ selectObj = parent
103
+ if not self._frame:
104
+ self._frame = InspectionFrame( parent=parent,
105
+ pos=self._pos,
106
+ size=self._size,
107
+ config=self._config,
108
+ locals=self._locals,
109
+ app=self._app)
110
+ if selectObj:
111
+ self._frame.SetObj(selectObj)
112
+ if refreshTree:
113
+ self._frame.RefreshTree()
114
+ self._frame.Show()
115
+ if self._frame.IsIconized():
116
+ self._frame.Iconize(False)
117
+ self._frame.Raise()
118
+
119
+
120
+ #----------------------------------------------------------------------------
121
+
122
+
123
+ class InspectionFrame(wx.Frame):
124
+ """
125
+ This class is the frame that holds the wxPython inspection tools.
126
+ The toolbar and AUI splitters/floating panes are also managed
127
+ here. The contents of the tool windows are handled by other
128
+ classes.
129
+ """
130
+ def __init__(self, wnd=None, locals=None, config=None,
131
+ app=None, title="wxPython Widget Inspection Tool",
132
+ *args, **kw):
133
+ kw['title'] = title
134
+ wx.Frame.__init__(self, *args, **kw)
135
+
136
+ self.SetExtraStyle(wx.WS_EX_BLOCK_EVENTS)
137
+ self.includeSizers = False
138
+ self.started = False
139
+
140
+ self.SetIcon(Icon.GetIcon())
141
+ self.MakeToolBar()
142
+ panel = wx.Panel(self, size=self.GetClientSize())
143
+
144
+ # tell FrameManager to manage this frame
145
+ self.mgr = aui.AuiManager(panel,
146
+ aui.AUI_MGR_DEFAULT
147
+ | aui.AUI_MGR_TRANSPARENT_DRAG
148
+ | aui.AUI_MGR_ALLOW_ACTIVE_PANE)
149
+
150
+ # make the child tools
151
+ self.tree = InspectionTree(panel, size=(100,300))
152
+ self.info = InspectionInfoPanel(panel,
153
+ style=wx.NO_BORDER,
154
+ )
155
+
156
+ if not locals:
157
+ locals = {}
158
+ myIntroText = (
159
+ "Python %s on %s, wxPython %s\n"
160
+ "NOTE: The 'obj' variable refers to the object selected in the tree."
161
+ % (sys.version.split()[0], sys.platform, wx.version()))
162
+ self.crust = wx.py.crust.Crust(panel, locals=locals,
163
+ intro=myIntroText,
164
+ showInterpIntro=False,
165
+ style=wx.NO_BORDER,
166
+ )
167
+ self.locals = self.crust.shell.interp.locals
168
+ self.crust.shell.interp.introText = ''
169
+ self.locals['obj'] = self.obj = wnd
170
+ self.locals['app'] = app
171
+ self.locals['wx'] = wx
172
+ wx.CallAfter(self._postStartup)
173
+
174
+ # put the chlid tools in AUI panes
175
+ self.mgr.AddPane(self.info,
176
+ aui.AuiPaneInfo().Name("info").Caption("Object Info").
177
+ CenterPane().CaptionVisible(True).
178
+ CloseButton(False).MaximizeButton(True)
179
+ )
180
+ self.mgr.AddPane(self.tree,
181
+ aui.AuiPaneInfo().Name("tree").Caption("Widget Tree").
182
+ CaptionVisible(True).Left().Dockable(True).Floatable(True).
183
+ BestSize((280,200)).CloseButton(False).MaximizeButton(True)
184
+ )
185
+ self.mgr.AddPane(self.crust,
186
+ aui.AuiPaneInfo().Name("crust").Caption("PyCrust").
187
+ CaptionVisible(True).Bottom().Dockable(True).Floatable(True).
188
+ BestSize((400,200)).CloseButton(False).MaximizeButton(True)
189
+ )
190
+
191
+ self.mgr.Update()
192
+
193
+ if config is None:
194
+ config = wx.Config('wxpyinspector')
195
+ self.config = config
196
+ self.Bind(wx.EVT_CLOSE, self.OnClose)
197
+ if self.Parent:
198
+ tlw = self.Parent.GetTopLevelParent()
199
+ tlw.Bind(wx.EVT_CLOSE, self.OnClose)
200
+ self.LoadSettings(self.config)
201
+ self.crust.shell.lineNumbers = False
202
+ self.crust.shell.setDisplayLineNumbers(False)
203
+ self.crust.shell.SetMarginWidth(1, 0)
204
+
205
+
206
+ def MakeToolBar(self):
207
+ tbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.TB_FLAT | wx.TB_TEXT | wx.NO_BORDER )
208
+ tbar.SetToolBitmapSize((24,24))
209
+
210
+ refreshBmp = wx.BitmapBundle(Refresh.GetBitmap())
211
+ findWidgetBmp = wx.BitmapBundle(Find.GetBitmap())
212
+ showSizersBmp = wx.BitmapBundle(ShowSizers.GetBitmap())
213
+ expandTreeBmp = wx.BitmapBundle(ExpandTree.GetBitmap())
214
+ collapseTreeBmp = wx.BitmapBundle(CollapseTree.GetBitmap())
215
+ highlightItemBmp = wx.BitmapBundle(HighlightItem.GetBitmap())
216
+ evtWatcherBmp = wx.BitmapBundle(EvtWatcher.GetBitmap())
217
+
218
+ toggleFillingBmp = wx.BitmapBundle(ShowFilling.GetBitmap())
219
+
220
+ refreshTool = tbar.AddTool(-1, 'Refresh', refreshBmp,
221
+ shortHelp = 'Refresh widget tree (F1)')
222
+ findWidgetTool = tbar.AddTool(-1, 'Find', findWidgetBmp,
223
+ shortHelp='Find new target widget. (F2) Click here and\nthen on another widget in the app.')
224
+ showSizersTool = tbar.AddTool(-1, 'Sizers', showSizersBmp,
225
+ shortHelp='Include sizers in widget tree (F3)',
226
+ kind=wx.ITEM_CHECK)
227
+ expandTreeTool = tbar.AddTool(-1, 'Expand', expandTreeBmp,
228
+ shortHelp='Expand all tree items (F4)')
229
+ collapseTreeTool = tbar.AddTool(-1, 'Collapse', collapseTreeBmp,
230
+ shortHelp='Collapse all tree items (F5)')
231
+ highlightItemTool = tbar.AddTool(-1, 'Highlight', highlightItemBmp,
232
+ shortHelp='Attempt to highlight live item (F6)')
233
+ evtWatcherTool = tbar.AddTool(-1, 'Events', evtWatcherBmp,
234
+ shortHelp='Watch the events of the selected item (F7)')
235
+
236
+ toggleFillingTool = tbar.AddTool(-1, 'Filling', toggleFillingBmp,
237
+ shortHelp='Show PyCrust \'filling\' (F8)',
238
+ kind=wx.ITEM_CHECK)
239
+ tbar.Realize()
240
+
241
+ self.Bind(wx.EVT_TOOL, self.OnRefreshTree, refreshTool)
242
+ self.Bind(wx.EVT_TOOL, self.OnFindWidget, findWidgetTool)
243
+ self.Bind(wx.EVT_TOOL, self.OnShowSizers, showSizersTool)
244
+ self.Bind(wx.EVT_TOOL, self.OnExpandTree, expandTreeTool)
245
+ self.Bind(wx.EVT_TOOL, self.OnCollapseTree, collapseTreeTool)
246
+ self.Bind(wx.EVT_TOOL, self.OnHighlightItem, highlightItemTool)
247
+ self.Bind(wx.EVT_TOOL, self.OnWatchEvents, evtWatcherTool)
248
+ self.Bind(wx.EVT_TOOL, self.OnToggleFilling, toggleFillingTool)
249
+ self.Bind(wx.EVT_UPDATE_UI, self.OnShowSizersUI, showSizersTool)
250
+ self.Bind(wx.EVT_UPDATE_UI, self.OnWatchEventsUI, evtWatcherTool)
251
+ self.Bind(wx.EVT_UPDATE_UI, self.OnToggleFillingUI, toggleFillingTool)
252
+
253
+ tbl = wx.AcceleratorTable(
254
+ [(wx.ACCEL_NORMAL, wx.WXK_F1, refreshTool.GetId()),
255
+ (wx.ACCEL_NORMAL, wx.WXK_F2, findWidgetTool.GetId()),
256
+ (wx.ACCEL_NORMAL, wx.WXK_F3, showSizersTool.GetId()),
257
+ (wx.ACCEL_NORMAL, wx.WXK_F4, expandTreeTool.GetId()),
258
+ (wx.ACCEL_NORMAL, wx.WXK_F5, collapseTreeTool.GetId()),
259
+ (wx.ACCEL_NORMAL, wx.WXK_F6, highlightItemTool.GetId()),
260
+ (wx.ACCEL_NORMAL, wx.WXK_F7, evtWatcherTool.GetId()),
261
+ (wx.ACCEL_NORMAL, wx.WXK_F8, toggleFillingTool.GetId()),
262
+ ])
263
+ self.SetAcceleratorTable(tbl)
264
+
265
+
266
+ def _postStartup(self):
267
+ if self.crust.ToolsShown():
268
+ self.crust.ToggleTools()
269
+ self.UpdateInfo()
270
+ self.started = True
271
+
272
+
273
+ def OnClose(self, evt):
274
+ evt.Skip()
275
+ if not self:
276
+ return
277
+ self.SaveSettings(self.config)
278
+ if hasattr(self, 'mgr'):
279
+ self.mgr.UnInit()
280
+ del self.mgr
281
+ if self.Parent:
282
+ tlw = self.Parent.GetTopLevelParent()
283
+ tlw.Unbind(wx.EVT_CLOSE, handler=self.OnClose)
284
+
285
+
286
+ def UpdateInfo(self):
287
+ self.info.UpdateInfo(self.obj)
288
+
289
+
290
+ def SetObj(self, obj):
291
+ if self.obj is obj:
292
+ return
293
+ self.locals['obj'] = self.obj = obj
294
+ self.UpdateInfo()
295
+ if not self.tree.built:
296
+ self.tree.BuildTree(obj, includeSizers=self.includeSizers)
297
+ else:
298
+ self.tree.SelectObj(obj)
299
+
300
+
301
+ def HighlightCurrentItem(self):
302
+ """
303
+ Draw a highlight rectangle around the item represented by the
304
+ current tree selection.
305
+ """
306
+ if not hasattr(self, 'highlighter'):
307
+ self.highlighter = _InspectionHighlighter()
308
+ self.highlighter.HighlightCurrentItem(self.tree)
309
+
310
+
311
+ def RefreshTree(self):
312
+ self.tree.BuildTree(self.obj, includeSizers=self.includeSizers)
313
+
314
+
315
+ def OnRefreshTree(self, evt):
316
+ self.RefreshTree()
317
+ self.UpdateInfo()
318
+
319
+
320
+ def OnFindWidget(self, evt):
321
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
322
+ self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnCaptureLost)
323
+ self.CaptureMouse()
324
+ self.finding = wx.BusyInfo("Click on any widget in the app...")
325
+
326
+
327
+ def OnCaptureLost(self, evt):
328
+ self.Unbind(wx.EVT_LEFT_DOWN)
329
+ self.Unbind(wx.EVT_MOUSE_CAPTURE_LOST)
330
+ del self.finding
331
+
332
+ def OnLeftDown(self, evt):
333
+ self.ReleaseMouse()
334
+ wnd, pt = wx.FindWindowAtPointer()
335
+ if wnd is not None:
336
+ self.SetObj(wnd)
337
+ else:
338
+ wx.Bell()
339
+ self.OnCaptureLost(evt)
340
+
341
+
342
+ def OnShowSizers(self, evt):
343
+ self.includeSizers = not self.includeSizers
344
+ self.RefreshTree()
345
+
346
+
347
+ def OnExpandTree(self, evt):
348
+ current = self.tree.GetSelection()
349
+ self.tree.ExpandAll()
350
+ self.tree.EnsureVisible(current)
351
+
352
+
353
+ def OnCollapseTree(self, evt):
354
+ current = self.tree.GetSelection()
355
+ self.tree.CollapseAll()
356
+ self.tree.EnsureVisible(current)
357
+ self.tree.SelectItem(current)
358
+
359
+
360
+ def OnHighlightItem(self, evt):
361
+ self.HighlightCurrentItem()
362
+
363
+
364
+ def OnWatchEvents(self, evt):
365
+ item = self.tree.GetSelection()
366
+ obj = self.tree.GetItemData(item)
367
+ if isinstance(obj, wx.Window):
368
+ import wx.lib.eventwatcher as ew
369
+ watcher = ew.EventWatcher(self)
370
+ watcher.watch(obj)
371
+ watcher.Show()
372
+
373
+ def OnWatchEventsUI(self, evt):
374
+ item = self.tree.GetSelection()
375
+ if item:
376
+ obj = self.tree.GetItemData(item)
377
+ evt.Enable(isinstance(obj, wx.Window))
378
+
379
+
380
+ def OnToggleFilling(self, evt):
381
+ self.crust.ToggleTools()
382
+
383
+
384
+ def OnShowSizersUI(self, evt):
385
+ evt.Check(self.includeSizers)
386
+
387
+
388
+ def OnToggleFillingUI(self, evt):
389
+ if self.started:
390
+ evt.Check(self.crust.ToolsShown())
391
+
392
+
393
+ def LoadSettings(self, config):
394
+ self.crust.LoadSettings(config)
395
+ self.info.LoadSettings(config)
396
+
397
+ pos = wx.Point(config.ReadInt('Window/PosX', -1),
398
+ config.ReadInt('Window/PosY', -1))
399
+
400
+ size = wx.Size(config.ReadInt('Window/Width', -1),
401
+ config.ReadInt('Window/Height', -1))
402
+ self.SetSize(size)
403
+ self.Move(pos)
404
+ rect = utils.AdjustRectToScreen(self.GetRect())
405
+ self.SetRect(rect)
406
+
407
+ perspective = config.Read('perspective1', '')
408
+ if perspective:
409
+ try:
410
+ self.mgr.LoadPerspective(perspective)
411
+ except Exception:
412
+ # ignore bad perspective string errors
413
+ pass
414
+ self.includeSizers = config.ReadBool('includeSizers', False)
415
+
416
+
417
+ def SaveSettings(self, config):
418
+ self.crust.SaveSettings(config)
419
+ self.info.SaveSettings(config)
420
+
421
+ if not self.IsIconized() and not self.IsMaximized():
422
+ w, h = self.GetSize()
423
+ config.WriteInt('Window/Width', w)
424
+ config.WriteInt('Window/Height', h)
425
+
426
+ px, py = self.GetPosition()
427
+ config.WriteInt('Window/PosX', px)
428
+ config.WriteInt('Window/PosY', py)
429
+
430
+ if hasattr(self, "mgr"):
431
+ perspective = self.mgr.SavePerspective()
432
+ config.Write('perspective1', perspective)
433
+ config.WriteBool('includeSizers', self.includeSizers)
434
+
435
+ #---------------------------------------------------------------------------
436
+
437
+ # should inspection frame (and children) be includeed in the tree?
438
+ INCLUDE_INSPECTOR = True
439
+
440
+ USE_CUSTOMTREECTRL = False
441
+ if USE_CUSTOMTREECTRL:
442
+ import wx.lib.agw.customtreectrl as CT
443
+ TreeBaseClass = CT.CustomTreeCtrl
444
+ else:
445
+ TreeBaseClass = wx.TreeCtrl
446
+
447
+ class InspectionTree(TreeBaseClass):
448
+ """
449
+ All of the widgets in the app, and optionally their sizers, are
450
+ loaded into this tree.
451
+ """
452
+ def __init__(self, *args, **kw):
453
+ #s = kw.get('style', 0)
454
+ #kw['style'] = s | wx.TR_DEFAULT_STYLE | wx.TR_HIDE_ROOT
455
+ TreeBaseClass.__init__(self, *args, **kw)
456
+ self.roots = []
457
+ self.built = False
458
+ self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelectionChanged)
459
+ self.toolFrame = wx.GetTopLevelParent(self)
460
+ if 'wxMac' in wx.PlatformInfo:
461
+ self.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
462
+
463
+
464
+ def BuildTree(self, startWidget, includeSizers=False, expandFrame=False):
465
+ if self.GetCount():
466
+ self.DeleteAllItems()
467
+ self.roots = []
468
+ self.built = False
469
+
470
+ realRoot = self.AddRoot('Top-level Windows')
471
+
472
+ for w in wx.GetTopLevelWindows():
473
+ if w is wx.GetTopLevelParent(self) and not INCLUDE_INSPECTOR:
474
+ continue
475
+ root = self._AddWidget(realRoot, w, includeSizers)
476
+ self.roots.append(root)
477
+
478
+ # Expand the subtree containing the startWidget, and select it.
479
+ if not startWidget or not isinstance(startWidget, wx.Window):
480
+ startWidget = wx.GetApp().GetTopWindow()
481
+ if expandFrame:
482
+ top = wx.GetTopLevelParent(startWidget)
483
+ topItem = self.FindWidgetItem(top)
484
+ if topItem:
485
+ self.ExpandAllChildren(topItem)
486
+ self.built = True
487
+ self.SelectObj(startWidget)
488
+
489
+
490
+ def _AddWidget(self, parentItem, widget, includeSizers):
491
+ text = self.GetTextForWidget(widget)
492
+ item = self.AppendItem(parentItem, text)
493
+ self.SetItemData(item, widget)
494
+
495
+ # Add the sizer and widgets in the sizer, if we're showing them
496
+ widgetsInSizer = []
497
+ if includeSizers and widget.GetSizer() is not None:
498
+ widgetsInSizer = self._AddSizer(item, widget.GetSizer())
499
+
500
+ # Add any children not in the sizer, or all children if we're
501
+ # not showing the sizers
502
+ for child in widget.GetChildren():
503
+ if (not child in widgetsInSizer and
504
+ (not child.IsTopLevel() or
505
+ isinstance(child, wx.PopupWindow))):
506
+ self._AddWidget(item, child, includeSizers)
507
+
508
+ return item
509
+
510
+
511
+ def _AddSizer(self, parentItem, sizer):
512
+ widgets = []
513
+ text = self.GetTextForSizer(sizer)
514
+ item = self.AppendItem(parentItem, text)
515
+ self.SetItemData(item, sizer)
516
+ self.SetItemTextColour(item, "blue")
517
+
518
+ for si in sizer.GetChildren():
519
+ if si.IsWindow():
520
+ w = si.GetWindow()
521
+ self._AddWidget(item, w, True)
522
+ widgets.append(w)
523
+ elif si.IsSizer():
524
+ ss = si.GetSizer()
525
+ widgets += self._AddSizer(item, ss)
526
+ ss._parentSizer = sizer
527
+ else:
528
+ i = self.AppendItem(item, "Spacer")
529
+ self.SetItemData(i, si)
530
+ self.SetItemTextColour(i, "blue")
531
+ return widgets
532
+
533
+
534
+ def FindWidgetItem(self, widget):
535
+ """
536
+ Find the tree item for a widget.
537
+ """
538
+ for item in self.roots:
539
+ found = self._FindWidgetItem(widget, item)
540
+ if found:
541
+ return found
542
+ return None
543
+
544
+ def _FindWidgetItem(self, widget, item):
545
+ if self.GetItemData(item) is widget:
546
+ return item
547
+ child, cookie = self.GetFirstChild(item)
548
+ while child:
549
+ found = self._FindWidgetItem(widget, child)
550
+ if found:
551
+ return found
552
+ child, cookie = self.GetNextChild(item, cookie)
553
+ return None
554
+
555
+
556
+ def GetTextForWidget(self, widget):
557
+ """
558
+ Returns the string to be used in the tree for a widget
559
+ """
560
+ if hasattr(widget, 'GetName'):
561
+ return "%s (\"%s\")" % (widget.__class__.__name__, widget.GetName())
562
+ return widget.__class__.__name__
563
+
564
+
565
+ def GetTextForSizer(self, sizer):
566
+ """
567
+ Returns the string to be used in the tree for a sizer
568
+ """
569
+ return "%s" % sizer.__class__.__name__
570
+
571
+
572
+ def SelectObj(self, obj):
573
+ item = self.FindWidgetItem(obj)
574
+ if item:
575
+ self.EnsureVisible(item)
576
+ self.SelectItem(item)
577
+
578
+
579
+ def OnSelectionChanged(self, evt):
580
+ item = evt.GetItem()
581
+ if item:
582
+ obj = self.GetItemData(item)
583
+ self.toolFrame.SetObj(obj)
584
+
585
+
586
+ #---------------------------------------------------------------------------
587
+
588
+ class InspectionInfoPanel(wx.stc.StyledTextCtrl):
589
+ """
590
+ Used to display information about the currently selected items.
591
+ Currently just a read-only :class:`stc.StyledTextCtrl` with some plain
592
+ text. Should probably add some styles to make things easier to
593
+ read.
594
+ """
595
+ def __init__(self, *args, **kw):
596
+ wx.stc.StyledTextCtrl.__init__(self, *args, **kw)
597
+
598
+ FACES = wx.py.editwindow.get_faces()
599
+ self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT,
600
+ "face:%(mono)s,size:%(size)d,back:%(backcol)s" % FACES)
601
+ self.StyleClearAll()
602
+ self.SetReadOnly(True)
603
+ self.SetMarginType(1, 0)
604
+ self.SetMarginWidth(1, 0)
605
+ self.SetSelForeground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT))
606
+ self.SetSelBackground(True, wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT))
607
+
608
+
609
+ def LoadSettings(self, config):
610
+ zoom = config.ReadInt('View/Zoom/Info', 0)
611
+ self.SetZoom(zoom)
612
+
613
+ def SaveSettings(self, config):
614
+ config.WriteInt('View/Zoom/Info', self.GetZoom())
615
+
616
+
617
+ def UpdateInfo(self, obj):
618
+ st = []
619
+ if not obj:
620
+ st.append("Item is None or has been destroyed.")
621
+
622
+ elif isinstance(obj, wx.Window):
623
+ st += self.FmtWidget(obj)
624
+
625
+ elif isinstance(obj, wx.Sizer):
626
+ st += self.FmtSizer(obj)
627
+
628
+ elif isinstance(obj, wx.SizerItem):
629
+ st += self.FmtSizerItem(obj)
630
+
631
+ self.SetReadOnly(False)
632
+ self.SetText('\n'.join(st))
633
+ self.SetReadOnly(True)
634
+
635
+
636
+ def Fmt(self, name, value):
637
+ if isinstance(value, str):
638
+ return " %s = '%s'" % (name, value)
639
+ else:
640
+ return " %s = %s" % (name, value)
641
+
642
+
643
+ def FmtWidget(self, obj):
644
+ def _countChildren(children):
645
+ count = 0
646
+ for child in children:
647
+ if not child.IsTopLevel():
648
+ count += 1
649
+ count += _countChildren(child.GetChildren())
650
+ return count
651
+ def _countAllChildren(children):
652
+ count = 0
653
+ for child in children:
654
+ count += 1
655
+ count += _countAllChildren(child.GetChildren())
656
+ return count
657
+
658
+ count = len([c for c in obj.GetChildren() if not c.IsTopLevel()])
659
+ rcount = _countChildren(obj.GetChildren())
660
+ tlwcount = _countAllChildren(obj.GetChildren())
661
+
662
+ st = ["Widget:"]
663
+ if hasattr(obj, 'GetName'):
664
+ st.append(self.Fmt('name', obj.GetName()))
665
+ st.append(self.Fmt('class', obj.__class__))
666
+ st.append(self.Fmt('bases', obj.__class__.__bases__))
667
+ st.append(self.Fmt('module', inspect.getmodule(obj)))
668
+ if hasattr(obj, 'this'):
669
+ st.append(self.Fmt('this', repr(obj.this)))
670
+ st.append(self.Fmt('id', obj.GetId()))
671
+ st.append(self.Fmt('style', obj.GetWindowStyle()))
672
+ st.append(self.Fmt('pos', obj.GetPosition()))
673
+ st.append(self.Fmt('size', obj.GetSize()))
674
+ st.append(self.Fmt('minsize', obj.GetMinSize()))
675
+ st.append(self.Fmt('bestsize', obj.GetBestSize()))
676
+ st.append(self.Fmt('client size', obj.GetClientSize()))
677
+ st.append(self.Fmt('virtual size',obj.GetVirtualSize()))
678
+ st.append(self.Fmt('IsEnabled', obj.IsEnabled()))
679
+ st.append(self.Fmt('IsShown', obj.IsShown()))
680
+ st.append(self.Fmt('IsFrozen', obj.IsFrozen()))
681
+ st.append(self.Fmt('fg color', obj.GetForegroundColour()))
682
+ st.append(self.Fmt('bg color', obj.GetBackgroundColour()))
683
+ st.append(self.Fmt('label', obj.GetLabel()))
684
+ if hasattr(obj, 'GetTitle'):
685
+ st.append(self.Fmt('title', obj.GetTitle()))
686
+ if hasattr(obj, 'GetValue'):
687
+ try:
688
+ st.append(self.Fmt('value', obj.GetValue()))
689
+ except Exception:
690
+ pass
691
+ st.append(' child count = %d (direct) %d (recursive) %d (include TLWs)' %
692
+ (count, rcount, tlwcount))
693
+ if obj.GetContainingSizer() is not None:
694
+ st.append('')
695
+ sizer = obj.GetContainingSizer()
696
+ st += self.FmtSizerItem(sizer.GetItem(obj))
697
+ return st
698
+
699
+
700
+ def FmtSizerItem(self, obj):
701
+ if obj is None:
702
+ return ['SizerItem: None']
703
+
704
+ st = ['SizerItem:']
705
+ st.append(self.Fmt('proportion', obj.GetProportion()))
706
+ st.append(self.Fmt('flag',
707
+ FlagsFormatter(itemFlags, obj.GetFlag())))
708
+ st.append(self.Fmt('border', obj.GetBorder()))
709
+ st.append(self.Fmt('pos', obj.GetPosition()))
710
+ st.append(self.Fmt('size', obj.GetSize()))
711
+ st.append(self.Fmt('minsize', obj.GetMinSize()))
712
+ st.append(self.Fmt('ratio', obj.GetRatio()))
713
+ st.append(self.Fmt('IsWindow', obj.IsWindow()))
714
+ st.append(self.Fmt('IsSizer', obj.IsSizer()))
715
+ st.append(self.Fmt('IsSpacer', obj.IsSpacer()))
716
+ st.append(self.Fmt('IsShown', obj.IsShown()))
717
+ if isinstance(obj, wx.GBSizerItem):
718
+ st.append(self.Fmt('cellpos', obj.GetPos()))
719
+ st.append(self.Fmt('cellspan', obj.GetSpan()))
720
+ st.append(self.Fmt('endpos', obj.GetEndPos()))
721
+ return st
722
+
723
+
724
+ def FmtSizer(self, obj):
725
+ st = ['Sizer:']
726
+ st.append(self.Fmt('class', obj.__class__))
727
+ if hasattr(obj, 'this'):
728
+ st.append(self.Fmt('this', repr(obj.this)))
729
+ st.append(self.Fmt('pos', obj.GetPosition()))
730
+ st.append(self.Fmt('size', obj.GetSize()))
731
+ st.append(self.Fmt('minsize', obj.GetMinSize()))
732
+ if isinstance(obj, wx.BoxSizer):
733
+ st.append(self.Fmt('orientation',
734
+ FlagsFormatter(orientFlags, obj.GetOrientation())))
735
+ if isinstance(obj, wx.GridSizer):
736
+ st.append(self.Fmt('cols', obj.GetCols()))
737
+ st.append(self.Fmt('rows', obj.GetRows()))
738
+ st.append(self.Fmt('vgap', obj.GetVGap()))
739
+ st.append(self.Fmt('hgap', obj.GetHGap()))
740
+ if isinstance(obj, wx.FlexGridSizer):
741
+ st.append(self.Fmt('rowheights', obj.GetRowHeights()))
742
+ st.append(self.Fmt('colwidths', obj.GetColWidths()))
743
+ st.append(self.Fmt('flexdir',
744
+ FlagsFormatter(orientFlags, obj.GetFlexibleDirection())))
745
+ st.append(self.Fmt('nonflexmode',
746
+ FlagsFormatter(flexmodeFlags, obj.GetNonFlexibleGrowMode())))
747
+ if isinstance(obj, wx.GridBagSizer):
748
+ st.append(self.Fmt('emptycell', obj.GetEmptyCellSize()))
749
+
750
+ if hasattr(obj, '_parentSizer'):
751
+ st.append('')
752
+ st += self.FmtSizerItem(obj._parentSizer.GetItem(obj))
753
+
754
+ return st
755
+
756
+
757
+ class FlagsFormatter(object):
758
+ def __init__(self, d, val):
759
+ self.d = d
760
+ self.val = val
761
+
762
+ def __str__(self):
763
+ st = []
764
+ for k in self.d:
765
+ if self.val & k:
766
+ st.append(self.d[k])
767
+ if st:
768
+ return '|'.join(st)
769
+ else:
770
+ return '0'
771
+
772
+ orientFlags = {
773
+ wx.HORIZONTAL : 'wx.HORIZONTAL',
774
+ wx.VERTICAL : 'wx.VERTICAL',
775
+ }
776
+
777
+ itemFlags = {
778
+ wx.TOP : 'wx.TOP',
779
+ wx.BOTTOM : 'wx.BOTTOM',
780
+ wx.LEFT : 'wx.LEFT',
781
+ wx.RIGHT : 'wx.RIGHT',
782
+ # wx.ALL : 'wx.ALL',
783
+ wx.EXPAND : 'wx.EXPAND',
784
+ # wx.GROW : 'wx.GROW',
785
+ wx.SHAPED : 'wx.SHAPED',
786
+ wx.STRETCH_NOT : 'wx.STRETCH_NOT',
787
+ # wx.ALIGN_CENTER : 'wx.ALIGN_CENTER',
788
+ wx.ALIGN_LEFT : 'wx.ALIGN_LEFT',
789
+ wx.ALIGN_RIGHT : 'wx.ALIGN_RIGHT',
790
+ wx.ALIGN_TOP : 'wx.ALIGN_TOP',
791
+ wx.ALIGN_BOTTOM : 'wx.ALIGN_BOTTOM',
792
+ wx.ALIGN_CENTER_VERTICAL : 'wx.ALIGN_CENTER_VERTICAL',
793
+ wx.ALIGN_CENTER_HORIZONTAL : 'wx.ALIGN_CENTER_HORIZONTAL',
794
+ wx.ADJUST_MINSIZE : 'wx.ADJUST_MINSIZE',
795
+ wx.FIXED_MINSIZE : 'wx.FIXED_MINSIZE',
796
+ }
797
+
798
+ flexmodeFlags = {
799
+ wx.FLEX_GROWMODE_NONE : 'wx.FLEX_GROWMODE_NONE',
800
+ wx.FLEX_GROWMODE_SPECIFIED : 'wx.FLEX_GROWMODE_SPECIFIED',
801
+ wx.FLEX_GROWMODE_ALL : 'wx.FLEX_GROWMODE_ALL',
802
+ }
803
+
804
+
805
+
806
+
807
+ #---------------------------------------------------------------------------
808
+
809
+ class _InspectionHighlighter(object):
810
+ """
811
+ All the highlighting code. A separate class to help reduce the
812
+ clutter in InspectionFrame.
813
+ """
814
+
815
+ # should non TLWs be flashed too? Otherwise use a highlight rectangle
816
+ flashAll = False
817
+
818
+ color1 = 'red' # for widgets and sizers
819
+ color2 = 'red' # for item boundaries in sizers
820
+ color3 = '#00008B' # for items in sizers
821
+
822
+ highlightTime = 3000 # how long to display the highlights
823
+
824
+ # how to draw it
825
+ useOverlay = 'wxMac' in wx.PlatformInfo or 'gtk3' in wx.PlatformInfo
826
+
827
+
828
+ def __init__(self):
829
+ if self.useOverlay:
830
+ self.overlay = wx.Overlay()
831
+
832
+
833
+ def HighlightCurrentItem(self, tree):
834
+ """
835
+ Draw a highlight rectangle around the item represented by the
836
+ current tree selection.
837
+ """
838
+ item = tree.GetSelection()
839
+ obj = tree.GetItemData(item)
840
+
841
+ if isinstance(obj, wx.Window):
842
+ self.HighlightWindow(obj)
843
+
844
+ elif isinstance(obj, wx.Sizer):
845
+ self.HighlightSizer(obj)
846
+
847
+ elif isinstance(obj, wx.SizerItem): # Spacer
848
+ pItem = tree.GetItemParent(item)
849
+ sizer = tree.GetItemData(pItem)
850
+ self.HighlightSizerItem(obj, sizer)
851
+
852
+ else:
853
+ raise RuntimeError("unknown object type: %s" % obj.__class__.__name__)
854
+
855
+
856
+ def HighlightWindow(self, win):
857
+ rect = win.GetRect()
858
+ tlw = win.GetTopLevelParent()
859
+ if self.flashAll or tlw is win:
860
+ self.FlickerTLW(win)
861
+ return
862
+ else:
863
+ pos = self.FindHighlightPos(tlw, win.ClientToScreen((0,0)))
864
+ rect.SetPosition(pos)
865
+ self.DoHighlight(tlw, rect, self.color1)
866
+
867
+
868
+ def HighlightSizerItem(self, item, sizer, penWidth=2):
869
+ win = sizer.GetContainingWindow()
870
+ tlw = win.GetTopLevelParent()
871
+ rect = item.GetRect()
872
+ pos = rect.GetPosition()
873
+ pos = self.FindHighlightPos(tlw, win.ClientToScreen(pos))
874
+ rect.SetPosition(pos)
875
+ if rect.width < 1: rect.width = 1
876
+ if rect.height < 1: rect.height = 1
877
+ self.DoHighlight(tlw, rect, self.color1, penWidth)
878
+
879
+
880
+ def HighlightSizer(self, sizer):
881
+ # first do the outline of the whole sizer like normal
882
+ win = sizer.GetContainingWindow()
883
+ tlw = win.GetTopLevelParent()
884
+ pos = sizer.GetPosition()
885
+ pos = self.FindHighlightPos(tlw, win.ClientToScreen(pos))
886
+ rect = wx.Rect(pos, sizer.GetSize())
887
+ dc, dco = self.DoHighlight(tlw, rect, self.color1)
888
+
889
+ # Now highlight the actual items within the sizer. This may
890
+ # get overdrawn by the code below for item boundaries, but if
891
+ # there is border padding then this will help make it more
892
+ # obvious.
893
+ dc.SetPen(wx.Pen(self.color3, 1))
894
+ for item in sizer.GetChildren():
895
+ if item.IsShown():
896
+ if item.IsWindow():
897
+ r = item.GetWindow().GetRect()
898
+ elif item.IsSizer():
899
+ p = item.GetSizer().GetPosition()
900
+ s = item.GetSizer().GetSize()
901
+ r = wx.Rect(p,s)
902
+ else:
903
+ continue
904
+ r = self.AdjustRect(tlw, win, r)
905
+ dc.DrawRectangle(r)
906
+
907
+ # Next highlight the area allocated to each item in the sizer.
908
+ # Each kind of sizer will need to be done a little
909
+ # differently.
910
+ dc.SetPen(wx.Pen(self.color2, 1))
911
+
912
+ if isinstance(sizer, wx.WrapSizer):
913
+ for item in sizer.GetChildren():
914
+ ir = self.AdjustRect(tlw, win, item.Rect)
915
+ dc.DrawRectangle(ir)
916
+
917
+ # wx.BoxSizer, wx.StaticBoxSizer
918
+ elif isinstance(sizer, wx.BoxSizer):
919
+ # NOTE: we have to do some reverse-engineering here for
920
+ # borders because the sizer and sizer item don't give us
921
+ # enough information to know for sure where item
922
+ # (allocated) boundaries are, just the boundaries of the
923
+ # actual widgets. TODO: It would be nice to add something
924
+ # to wx.SizerItem that would give us the full bounds, but
925
+ # that will have to wait until 2.9...
926
+ x, y = rect.GetPosition()
927
+ if sizer.Orientation == wx.HORIZONTAL:
928
+ y1 = y + rect.height
929
+ for item in sizer.GetChildren():
930
+ ir = self.AdjustRect(tlw, win, item.Rect)
931
+ x = ir.x
932
+ if item.Flag & wx.LEFT:
933
+ x -= item.Border
934
+ dc.DrawLine(x, y, x, y1)
935
+ if item.IsSizer():
936
+ dc.DrawRectangle(ir)
937
+
938
+ if sizer.Orientation == wx.VERTICAL:
939
+ x1 = x + rect.width
940
+ for item in sizer.GetChildren():
941
+ ir = self.AdjustRect(tlw, win, item.Rect)
942
+ y = ir.y
943
+ if item.Flag & wx.TOP:
944
+ y -= item.Border
945
+ dc.DrawLine(x, y, x1, y)
946
+ if item.IsSizer():
947
+ dc.DrawRectangle(ir)
948
+
949
+ # wx.FlexGridSizer, wx.GridBagSizer
950
+ elif isinstance(sizer, wx.FlexGridSizer):
951
+ sizer.Layout()
952
+ y = rect.y
953
+ for rh in sizer.RowHeights[:-1]:
954
+ y += rh
955
+ dc.DrawLine(rect.x, y, rect.x+rect.width, y)
956
+ y+= sizer.VGap
957
+ dc.DrawLine(rect.x, y, rect.x+rect.width, y)
958
+ x = rect.x
959
+ for cw in sizer.ColWidths[:-1]:
960
+ x += cw
961
+ dc.DrawLine(x, rect.y, x, rect.y+rect.height)
962
+ x+= sizer.HGap
963
+ dc.DrawLine(x, rect.y, x, rect.y+rect.height)
964
+
965
+ # wx.GridSizer
966
+ elif isinstance(sizer, wx.GridSizer):
967
+ # NOTE: More reverse engineering (see above.) This time we
968
+ # need to determine what the sizer is using for row
969
+ # heights and column widths.
970
+ #rh = cw = 0
971
+ #for item in sizer.GetChildren():
972
+ # rh = max(rh, item.Size.height)
973
+ # cw = max(cw, item.Size.width)
974
+ cw = (rect.width - sizer.HGap*(sizer.Cols-1)) / sizer.Cols
975
+ rh = (rect.height - sizer.VGap*(sizer.Rows-1)) / sizer.Rows
976
+ y = rect.y
977
+ for i in range(sizer.Rows-1):
978
+ y += rh
979
+ dc.DrawLine(rect.x, y, rect.x+rect.width, y)
980
+ y+= sizer.VGap
981
+ dc.DrawLine(rect.x, y, rect.x+rect.width, y)
982
+ x = rect.x
983
+ for i in range(sizer.Cols-1):
984
+ x += cw
985
+ dc.DrawLine(x, rect.y, x, rect.y+rect.height)
986
+ x+= sizer.HGap
987
+ dc.DrawLine(x, rect.y, x, rect.y+rect.height)
988
+
989
+ # Anything else is probably a custom sizer, just highlight the items
990
+ else:
991
+ del dc, odc
992
+ for item in sizer.GetChildren():
993
+ self.HighlightSizerItem(item, sizer, 1)
994
+
995
+
996
+ def FindHighlightPos(self, tlw, pos):
997
+ if self.useOverlay:
998
+ # We'll be using a ClientDC in this case so adjust the
999
+ # position accordingly
1000
+ pos = tlw.ScreenToClient(pos)
1001
+ return pos
1002
+
1003
+
1004
+ def AdjustRect(self, tlw, win, rect):
1005
+ pos = self.FindHighlightPos(tlw, win.ClientToScreen(rect.Position))
1006
+ rect.Position = pos
1007
+ return wx.Rect(pos, rect.Size)
1008
+
1009
+
1010
+ def DoHighlight(self, tlw, rect, colour, penWidth=2):
1011
+ if not tlw.IsFrozen():
1012
+ tlw.Freeze()
1013
+
1014
+ if self.useOverlay:
1015
+ dc = wx.ClientDC(tlw)
1016
+ dco = wx.DCOverlay(self.overlay, dc)
1017
+ dco.Clear()
1018
+ else:
1019
+ dc = wx.ScreenDC()
1020
+ dco = None
1021
+
1022
+ dc.SetPen(wx.Pen(colour, penWidth))
1023
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
1024
+
1025
+ drawRect = wx.Rect(*rect)
1026
+ dc.DrawRectangle(drawRect)
1027
+
1028
+ drawRect.Inflate(2,2)
1029
+ if not self.useOverlay:
1030
+ pos = tlw.ScreenToClient(drawRect.GetPosition())
1031
+ drawRect.SetPosition(pos)
1032
+ wx.CallLater(self.highlightTime, self.DoUnhighlight, tlw, drawRect)
1033
+
1034
+ return dc, dco
1035
+
1036
+
1037
+ def DoUnhighlight(self, tlw, rect):
1038
+ if not tlw:
1039
+ return
1040
+ if tlw.IsFrozen():
1041
+ tlw.Thaw()
1042
+ if self.useOverlay:
1043
+ dc = wx.ClientDC(tlw)
1044
+ dco = wx.DCOverlay(self.overlay, dc)
1045
+ dco.Clear()
1046
+ del dc, dco
1047
+ self.overlay.Reset()
1048
+ else:
1049
+ tlw.RefreshRect(rect)
1050
+
1051
+
1052
+ def FlickerTLW(self, tlw):
1053
+ """
1054
+ Use a timer to alternate a TLW between shown and hidden state a
1055
+ few times. Use to highlight a TLW since drawing and clearing an
1056
+ outline is trickier.
1057
+ """
1058
+ self.flickerCount = 0
1059
+ tlw.Hide()
1060
+ self.cl = wx.CallLater(300, self._Toggle, tlw)
1061
+
1062
+
1063
+ def _Toggle(self, tlw):
1064
+ if tlw.IsShown():
1065
+ tlw.Hide()
1066
+ self.cl.Restart()
1067
+ else:
1068
+ tlw.Show()
1069
+ self.flickerCount += 1
1070
+ if self.flickerCount < 4:
1071
+ self.cl.Restart()
1072
+
1073
+
1074
+ #---------------------------------------------------------------------------
1075
+ from wx.lib.embeddedimage import PyEmbeddedImage
1076
+
1077
+ Refresh = PyEmbeddedImage(
1078
+ "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABehJ"
1079
+ "REFUSImdll1olNkZx3/vRzIxk5lJbMwmGHccP+JHS6VrYo3TKCvL0i0LLTRB8cbLitp6p9ib"
1080
+ "elHohVLT0BqXBnetqBQveiWF0oXiF+1FS4PUxFgbm0yYTN/JZL4nmcl7/r3IJMRlodAHDhwO"
1081
+ "z8d5/uf/PM+x+N9yADgDfAtwAAvwgafAJ8DfvsxIq3q4G86cuiHAB8C/gZLjOO/4vv8u8LWu"
1082
+ "rq4lgGQy2dTQ0JDZuXPn9snJyXmgGYgBnwMGcCzwBZb7BedbgJ+5rntk69atJdd1f/D69evX"
1083
+ "tm1bAwMDDA4ONlmWxYMHD5iYmGj0fT8BhGOx2Cezs7MdKysrfwZ+DCTXgmzMaovjOPdXs1tf"
1084
+ "nwJXgX8ODQ0plUqpXC7r9OnTAmZDodDNtra2zzba2Lb9AOj8MtjGAIVCIfX29ppDhw6Z1tZW"
1085
+ "AWpvb9fNmzf9dDqtUqmksbExPxQKCdC+ffvU29ur3t5eEw6H1wL9po7KunzgOM4/AB08eNBM"
1086
+ "TU3J8zxdunRJtm3r4sWLkqRCoaBkMilJunz5smzb1oULFzQ/P6/p6Wn19/cbQK7rvgQ+2hig"
1087
+ "Z/v27c8A9fX1yfM8JRIJJZNJzczMKJVKqVQqKZ/PK5fLqVgsKpVKaWZmRslkUolEQouLixoY"
1088
+ "GDCAotHo34H9bEijMZvNft7W1hYJBAJf9zyPeDxOR0cHoVCIxsZGarUalmVhWRbGGILBIJFI"
1089
+ "hGAwSK1WY3h4mIcPH1qVSuVue3v75cXFxQyQBzjQ09Pz3V27dn0jEon8qv5QmpmZ0crKirLZ"
1090
+ "rMrlsr4olUpF2WxW1WpVnucpGAyu4f8LYKfjOB8CBxzgSqFQ+NhxnI8zmUxfMBiMnD9/nmPH"
1091
+ "jtHY2Iht2xSLRcbHx3ny5AnPnz8nn88TCoXYtGkTxhh8f5WNExMTlMvlDtu2+4wx/cBugOeA"
1092
+ "4vG4Tp48qdHRUV+SisWicrmcJOnp06d6//331dDQINu2dfToUT169EiSlMvlVCgUJEm3bt3y"
1093
+ "BwcHdfz4cdm2rbpvXnR1dVVGRkaUy+WUz+eVTCbX95J07949NTQ0bOS6bt++LUnK5/PK5/Mq"
1094
+ "FApKp9NKpVIaHR1Vd3f3MvDCZa1nuC6+72NZFsFg8K0CkbQOA4AxBmPMWzrFYpFwOIxlWdi2"
1095
+ "jWVZAJYD/KhUKr2ztLTE48ePWVpaMocPH7Z838cYQyAQIJ/P8+rVK2ZnZ5HEkSNHGBoaIhqN"
1096
+ "sry8jG3bbN68mfv375uRkRHr2bNnjI+PO0DKAq4AvbZtNxljdnR0dMTOnDnDuXPnCIfDABQK"
1097
+ "BSYnJ5mensYYw44dO9i7dy/hcBhJVCoVRkZGGB4eJpfLzXV2ds5mMpmVarX6AqDDcZzj9cL4"
1098
+ "+f9L0+bmZgEKh8O3enp6+vbs2fN94D0HKEmqxWKxYDabPRqJRN47e/YsAwMDBINBXNfFGEOl"
1099
+ "UqFarVKtVtdhCQQCACwvL1Or1VhcXKRUKk3Ozc39cWFh4V/Ay7U32rWxVczPzyuRSMjzPHme"
1100
+ "p4WFBRUKhbcYk8lk5Hme0um0EomE0um04vG4AMVisWfAPoFl1wNsT8zNbV4jTaVSIRgMcv36"
1101
+ "daLRKFevXqWlpYVyuQxAS0sLN27cIBqNcu3aNZqamlhaWkKSABKJxBYgZoEQWEOrPenTOobq"
1102
+ "7+838Xjc7N+/X4BaWlo0Njbm5/N5ZbNZ3blzx+/s7BSg1tZWxeNxxePx9fYO3AUaV69brwOg"
1103
+ "qz4s1guqtbX1t+Fw+NfA7IkTJ5TL5ZTJZHTq1CkBb4BfAp9ttHFd93dA95pvF+AgNPwVksaY"
1104
+ "HwIV13W/2d3dnX/z5s1Pd+/e7TQ3N+9LJpPdd+/exXVdPM/Dtu2XxpiRWCzWJOmrc3NzbbVa"
1105
+ "7S8rKyuXgASrqBh+AnY9i43z+aM6bbf29PR8LxAI/AlQd3f38rZt25YdxxHwB8dxvg28C+wF"
1106
+ "vrMOS30MrGdwBSytDmgLMBb8fo1eU1NT7cAE8JVEIrHx2zLt+/5/gJm66mT9oharPwsL4L/1"
1107
+ "GXlKb/xX4wAAAABJRU5ErkJggg==")
1108
+
1109
+ Find = PyEmbeddedImage(
1110
+ "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABgRJ"
1111
+ "REFUSIm1lU1oG9sVx/9z5440+kBWJUvGDZESXuskZPMIwVaoybNp4niXEChdJPDAIWk+IGnA"
1112
+ "i1Ioz9208apk10WcZFMI3Zgugrww6cNxKcakdoK/ghU7k5EsW2PLljXfc2duFw/5uaRv1x4Y"
1113
+ "uHc4c3/38P+fM8D/OYTDm7Gxsd/4vv/H169fQ5IkAIDjODh16hSy2ey3t27d6geAJ0+eFDVN"
1114
+ "G1xYWEA4HAYAeJ6H3t5eUEp/f+PGjZHPSOPj48P37t1j+XyeAzh4QqEQLxQK/Pr1639v5V67"
1115
+ "dq3Y29t7kEMI4aIo8lwux2/fvs3Gx8d/28qlrYXv+18RQsTNzU129epVWigUUC6X8fz5c8zN"
1116
+ "zUEQBKuVu7a2Zs7MzOD06dO4c+cOJicnUavVMDs7ywRBoIyxfgB/+A8ApXS7Xq8jkUjQCxcu"
1117
+ "4MqVK1hbW8OrV6/w6dMndHV1fXHmzJmvCSGs2WyeePPmDU6ePImbN2+CUgpVVVEqleju7i4o"
1118
+ "pdufVSDLMhhj0DQNMzMz2Nragu/72N7ehizLLJ1Od3me91wQBKRSKSSTSW9+fl56/PgxFhcX"
1119
+ "IQgCNE2DbdsIhUL4DOC6LjjnIIRAFEXU63VYloUgCBAEAVUUJTBN0wGAWCwW5pxLtm1jdXUV"
1120
+ "mqYhnU4fGIMxdgAgrcWHDx+aiqJAFEVks1l4nodisQjHcdDT04NsNvuPYrEYLRaL0Ww2++rc"
1121
+ "uXMwDAMTExM4duwYGGNwXRfVahUrKysHABEA7t69+7u3b9/ekmU50t3dDV3XMTExgUqlAlmW"
1122
+ "cfbsWdi2Td+9e3cEwIWurq6vkslk29LSEmq1GjRNQz6fR0dHByRJgqqq06VS6eUBoLu7+2+r"
1123
+ "q6s/2traYslkkszOzkJRFMiyjFwux8LhMNF1PWGa5rl4PP6zeDze5rouDMNg9Xqd7O3tQRRF"
1124
+ "ZDIZqKqKcrncdv/+/a2pqalFCgDhcPhjpVL50jRNWigU0N/fj0uXLkFVVayvr9OFhYVSNBot"
1125
+ "p1KpPgAol8tTjUajI5/PnxgYGIAoitB1HdVqFe/fv/dyudxPG43GXwD8FQDw8OHDuVQqxQcG"
1126
+ "BnitVuOGYfD19XU+PDzM29raOIBhAJFDDZgEcLuvr48risKbzSbXNI2PjIxwWZZ5LpfjDx48"
1127
+ "WD5wESEElFLoug5VVRGJRFAqlaDressZDIB7qPE9AL7jOFBVFYZhYGNjA3t7e5AkCYIggBDy"
1128
+ "vU0dx3FM04Smadjc3IQsy1heXoZpmq1Z8ysAg4cA4wB+7DgOKpUKPM/DysoKdnZ2YJomJEmC"
1129
+ "4zguAIhjY2MjL168+DmAeKFQQGdnJ2zbRrVaRb1ex/Lyssc57+jp6fnJ8ePHkc/ncfTo0S/K"
1130
+ "5XI2kUh43d3douu6KJfLkCQJ7e3taDQaqFQq4qNHj2KUMfbN4uIiLl686J8/f16sVqtIJpNw"
1131
+ "HAecc9i2LeVyOQwODm7ruv4tgCAej/dVq9WsYRiSaZpwHAe6riMajeLy5ctgjPkvX75sZ4x9"
1132
+ "Q6anp8E5RyaTET3Pw87ODmzbxs7ODhhjoJSCEIL9/f1/jY6O/mJ0dPSXzWbzn5RSuK6Ler0O"
1133
+ "27bRaDSgKAosy0ImkxEBYHp6GqQlimVZYIyBEALHcUAIgSB897vgnINzHjqkQbg1VgRBgOM4"
1134
+ "EAQBoVAInufBsr4bvJIkodUHKJVKkGUZrutid3cXhmHA9338UFBKYRgGVldXEQqFYJomLMvC"
1135
+ "3NwcSqXSwVyirRuKoohUKoVYLIZMJoOPHz8iCALIsvxfQUEQgFKKzs5OdHR0QFVVbG9vgzEG"
1136
+ "y7K+t2kkEkEQBFBVNVhaWiLRaBTxeByKoiAIAtRqNT+dTosA2g8d3k4pRb1e9+fn58V0Og1V"
1137
+ "VdFsNsE5h6Ioge/7JBKJgFqWNX/kyJETGxsbkampKXDOEQTBQYmSJInxeBwAploAQsjrWCx2"
1138
+ "VpIkcXJyEr7vQ5Kkw7qRzs5Ox7KsZQEAhoaG5iKRyJctcQ5HIpFAo9H487Nnz+4cfj80NPSn"
1139
+ "RCLx6/39/c++kWUZtm2vPH369NQPivi/in8Df18XwyUA5+QAAAAASUVORK5CYII=")
1140
+
1141
+ ShowSizers = PyEmbeddedImage(
1142
+ "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABChJ"
1143
+ "REFUSIm1lU1oXFUUx3/33nn3zbx5mcm0M5OZxGlNAn6XUqlRKIIWKrXqRlCLOwvitrooqKDg"
1144
+ "RhcirkSpigSECl0WBa104UKoSIoLS8TWlja1NTOTyUzz5s37uNdFWpumJSktHriry//8zj38"
1145
+ "z7nwP4dY5/7BUqn0quu62621i9cJhSjGcTzTarUOAr/dFn1sbGy/N+SdksgoQ2bh2mFBQpTz"
1146
+ "vdP1ev3AWjkya10qpe4yPbPZ3GeUecEMswQoYK4I3w+wzWiz3qgbtw0AQoHoswWfNxyYLYE2"
1147
+ "8GcVfr8IzU5gjOnfCWA5YuCvHPw0CRkLhGDjW5LeGiAFWjGcaYKyUHLAwvoeWQcgpczZjM3z"
1148
+ "A3CiD5fPAlikFXRicNy8lNJbK4das/A0VdKVJd/4oWqJZhSGVcJUeH3n5JA/NGe1OhEG/W+i"
1149
+ "KJq9LUAURe1KuVJQrrqnn4YVrXXkOE5gFCpf8NteLvdts9k8AgRXJDf0bC1ArlgsTiVJsqfX"
1150
+ "6+1K03RQLpenfd//tdvtbh0MBvdaaxe01pcGg8FFlq1wU8jNoqiUeq5Wqx3SWlutdWvTpk3v"
1151
+ "ANuBbY1G423Xdecdx7EjIyOHlVLPA6X1kl4lK6XU7rGxsU+UUkue54XlcvlL4LEVL36kUql8"
1152
+ "ns/nl6SUwejo6EGl1DNcM81/r7ihRfl8fmehUHil2Wzu1Vr3Xdc9lCTJZ4PB4DhXzAlcAOa0"
1153
+ "1koIMdntdqdKpZInhGjHcXx6ZT4FjDQajR21Wm2L7/sPJ0nyYr/ff1ZKOV8ul2eTJDnS6XSO"
1154
+ "sjwN4mp1cRw3s9lssVQq1cIwVEmSbNVa+9VqNTsyMjLh+/744uJiT3ied8BxnJcx6QMS0wkH"
1155
+ "UaEfJe6w4mc8v5AINWOS+KMgCGZWVuZ53taMlPtRaqovTRAv9LaTdQIn5y0oYzZkkaejOJ6m"
1156
+ "Xq8fk0IkCGVxci2UnsfNz1MatSDtUN7rT0xMvLa6lePj4/v8wlAfsCVUuJFMZxh1eQMqyIFF"
1157
+ "irRerx/LGGMCYa3ioV1f8el30/w4k8V178bNfMjHL3mcPREA0U1MES3ZNK2R6Z9katpgkpBU"
1158
+ "jFLovcnJRz8QF54wxgTXVoUQl9iBzz/bniQlT39JIdecQywICfEwQwFkd4KqdAmDS8gKEMLK"
1159
+ "XZTaOVImsbyOpM1QXiPkmgBAZBApeOEsS5OSjD8gJYsG6AFkhBA5C3D6+G72vudTGYXg8gYQ"
1160
+ "0J6DDB4sK67LLISjhXQ6xLm3+OXxU6RuBGxEM0sPLFkhRC5jjDmntD5D2N4jDr8LsMCV+bCQ"
1161
+ "t8Xhs0mStFYD4jhu55B/LEpx//vi/A5gieWdJLBoV+m2MeacAJ6uVqt7pZQNa+11v5MQohAE"
1162
+ "wdFut/sFcH4VY9T3/X2+7z9lre2t0mXTNP17fn7+6/V6fMfxL1klnkaQRVDaAAAAAElFTkSu"
1163
+ "QmCC")
1164
+
1165
+ ShowFilling = PyEmbeddedImage(
1166
+ "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAZ5J"
1167
+ "REFUSIntlc9KAkEcxz+tu7OxLRSuGUXtIfUpukW9QJcO3nqELoLXLr2Bt47dRBAqgxJ6BqMw"
1168
+ "PJe0FEliaLNrFxV1zXatY9/TMDPf72eG3/yBf/2guaH2DrALrADtGfME8AKUgCsAdWhwX1XV"
1169
+ "bSnlMtCZEaApivrqeXJxEmBDSrl+dHQoNjf3OD9/xjSDJ5vmMre3Z1xeHi8AG/3+YcAH8GEY"
1170
+ "SbG6uoVtP2IYwQFLS2s8PT0MciYBALi5uUfTrrEsB88LDtB1C027A+h+N6cAvBUK+e6surg4"
1171
+ "6wLvvSwAlHFKu/0ZfNkBvD6AEGJmwCSvrwaNRgOAZrMZKtw0zYF3KiCXy1Eul2m1WqEAhmFQ"
1172
+ "q9VgrMg+QKVSoVqt4oU5QoCiKHQ6/vvpA2QyGdLpNPV6PRQgHo+Tz+fJZrPTAYlEgmQyiW3b"
1173
+ "oQBCCFKpFIy+b36ArusDQ1j1vCM18B3TaDQaOrgvy7Jgyg7mgflisQiA4zihwmOxGKVSCUDv"
1174
+ "ZTFOO/mL5zoSiby6rnsFHMDoDk6llA6//HBc1+1/OP8Kpi8497f1tG0HzQAAAABJRU5ErkJg"
1175
+ "gg==")
1176
+
1177
+ Icon = PyEmbeddedImage(
1178
+ "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAALhJ"
1179
+ "REFUWIXtl80SgyAMhHeR99Y+eJseLAdHbJM0TjiwN2dI+MgfQpYFmSqpu0+AEQDqrwXyeorH"
1180
+ "McvCEIBdm3F7/fr0FKgBRFaIrHkAdykdQFmEGm2HL233BAIAYmxYEqjePo9SBYBvBKppclDz"
1181
+ "prMcqAhbAtknJx+3AKRHgGhnv4iApQY+jtSWpOY27BnifNt5uyk9BekAoZNwl21yDBSBi/63"
1182
+ "yOMiLAXaf8AuwP9n94vzaTYBsgHeht4lXXmb7yQAAAAASUVORK5CYII=")
1183
+
1184
+ CollapseTree = PyEmbeddedImage(
1185
+ "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAf9J"
1186
+ "REFUSIm9lD9r20AYhx9Fxe5SKDIynVJodFMaChkC6eBCJ+WWdulSb1o6RR8gH6AfQF5aSksX"
1187
+ "aQ0eajwVkinO1MFk0YXg0uLSISZDoQhcddAf5MR241buD4670/tyD+/vXh0sWdqUb1vAQ2Bj"
1188
+ "Suwb0E7Xx38DaAKPgTuAnJLfSSEAn4DWIoAm8ByQruti2zYAlmUBoJSi2+3ieV4R1v0TJANs"
1189
+ "AS8Ap9PpYFkWUSSuJFcqIUopAKSUAO+A18yxS0/nZ8AD13WFbdtEkWB9Hep1ODqC0QgMA8bj"
1190
+ "GqYJhmGgaRq9Xm8I3AY+zgKspPMGIIuHZ6qn4/Q02UeRIIpEZqEkua+ZWpkXLEM3ipvEe9C0"
1191
+ "ad2bqN+P89zr6P9WoJRidVXQ78e55/U09h1YW5vMTTWcB8i66B7wq1arie1ti/G4hmEknfNl"
1192
+ "BD8Kh1cqIbp+ThAEVKtVBoNBCziZBfjX/wDgEHg0C7D0O8gs+grcAm76vi80TcM04eJCYZqg"
1193
+ "6+ecnR0TBAGu6+L7PlJKhAgJQ+6SvF/vrwNsAm+BD0B8eTQajXztOMT7HnFrL48fpGNCizzX"
1194
+ "Q5IXdDfdN/Y92Hna5s2rJ+y+zPPm3skiOoCkip+f23Fr70o1pWgCkoGKkKV3URnKqyjaxTKs"
1195
+ "omCX4+SQ0pS1aew4xJub5VZwGZQdfv83yOfTR/iA1xwAAAAASUVORK5CYII=")
1196
+
1197
+ ExpandTree = PyEmbeddedImage(
1198
+ "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAepJ"
1199
+ "REFUSIm1lDFr20AYhp+ri+iSxUUhW4dIU9wlQ4YOKnRSj4K7Z9NSCFg/ID+gP0BZWkpLF3kN"
1200
+ "Giq0pkOpMxWSTFIIFIqHQCFbUQnXQTpFslXXptYLx90nvdzD9913Bx1LtHzbA54Aj1v+nQFf"
1201
+ "yvXpMoD7M/E+8AzYAmSLP66BbSBcBTACXED6vo/rugBYlgVAlmUkSSKDIND+rXJeCNEl2gNe"
1202
+ "AV4cx1iWRZ7bc2bDSMmyDAApJcAH4C0LytUr5wPA8n3fdl2XPLfZ2YHNTbi+vjPf3j7ENKHf"
1203
+ "7yOEYDKZTIHfwNe/Ae7V0pX1zbUGA8FgILi8LOI8t8lzW5dQ0t4Mc4DO1ADoA724ACEEQtx1"
1204
+ "8XBYZDLrXQnQhRoA3SEAUaSIItWIz89Vm3e6DOAMiJMkwTBSALa3i6Gl14aRYhgpSZLgOA7A"
1205
+ "t0WA/70HAJ+Bp//KoDPpi/YD2AAehGFoCyEwTbi5yTBN6PV+cnV1yng8xvd9wjBESoltp6Qp"
1206
+ "jyjer4/LAPeB98AnQM0Ox3GqteehjgPU0WH1/6QcDa3yXE8pDnRUxs5xAM9fRrx7M2T0uvIt"
1207
+ "PJNVdAJFFr++R+rocC6btagB0aA6pPMuWoeqLOrlootSUSuX51WQtUm3qfI81O7uejOYBenN"
1208
+ "X/wBVz/ONKbGYPkAAAAASUVORK5CYII=")
1209
+
1210
+ HighlightItem = PyEmbeddedImage(
1211
+ "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAQZJ"
1212
+ "REFUSInFlTGSgjAUhv8XuIRl9ga0XgmuoI5abwfH8Ai22GlJZ0otuQD5t3DZ1V1CwgzgP8OQ"
1213
+ "QCZfkv+9FxEVYUrFbYO2oW+wqEiGAtRzhyRIQh9eH+RXAMBmvfIuohcwheLnTnZ6vM3NjAaQ"
1214
+ "1mTahvrAHwCzj+BJVI83sesHAMjRM3OVgNkFm/WK292+EzKvB86zr5Lu76b2AubdAbqMda0+"
1215
+ "UOIqFdY2lKMHYGrw06DL3Tbrxzmi/Iq0JNLyO/Pxm/Uze/BXVRIUKajvKM6AXuh/kfjeHTC7"
1216
+ "TAdw1RfahmlJFOewgtjvQY/0QgeNe3MUOVQsw2/OwQBRkQy5Op2lYixN7sEXVhRd4PXVHvwA"
1217
+ "AAAASUVORK5CYII=")
1218
+
1219
+ EvtWatcher = PyEmbeddedImage(
1220
+ "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABwxJ"
1221
+ "REFUSIltlltsXFcVhr+zzzlzztw949vMxGPHl3Hiqk6I07RJhcBGoUK0VSuaSFwahAChSkiV"
1222
+ "QCotlQAJP/FAeKFPSChRJUAtqZACjUpJBCqUlEY0l7HjpraT+DKejDPjmfHcznXz0Bg1iPWy"
1223
+ "ttbD/629tbT/pXB/KIAEVCADxIBdwMi93AX4QBlYA5aBIlADNvg/oXzirAIeoAcCgVFN0460"
1224
+ "Wq0DuVzuc7VaLVspl52xsTHN9TwWFxfdbDarKYqysLKy8tdYLHalXq9fBG7fa0Dcy/8F7BSi"
1225
+ "hmEcdF33Cc/znt63b1//1NRUMBQKqeFolOHRMTzbYmlxEcdx2Nrast+7eNFaWl6+bZrm667r"
1226
+ "nnNd9ypg7Whq9yA+EInH4w/VarUTmqY9MTMz03vs2HFS/X1eOjvojmUHFM22sIMRXN/nxlxe"
1227
+ "lutVdXLqYPTM73774KVLl+KKosSCwaBst9vXdiDqzg0MwzjSbDafBR6bmppKv/TSS+7MzLTs"
1228
+ "7elTUwMp0ed7wlwvCnOwX8QjQaHHYiKdSCqHcjkvkckwl893VSqVbtd1DV3XC77vFwFFvff2"
1229
+ "4wjxFen7xx46dCjzwosvuuO5nNbT0yuSXWFk0KSx3sa53aLal6QtBVFF0GdZinBsoaZSjO7e"
1230
+ "LfP5fG+1Wu0TQmwbhnHLdd1tFRgIhULTtmV9Z3p6Ovvyyy+7ubExbWhoCEWoBBWPSzWdM4UE"
1231
+ "C+U011YM3gvojCwskZAOzclxkgFDCYZCyv79+735+fnuUqkUjUQii51Op6YCWcdxnsiNjR0+"
1232
+ "fuKE+cUjR+Sg7wurt5eA6bB2I8b3/1Hn3EKFY+UYzS2H2Y1bbFlpDuaydJsbBAo1woMDaLqO"
1233
+ "lFIpFApsbGysxGKxD1XgwJ7x8ecOPPLI4NMPP+w9ODqq2uEwkSvLrJWzfP5PS/SoJb7xpSy/"
1234
+ "GNUJd6noWoK3bn1E+a7D4XiaaJ+FpwWpVatKu9Vyt5vNrmaj4ZZKpUsCGCkWi/1d8TiZ3cMS"
1235
+ "VcHvWLyvJHj2gy0mBz1+/7VJHvRXmDv5dc6e/jF1c4HUeJjXS02ev9HhcjCDY2ok0ymGRkak"
1236
+ "qigU79xJCyFGNGBXrV4XXaEQxsiI4mnglRv8OZbjxvYax2cGaEfavPnTU/CrV1kH1qv/5Oi3"
1237
+ "XyG1Z4wr60Xenw+xJ75JVzyAOzSkqIEAtmUZpmkOCqBrYmJCGx4bI9SxICCoZrJEFySvtNL8"
1238
+ "xoqQ+uGP+OXJn0EkigiY8Ie/cPvfeY4GVX7QTMFNG+PGBqwX0KWv7H3gAbIDA4FOp5PQAN+2"
1239
+ "LGlLiV6vozp1lOgAvq6wrnkc3FQpVvtYBYRl47s2AJoQtARsuS6RqE7j0Ql0Ddy7VdxOB8u2"
1240
+ "JeALoLy0vOzevL5AvbsLPJPEu9exd8NPomtcr3jseupJeOYxcCyQEp47wa7Dh3hrq8PJ3iLa"
1241
+ "uABVQVU1LMeR1+fnKZVKlmmamxqwtiuT8betDvXFRUlmEMZ7eDzZ4vrGCK9duUx/LsL0t37N"
1242
+ "+sQ7aIZB6tHPkF8pYJeafDfdw5Pr8/j9uymUNvlwfl5quk4ymbQrlcqKBiwJIZaqtVpvcXVd"
1243
+ "jA4OSW9olzJuW/xcKxJWDV5d1Ulne/jqp79Mx4U3i228lQDP70nyvf0msZaPVymzcrcsC8Wi"
1244
+ "aGxvI4T4CFhSgWC9Xk90ms29vcPD4eHJSS9gu0JtO8Q6qxwaHmYpFmF5ZZPHb0VQq5Lzosg3"
1245
+ "H0jzwsEg+qhLM9GLslGg4jj+uQvn1fNvv32rVCqdicfjH6iAHg6HzVKpNNWoVvt6+/tlJBAQ"
1246
+ "aduiMZ4jNqiwt0cwkOjBNyVG3OXop7p5Zp9NT9ii09bwOy3my2X+/u678tXTp8Xq2trlZDL5"
1247
+ "RrVaXVWBhuM4DdM01ZXV1ZFrV68md4+O+mp/v5Lo6kJKlRgukynJ/u46hwvzjOdMjFAAPAXL"
1248
+ "arO4tMTfLlxgdnZWFIvFq4ZhnG40GheAzZ3vuuq6bktVVSqVSnd+bq53ct8+T1NVGYnElGg4"
1249
+ "pPjSQ8VD85r43XGMaIzKZlmura95Fy9eFLOzs9RqtX8JId5wXfeP8PFk7wAUoBQMBu86jhOs"
1250
+ "1Wp983Nz3YBotZredqPhSV/BcjzZDGjybrPl5/Nz3rWrV+XZs2e1U6dO+Xfu3MkLId7QNO01"
1251
+ "z/MWd/z9fy3TCIfDeyzL+oLruk8NDw8PT05O9qiqqgcCAbl3YkJxfJ/r165JVQil0Wy2L1++"
1252
+ "XC4WiwuGYZyRUp63bfsm4O5oftL0dyAiGAxmDMM4UK1WJ4eGhj67vb09tFWtkk6lDN9xZHFz"
1253
+ "08pkMhJYKBQK7ySTyXylUrkClO51vmPD920V90GA/lgsFqrX6/26ro8oijJo23YC8E3TvGvb"
1254
+ "9m0hxHI4HC7XarXmJ8Th49UHgP8A40NGDcCfTKIAAAAASUVORK5CYII=")