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.
- wx/WebView2Loader.dll +0 -0
- wx/__init__.py +22 -0
- wx/__init__.pyi +10 -0
- wx/__version__.py +9 -0
- wx/__version__.pyi +15 -0
- wx/_adv.cp315-win_amd64.pyd +0 -0
- wx/_aui.cp315-win_amd64.pyd +0 -0
- wx/_core.cp315-win_amd64.pyd +0 -0
- wx/_dataview.cp315-win_amd64.pyd +0 -0
- wx/_glcanvas.cp315-win_amd64.pyd +0 -0
- wx/_grid.cp315-win_amd64.pyd +0 -0
- wx/_html.cp315-win_amd64.pyd +0 -0
- wx/_html2.cp315-win_amd64.pyd +0 -0
- wx/_media.cp315-win_amd64.pyd +0 -0
- wx/_msw.cp315-win_amd64.pyd +0 -0
- wx/_propgrid.cp315-win_amd64.pyd +0 -0
- wx/_ribbon.cp315-win_amd64.pyd +0 -0
- wx/_richtext.cp315-win_amd64.pyd +0 -0
- wx/_stc.cp315-win_amd64.pyd +0 -0
- wx/_xml.cp315-win_amd64.pyd +0 -0
- wx/_xrc.cp315-win_amd64.pyd +0 -0
- wx/adv.py +127 -0
- wx/adv.pyi +5931 -0
- wx/aui.py +70 -0
- wx/aui.pyi +4805 -0
- wx/core.py +3417 -0
- wx/core.pyi +62949 -0
- wx/dataview.py +176 -0
- wx/dataview.pyi +3828 -0
- wx/gizmos.py +18 -0
- wx/glcanvas.py +13 -0
- wx/glcanvas.pyi +544 -0
- wx/grid.py +237 -0
- wx/grid.pyi +5678 -0
- wx/html.py +38 -0
- wx/html.pyi +3283 -0
- wx/html2.py +46 -0
- wx/html2.pyi +1301 -0
- wx/include/wxPython/sip.h +1938 -0
- wx/include/wxPython/wxpy_api.h +418 -0
- wx/lib/CDate.py +201 -0
- wx/lib/ClickableHtmlWindow.py +57 -0
- wx/lib/__init__.py +0 -0
- wx/lib/activex.py +178 -0
- wx/lib/activexwrapper.py +153 -0
- wx/lib/agw/__init__.py +128 -0
- wx/lib/agw/advancedsplash.py +563 -0
- wx/lib/agw/aquabutton.py +1127 -0
- wx/lib/agw/artmanager.py +2110 -0
- wx/lib/agw/aui/__init__.py +295 -0
- wx/lib/agw/aui/aui_constants.py +2616 -0
- wx/lib/agw/aui/aui_switcherdialog.py +1232 -0
- wx/lib/agw/aui/aui_utilities.py +648 -0
- wx/lib/agw/aui/auibar.py +4045 -0
- wx/lib/agw/aui/auibook.py +6288 -0
- wx/lib/agw/aui/dockart.py +1198 -0
- wx/lib/agw/aui/framemanager.py +10485 -0
- wx/lib/agw/aui/tabart.py +2749 -0
- wx/lib/agw/aui/tabmdi.py +679 -0
- wx/lib/agw/balloontip.py +1157 -0
- wx/lib/agw/buttonpanel.py +2787 -0
- wx/lib/agw/cubecolourdialog.py +3529 -0
- wx/lib/agw/customtreectrl.py +9908 -0
- wx/lib/agw/data/ShortcutEditor_1.png +0 -0
- wx/lib/agw/data/ShortcutEditor_1_thumb.png +0 -0
- wx/lib/agw/data/ShortcutEditor_2.png +0 -0
- wx/lib/agw/data/ShortcutEditor_2_thumb.png +0 -0
- wx/lib/agw/data/ShortcutEditor_3.png +0 -0
- wx/lib/agw/data/ShortcutEditor_3_thumb.png +0 -0
- wx/lib/agw/data/ShortcutEditor_4.png +0 -0
- wx/lib/agw/data/ShortcutEditor_4_thumb.png +0 -0
- wx/lib/agw/data/default_help_text.html +105 -0
- wx/lib/agw/flatmenu.py +7392 -0
- wx/lib/agw/flatnotebook.py +6669 -0
- wx/lib/agw/floatspin.py +1820 -0
- wx/lib/agw/fmcustomizedlg.py +535 -0
- wx/lib/agw/fmresources.py +407 -0
- wx/lib/agw/foldpanelbar.py +2282 -0
- wx/lib/agw/fourwaysplitter.py +1130 -0
- wx/lib/agw/genericmessagedialog.py +1549 -0
- wx/lib/agw/gradientbutton.py +731 -0
- wx/lib/agw/hyperlink.py +664 -0
- wx/lib/agw/hypertreelist.py +5756 -0
- wx/lib/agw/infobar.py +885 -0
- wx/lib/agw/knobctrl.py +944 -0
- wx/lib/agw/labelbook.py +3028 -0
- wx/lib/agw/multidirdialog.py +581 -0
- wx/lib/agw/peakmeter.py +1028 -0
- wx/lib/agw/persist/__init__.py +188 -0
- wx/lib/agw/persist/persist_constants.py +283 -0
- wx/lib/agw/persist/persist_handlers.py +2614 -0
- wx/lib/agw/persist/persistencemanager.py +863 -0
- wx/lib/agw/piectrl.py +1082 -0
- wx/lib/agw/pybusyinfo.py +399 -0
- wx/lib/agw/pycollapsiblepane.py +940 -0
- wx/lib/agw/pygauge.py +570 -0
- wx/lib/agw/pyprogress.py +916 -0
- wx/lib/agw/ribbon/__init__.py +198 -0
- wx/lib/agw/ribbon/art.py +219 -0
- wx/lib/agw/ribbon/art_aui.py +1283 -0
- wx/lib/agw/ribbon/art_default.py +81 -0
- wx/lib/agw/ribbon/art_internal.py +248 -0
- wx/lib/agw/ribbon/art_msw.py +2735 -0
- wx/lib/agw/ribbon/art_osx.py +52 -0
- wx/lib/agw/ribbon/bar.py +1259 -0
- wx/lib/agw/ribbon/buttonbar.py +1317 -0
- wx/lib/agw/ribbon/control.py +205 -0
- wx/lib/agw/ribbon/gallery.py +973 -0
- wx/lib/agw/ribbon/page.py +946 -0
- wx/lib/agw/ribbon/panel.py +1170 -0
- wx/lib/agw/ribbon/toolbar.py +1441 -0
- wx/lib/agw/rulerctrl.py +1885 -0
- wx/lib/agw/scrolledthumbnail.py +2116 -0
- wx/lib/agw/shapedbutton.py +1809 -0
- wx/lib/agw/shortcuteditor.py +2642 -0
- wx/lib/agw/speedmeter.py +1800 -0
- wx/lib/agw/supertooltip.py +1443 -0
- wx/lib/agw/thumbnailctrl.py +529 -0
- wx/lib/agw/toasterbox.py +1327 -0
- wx/lib/agw/ultimatelistctrl.py +13671 -0
- wx/lib/agw/xlsgrid.py +2111 -0
- wx/lib/agw/zoombar.py +1336 -0
- wx/lib/analogclock/__init__.py +140 -0
- wx/lib/analogclock/analogclock.py +630 -0
- wx/lib/analogclock/helpers.py +986 -0
- wx/lib/analogclock/lib_setup/__init__.py +0 -0
- wx/lib/analogclock/lib_setup/buttontreectrlpanel.py +297 -0
- wx/lib/analogclock/lib_setup/fontselect.py +57 -0
- wx/lib/analogclock/setup.py +490 -0
- wx/lib/analogclock/styles.py +47 -0
- wx/lib/anchors.py +103 -0
- wx/lib/art/__init__.py +4 -0
- wx/lib/art/flagart.py +1583 -0
- wx/lib/art/img2pyartprov.py +56 -0
- wx/lib/busy.py +152 -0
- wx/lib/buttons.py +1140 -0
- wx/lib/calendar.py +1596 -0
- wx/lib/checkbox.py +837 -0
- wx/lib/colourchooser/__init__.py +36 -0
- wx/lib/colourchooser/canvas.py +145 -0
- wx/lib/colourchooser/intl.py +24 -0
- wx/lib/colourchooser/pycolourbox.py +89 -0
- wx/lib/colourchooser/pycolourchooser.py +626 -0
- wx/lib/colourchooser/pycolourslider.py +98 -0
- wx/lib/colourchooser/pypalette.py +208 -0
- wx/lib/colourdb.py +740 -0
- wx/lib/colourselect.py +385 -0
- wx/lib/colourutils.py +118 -0
- wx/lib/combotreebox.py +944 -0
- wx/lib/delayedresult.py +420 -0
- wx/lib/dialogs.py +510 -0
- wx/lib/docview.py +3210 -0
- wx/lib/dragscroller.py +79 -0
- wx/lib/editor/README.txt +77 -0
- wx/lib/editor/__init__.py +24 -0
- wx/lib/editor/editor.py +974 -0
- wx/lib/editor/images.py +15 -0
- wx/lib/editor/selection.py +44 -0
- wx/lib/embeddedimage.py +76 -0
- wx/lib/eventStack.py +136 -0
- wx/lib/eventwatcher.py +440 -0
- wx/lib/evtmgr.py +521 -0
- wx/lib/expando.py +393 -0
- wx/lib/fancytext.py +494 -0
- wx/lib/filebrowsebutton.py +461 -0
- wx/lib/flashwin.py +262 -0
- wx/lib/flashwin_old.py +651 -0
- wx/lib/floatcanvas/FCEvents.py +53 -0
- wx/lib/floatcanvas/FCObjects.py +2910 -0
- wx/lib/floatcanvas/FloatCanvas.py +1025 -0
- wx/lib/floatcanvas/GUIMode.py +396 -0
- wx/lib/floatcanvas/NavCanvas.py +162 -0
- wx/lib/floatcanvas/Resources.py +319 -0
- wx/lib/floatcanvas/ScreenShot.py +1788 -0
- wx/lib/floatcanvas/Utilities/BBox.py +313 -0
- wx/lib/floatcanvas/Utilities/Colors.py +137 -0
- wx/lib/floatcanvas/Utilities/GUI.py +91 -0
- wx/lib/floatcanvas/Utilities/__init__.py +7 -0
- wx/lib/floatcanvas/__init__.py +124 -0
- wx/lib/foldmenu.py +89 -0
- wx/lib/gestures.py +310 -0
- wx/lib/gizmos/__init__.py +18 -0
- wx/lib/gizmos/dynamicsash.py +1202 -0
- wx/lib/gizmos/ledctrl.py +299 -0
- wx/lib/gizmos/treelistctrl.py +87 -0
- wx/lib/graphics.py +1942 -0
- wx/lib/gridmovers.py +516 -0
- wx/lib/iewin.py +249 -0
- wx/lib/iewin_old.py +894 -0
- wx/lib/imagebrowser.py +853 -0
- wx/lib/imageutils.py +163 -0
- wx/lib/infoframe.py +490 -0
- wx/lib/inspection.py +1254 -0
- wx/lib/intctrl.py +990 -0
- wx/lib/itemspicker.py +256 -0
- wx/lib/langlistctrl.py +480 -0
- wx/lib/layoutf.py +271 -0
- wx/lib/masked/__init__.py +27 -0
- wx/lib/masked/combobox.py +839 -0
- wx/lib/masked/ctrl.py +108 -0
- wx/lib/masked/ipaddrctrl.py +241 -0
- wx/lib/masked/maskededit.py +7262 -0
- wx/lib/masked/numctrl.py +2000 -0
- wx/lib/masked/textctrl.py +465 -0
- wx/lib/masked/timectrl.py +1465 -0
- wx/lib/mixins/__init__.py +17 -0
- wx/lib/mixins/grid.py +47 -0
- wx/lib/mixins/gridlabelrenderer.py +277 -0
- wx/lib/mixins/imagelist.py +77 -0
- wx/lib/mixins/inspection.py +184 -0
- wx/lib/mixins/listctrl.py +893 -0
- wx/lib/mixins/rubberband.py +403 -0
- wx/lib/mixins/treemixin.py +678 -0
- wx/lib/msgpanel.py +95 -0
- wx/lib/multisash.py +746 -0
- wx/lib/myole4ax.idl +178 -0
- wx/lib/myole4ax.tlb +0 -0
- wx/lib/newevent.py +229 -0
- wx/lib/newevent.pyi +25 -0
- wx/lib/nvdlg.py +156 -0
- wx/lib/ogl/__init__.py +13 -0
- wx/lib/ogl/basic.py +3989 -0
- wx/lib/ogl/bmpshape.py +86 -0
- wx/lib/ogl/canvas.py +467 -0
- wx/lib/ogl/composit.py +1576 -0
- wx/lib/ogl/diagram.py +230 -0
- wx/lib/ogl/divided.py +482 -0
- wx/lib/ogl/drawn.py +898 -0
- wx/lib/ogl/lines.py +1809 -0
- wx/lib/ogl/oglmisc.py +607 -0
- wx/lib/pdfviewer/__init__.py +113 -0
- wx/lib/pdfviewer/bitmaps/ArrowLeft.png +0 -0
- wx/lib/pdfviewer/bitmaps/ArrowRight.png +0 -0
- wx/lib/pdfviewer/bitmaps/DirectionH.png +0 -0
- wx/lib/pdfviewer/bitmaps/DirectionV.png +0 -0
- wx/lib/pdfviewer/bitmaps/PlayerFirst.png +0 -0
- wx/lib/pdfviewer/bitmaps/PlayerLast.png +0 -0
- wx/lib/pdfviewer/bitmaps/PlayerNext.png +0 -0
- wx/lib/pdfviewer/bitmaps/PlayerPrev.png +0 -0
- wx/lib/pdfviewer/bitmaps/Printer.png +0 -0
- wx/lib/pdfviewer/bitmaps/ReadMe.txt +28 -0
- wx/lib/pdfviewer/bitmaps/Save.png +0 -0
- wx/lib/pdfviewer/bitmaps/ZoomIn.png +0 -0
- wx/lib/pdfviewer/bitmaps/ZoomOut.png +0 -0
- wx/lib/pdfviewer/bitmaps/encode_bitmaps.py +37 -0
- wx/lib/pdfviewer/buttonpanel.py +285 -0
- wx/lib/pdfviewer/images.py +240 -0
- wx/lib/pdfviewer/viewer.py +1118 -0
- wx/lib/pdfwin.py +295 -0
- wx/lib/pdfwin_old.py +789 -0
- wx/lib/platebtn.py +789 -0
- wx/lib/plot/CHANGELOG.md +150 -0
- wx/lib/plot/README.md +16 -0
- wx/lib/plot/__init__.py +46 -0
- wx/lib/plot/__main__.py +5 -0
- wx/lib/plot/examples/__init__.py +0 -0
- wx/lib/plot/examples/demo.py +1010 -0
- wx/lib/plot/examples/simple_example.py +56 -0
- wx/lib/plot/plotcanvas.py +2985 -0
- wx/lib/plot/polyobjects.py +1524 -0
- wx/lib/plot/utils.py +334 -0
- wx/lib/popupctl.py +251 -0
- wx/lib/printout.py +1155 -0
- wx/lib/progressindicator.py +151 -0
- wx/lib/pubsub/LICENSE_BSD_Simple.txt +23 -0
- wx/lib/pubsub/README_WxPython.txt +22 -0
- wx/lib/pubsub/RELEASE_NOTES.txt +71 -0
- wx/lib/pubsub/__init__.py +25 -0
- wx/lib/pubsub/core/__init__.py +92 -0
- wx/lib/pubsub/core/arg1/__init__.py +16 -0
- wx/lib/pubsub/core/arg1/listenerimpl.py +97 -0
- wx/lib/pubsub/core/arg1/publisher.py +40 -0
- wx/lib/pubsub/core/arg1/publishermixin.py +34 -0
- wx/lib/pubsub/core/arg1/topicargspecimpl.py +66 -0
- wx/lib/pubsub/core/arg1/topicmgrimpl.py +19 -0
- wx/lib/pubsub/core/callables.py +198 -0
- wx/lib/pubsub/core/imp2.py +62 -0
- wx/lib/pubsub/core/itopicdefnprovider.py +0 -0
- wx/lib/pubsub/core/kwargs/__init__.py +16 -0
- wx/lib/pubsub/core/kwargs/datamsg.py +27 -0
- wx/lib/pubsub/core/kwargs/listenerimpl.py +93 -0
- wx/lib/pubsub/core/kwargs/publisher.py +77 -0
- wx/lib/pubsub/core/kwargs/publishermixin.py +65 -0
- wx/lib/pubsub/core/kwargs/topicargspecimpl.py +216 -0
- wx/lib/pubsub/core/kwargs/topicmgrimpl.py +13 -0
- wx/lib/pubsub/core/listener.py +40 -0
- wx/lib/pubsub/core/listenerbase.py +185 -0
- wx/lib/pubsub/core/notificationmgr.py +185 -0
- wx/lib/pubsub/core/publisherbase.py +189 -0
- wx/lib/pubsub/core/topicargspec.py +77 -0
- wx/lib/pubsub/core/topicdefnprovider.py +631 -0
- wx/lib/pubsub/core/topicexc.py +72 -0
- wx/lib/pubsub/core/topicmgr.py +454 -0
- wx/lib/pubsub/core/topicobj.py +472 -0
- wx/lib/pubsub/core/topictreetraverser.py +143 -0
- wx/lib/pubsub/core/topicutils.py +119 -0
- wx/lib/pubsub/core/treeconfig.py +21 -0
- wx/lib/pubsub/core/validatedefnargs.py +29 -0
- wx/lib/pubsub/core/weakmethod.py +102 -0
- wx/lib/pubsub/policies.py +24 -0
- wx/lib/pubsub/pub.py +199 -0
- wx/lib/pubsub/setuparg1.py +47 -0
- wx/lib/pubsub/setupkwargs.py +29 -0
- wx/lib/pubsub/utils/__init__.py +27 -0
- wx/lib/pubsub/utils/exchandling.py +100 -0
- wx/lib/pubsub/utils/misc.py +99 -0
- wx/lib/pubsub/utils/notification.py +331 -0
- wx/lib/pubsub/utils/topictreeprinter.py +195 -0
- wx/lib/pubsub/utils/xmltopicdefnprovider.py +286 -0
- wx/lib/pydocview.py +3300 -0
- wx/lib/rcsizer.py +227 -0
- wx/lib/resizewidget.py +357 -0
- wx/lib/scrolledpanel.py +243 -0
- wx/lib/sheet.py +350 -0
- wx/lib/sized_controls.py +691 -0
- wx/lib/softwareupdate.py +355 -0
- wx/lib/splitter.py +925 -0
- wx/lib/statbmp.py +199 -0
- wx/lib/stattext.py +321 -0
- wx/lib/throbber.py +424 -0
- wx/lib/ticker.py +306 -0
- wx/lib/ticker_xrc.py +48 -0
- wx/lib/utils.py +89 -0
- wx/lib/wordwrap.py +97 -0
- wx/lib/wxcairo/__init__.py +139 -0
- wx/lib/wxcairo/wx_cairocffi.py +200 -0
- wx/lib/wxcairo/wx_pycairo.py +455 -0
- wx/lib/wxpTag.py +274 -0
- wx/libcairo-2.dll +0 -0
- wx/locale/af/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/an/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ar/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ca/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ca@valencia/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/co/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/cs/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/da/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/de/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/el/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/es/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/eu/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/fa_IR/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/fi/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/fr/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/gl_ES/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/hi/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/hr/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/hu/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/id/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/it/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ja/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ka/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ko_KR/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/lt/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/lv/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ms/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/nb/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ne/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/nl/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/pl/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/pt/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/pt_BR/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ro/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ru/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sk/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sl/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sq/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sr/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/sv/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/ta/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/tr/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/uk/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/vi/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/zh_CN/LC_MESSAGES/wxstd.mo +0 -0
- wx/locale/zh_TW/LC_MESSAGES/wxstd.mo +0 -0
- wx/media.py +30 -0
- wx/media.pyi +272 -0
- wx/msw.py +16 -0
- wx/msw.pyi +91 -0
- wx/propgrid.py +498 -0
- wx/propgrid.pyi +7427 -0
- wx/py/CHANGES.txt +796 -0
- wx/py/Py.ico +0 -0
- wx/py/PyAlaCarte.py +34 -0
- wx/py/PyAlaMode.py +34 -0
- wx/py/PyAlaModeTest.py +33 -0
- wx/py/PyCrust.ico +0 -0
- wx/py/PyCrust.py +78 -0
- wx/py/PyCrust_16.png +0 -0
- wx/py/PyCrust_32.png +0 -0
- wx/py/PyFilling.py +35 -0
- wx/py/PyShell.py +78 -0
- wx/py/PySlices.ico +0 -0
- wx/py/PySlices.py +98 -0
- wx/py/PySlicesShell.py +94 -0
- wx/py/PySlices_16.png +0 -0
- wx/py/PySlices_32.png +0 -0
- wx/py/PyWrap.py +52 -0
- wx/py/README.txt +77 -0
- wx/py/__init__.py +20 -0
- wx/py/buffer.py +136 -0
- wx/py/crust.py +403 -0
- wx/py/crustslices.py +403 -0
- wx/py/dispatcher.py +259 -0
- wx/py/document.py +37 -0
- wx/py/editor.py +844 -0
- wx/py/editwindow.py +316 -0
- wx/py/filling.py +358 -0
- wx/py/frame.py +976 -0
- wx/py/images.py +212 -0
- wx/py/interpreter.py +161 -0
- wx/py/introspect.py +402 -0
- wx/py/magic.py +98 -0
- wx/py/parse.py +134 -0
- wx/py/path.py +36 -0
- wx/py/pseudo.py +99 -0
- wx/py/shell.py +1579 -0
- wx/py/sliceshell.py +3805 -0
- wx/py/tests/test_interpreter.py +71 -0
- wx/py/tests/test_introspect.py +810 -0
- wx/py/tests/test_pseudo.py +70 -0
- wx/py/tests/test_version.py +36 -0
- wx/py/tests/testall.py +22 -0
- wx/py/version.py +7 -0
- wx/py.typed +0 -0
- wx/ribbon.py +48 -0
- wx/ribbon.pyi +3099 -0
- wx/richtext.py +141 -0
- wx/richtext.pyi +13581 -0
- wx/siplib.cp315-win_amd64.pyd +0 -0
- wx/siplib.pyi +19 -0
- wx/stc.py +59 -0
- wx/stc.pyi +9918 -0
- wx/svg/__init__.py +363 -0
- wx/svg/_nanosvg.cp315-win_amd64.pyd +0 -0
- wx/tools/__init__.py +18 -0
- wx/tools/dbg.py +268 -0
- wx/tools/genaxmodule.py +50 -0
- wx/tools/helpviewer.py +92 -0
- wx/tools/img2img.py +85 -0
- wx/tools/img2png.py +54 -0
- wx/tools/img2py.py +306 -0
- wx/tools/img2xpm.py +54 -0
- wx/tools/pywxrc.py +951 -0
- wx/tools/wxget.py +254 -0
- wx/tools/wxget_docs_demo.py +183 -0
- wx/wxbase334u_net_vc140_x64.dll +0 -0
- wx/wxbase334u_vc140_x64.dll +0 -0
- wx/wxbase334u_xml_vc140_x64.dll +0 -0
- wx/wxmsw334u_adv_vc140_x64.dll +0 -0
- wx/wxmsw334u_aui_vc140_x64.dll +0 -0
- wx/wxmsw334u_core_vc140_x64.dll +0 -0
- wx/wxmsw334u_gl_vc140_x64.dll +0 -0
- wx/wxmsw334u_html_vc140_x64.dll +0 -0
- wx/wxmsw334u_media_vc140_x64.dll +0 -0
- wx/wxmsw334u_propgrid_vc140_x64.dll +0 -0
- wx/wxmsw334u_qa_vc140_x64.dll +0 -0
- wx/wxmsw334u_ribbon_vc140_x64.dll +0 -0
- wx/wxmsw334u_richtext_vc140_x64.dll +0 -0
- wx/wxmsw334u_stc_vc140_x64.dll +0 -0
- wx/wxmsw334u_webview_vc140_x64.dll +0 -0
- wx/wxmsw334u_xrc_vc140_x64.dll +0 -0
- wx/xml.py +18 -0
- wx/xml.pyi +728 -0
- wx/xrc.py +68 -0
- wx/xrc.pyi +896 -0
- wxpython-4.3.2.dist-info/METADATA +71 -0
- wxpython-4.3.2.dist-info/RECORD +472 -0
- wxpython-4.3.2.dist-info/WHEEL +5 -0
- wxpython-4.3.2.dist-info/entry_points.txt +13 -0
- wxpython-4.3.2.dist-info/licenses/LICENSE.txt +610 -0
- wxpython-4.3.2.dist-info/top_level.txt +1 -0
wx/py/editor.py
ADDED
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
#----------------------------------------------------------------------
|
|
2
|
+
# Name: editor.py
|
|
3
|
+
# Author: Patrick K. O'Brien <pobrien@orbtech.com>
|
|
4
|
+
# Tags: phoenix-port
|
|
5
|
+
#----------------------------------------------------------------------
|
|
6
|
+
"""PyAlaCarte and PyAlaMode editors."""
|
|
7
|
+
|
|
8
|
+
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
|
9
|
+
|
|
10
|
+
import wx
|
|
11
|
+
|
|
12
|
+
from .buffer import Buffer
|
|
13
|
+
from . import crust
|
|
14
|
+
from . import dispatcher
|
|
15
|
+
from . import editwindow
|
|
16
|
+
from . import frame
|
|
17
|
+
from .shell import Shell
|
|
18
|
+
from . import version
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class EditorFrame(frame.Frame):
|
|
22
|
+
"""Frame containing one editor."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, parent=None, id=-1, title='PyAlaCarte',
|
|
25
|
+
pos=wx.DefaultPosition, size=(800, 600),
|
|
26
|
+
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE,
|
|
27
|
+
filename=None):
|
|
28
|
+
"""Create EditorFrame instance."""
|
|
29
|
+
frame.Frame.__init__(self, parent, id, title, pos, size, style)
|
|
30
|
+
self.buffers = {}
|
|
31
|
+
self.buffer = None # Current buffer.
|
|
32
|
+
self.editor = None
|
|
33
|
+
self._defaultText = title + ' - the tastiest Python editor.'
|
|
34
|
+
self._statusText = self._defaultText
|
|
35
|
+
self.SetStatusText(self._statusText)
|
|
36
|
+
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
|
37
|
+
self._setup()
|
|
38
|
+
if filename:
|
|
39
|
+
self.bufferCreate(filename)
|
|
40
|
+
|
|
41
|
+
def _setup(self):
|
|
42
|
+
"""Setup prior to first buffer creation.
|
|
43
|
+
|
|
44
|
+
Useful for subclasses."""
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
def setEditor(self, editor):
|
|
48
|
+
self.editor = editor
|
|
49
|
+
self.buffer = self.editor.buffer
|
|
50
|
+
self.buffers[self.buffer.id] = self.buffer
|
|
51
|
+
|
|
52
|
+
def OnAbout(self, event):
|
|
53
|
+
"""Display an About window."""
|
|
54
|
+
title = 'About PyAlaCarte'
|
|
55
|
+
text = 'Another fine, flaky program.'
|
|
56
|
+
dialog = wx.MessageDialog(self, text, title,
|
|
57
|
+
wx.OK | wx.ICON_INFORMATION)
|
|
58
|
+
dialog.ShowModal()
|
|
59
|
+
dialog.Destroy()
|
|
60
|
+
|
|
61
|
+
def OnClose(self, event):
|
|
62
|
+
"""Event handler for closing."""
|
|
63
|
+
for buffer in self.buffers.values():
|
|
64
|
+
self.buffer = buffer
|
|
65
|
+
if buffer.hasChanged():
|
|
66
|
+
cancel = self.bufferSuggestSave()
|
|
67
|
+
if cancel and event.CanVeto():
|
|
68
|
+
event.Veto()
|
|
69
|
+
return
|
|
70
|
+
self.Destroy()
|
|
71
|
+
|
|
72
|
+
def OnIdle(self, event):
|
|
73
|
+
"""Event handler for idle time."""
|
|
74
|
+
self._updateStatus()
|
|
75
|
+
if hasattr(self, 'notebook'):
|
|
76
|
+
self._updateTabText()
|
|
77
|
+
self._updateTitle()
|
|
78
|
+
event.Skip()
|
|
79
|
+
|
|
80
|
+
def _updateStatus(self):
|
|
81
|
+
"""Show current status information."""
|
|
82
|
+
if self.editor and hasattr(self.editor, 'getStatus'):
|
|
83
|
+
status = self.editor.getStatus()
|
|
84
|
+
text = 'File: %s | Line: %d | Column: %d' % status
|
|
85
|
+
else:
|
|
86
|
+
text = self._defaultText
|
|
87
|
+
if text != self._statusText:
|
|
88
|
+
self.SetStatusText(text)
|
|
89
|
+
self._statusText = text
|
|
90
|
+
|
|
91
|
+
def _updateTabText(self):
|
|
92
|
+
"""Show current buffer information on notebook tab."""
|
|
93
|
+
## suffix = ' **'
|
|
94
|
+
## notebook = self.notebook
|
|
95
|
+
## selection = notebook.GetSelection()
|
|
96
|
+
## if selection == -1:
|
|
97
|
+
## return
|
|
98
|
+
## text = notebook.GetPageText(selection)
|
|
99
|
+
## window = notebook.GetPage(selection)
|
|
100
|
+
## if window.editor and window.editor.buffer.hasChanged():
|
|
101
|
+
## if text.endswith(suffix):
|
|
102
|
+
## pass
|
|
103
|
+
## else:
|
|
104
|
+
## notebook.SetPageText(selection, text + suffix)
|
|
105
|
+
## else:
|
|
106
|
+
## if text.endswith(suffix):
|
|
107
|
+
## notebook.SetPageText(selection, text[:len(suffix)])
|
|
108
|
+
|
|
109
|
+
def _updateTitle(self):
|
|
110
|
+
"""Show current title information."""
|
|
111
|
+
title = self.GetTitle()
|
|
112
|
+
if self.bufferHasChanged():
|
|
113
|
+
if title.startswith('* '):
|
|
114
|
+
pass
|
|
115
|
+
else:
|
|
116
|
+
self.SetTitle('* ' + title)
|
|
117
|
+
else:
|
|
118
|
+
if title.startswith('* '):
|
|
119
|
+
self.SetTitle(title[2:])
|
|
120
|
+
|
|
121
|
+
def hasBuffer(self):
|
|
122
|
+
"""Return True if there is a current buffer."""
|
|
123
|
+
if self.buffer:
|
|
124
|
+
return True
|
|
125
|
+
else:
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
def bufferClose(self):
|
|
129
|
+
"""Close buffer."""
|
|
130
|
+
if self.bufferHasChanged():
|
|
131
|
+
cancel = self.bufferSuggestSave()
|
|
132
|
+
if cancel:
|
|
133
|
+
return cancel
|
|
134
|
+
self.bufferDestroy()
|
|
135
|
+
cancel = False
|
|
136
|
+
return cancel
|
|
137
|
+
|
|
138
|
+
def bufferCreate(self, filename=None):
|
|
139
|
+
"""Create new buffer."""
|
|
140
|
+
self.bufferDestroy()
|
|
141
|
+
buffer = Buffer()
|
|
142
|
+
self.panel = panel = wx.Panel(parent=self, id=-1)
|
|
143
|
+
panel.Bind (wx.EVT_ERASE_BACKGROUND, lambda x: x)
|
|
144
|
+
editor = Editor(parent=panel)
|
|
145
|
+
panel.editor = editor
|
|
146
|
+
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
147
|
+
sizer.Add(editor.window, 1, wx.EXPAND)
|
|
148
|
+
panel.SetSizer(sizer)
|
|
149
|
+
panel.SetAutoLayout(True)
|
|
150
|
+
sizer.Layout()
|
|
151
|
+
buffer.addEditor(editor)
|
|
152
|
+
buffer.open(filename)
|
|
153
|
+
self.setEditor(editor)
|
|
154
|
+
self.editor.setFocus()
|
|
155
|
+
self.SendSizeEvent()
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def bufferDestroy(self):
|
|
159
|
+
"""Destroy the current buffer."""
|
|
160
|
+
if self.buffer:
|
|
161
|
+
for editor in self.buffer.editors.values():
|
|
162
|
+
editor.destroy()
|
|
163
|
+
self.editor = None
|
|
164
|
+
del self.buffers[self.buffer.id]
|
|
165
|
+
self.buffer = None
|
|
166
|
+
self.panel.Destroy()
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def bufferHasChanged(self):
|
|
170
|
+
"""Return True if buffer has changed since last save."""
|
|
171
|
+
if self.buffer:
|
|
172
|
+
return self.buffer.hasChanged()
|
|
173
|
+
else:
|
|
174
|
+
return False
|
|
175
|
+
|
|
176
|
+
def bufferNew(self):
|
|
177
|
+
"""Create new buffer."""
|
|
178
|
+
if self.bufferHasChanged():
|
|
179
|
+
cancel = self.bufferSuggestSave()
|
|
180
|
+
if cancel:
|
|
181
|
+
return cancel
|
|
182
|
+
self.bufferCreate()
|
|
183
|
+
cancel = False
|
|
184
|
+
return cancel
|
|
185
|
+
|
|
186
|
+
def bufferOpen(self):
|
|
187
|
+
"""Open file in buffer."""
|
|
188
|
+
if self.bufferHasChanged():
|
|
189
|
+
cancel = self.bufferSuggestSave()
|
|
190
|
+
if cancel:
|
|
191
|
+
return cancel
|
|
192
|
+
filedir = ''
|
|
193
|
+
if self.buffer and self.buffer.doc.filedir:
|
|
194
|
+
filedir = self.buffer.doc.filedir
|
|
195
|
+
result = openSingle(directory=filedir)
|
|
196
|
+
if result.path:
|
|
197
|
+
self.bufferCreate(result.path)
|
|
198
|
+
cancel = False
|
|
199
|
+
return cancel
|
|
200
|
+
|
|
201
|
+
## def bufferPrint(self):
|
|
202
|
+
## """Print buffer."""
|
|
203
|
+
## pass
|
|
204
|
+
|
|
205
|
+
## def bufferRevert(self):
|
|
206
|
+
## """Revert buffer to version of file on disk."""
|
|
207
|
+
## pass
|
|
208
|
+
|
|
209
|
+
def bufferSave(self):
|
|
210
|
+
"""Save buffer to its file."""
|
|
211
|
+
if self.buffer.doc.filepath:
|
|
212
|
+
self.buffer.save()
|
|
213
|
+
cancel = False
|
|
214
|
+
else:
|
|
215
|
+
cancel = self.bufferSaveAs()
|
|
216
|
+
return cancel
|
|
217
|
+
|
|
218
|
+
def bufferSaveAs(self):
|
|
219
|
+
"""Save buffer to a new filename."""
|
|
220
|
+
if self.bufferHasChanged() and self.buffer.doc.filepath:
|
|
221
|
+
cancel = self.bufferSuggestSave()
|
|
222
|
+
if cancel:
|
|
223
|
+
return cancel
|
|
224
|
+
filedir = ''
|
|
225
|
+
if self.buffer and self.buffer.doc.filedir:
|
|
226
|
+
filedir = self.buffer.doc.filedir
|
|
227
|
+
result = saveSingle(directory=filedir)
|
|
228
|
+
if result.path:
|
|
229
|
+
self.buffer.saveAs(result.path)
|
|
230
|
+
cancel = False
|
|
231
|
+
else:
|
|
232
|
+
cancel = True
|
|
233
|
+
return cancel
|
|
234
|
+
|
|
235
|
+
def bufferSuggestSave(self):
|
|
236
|
+
"""Suggest saving changes. Return True if user selected Cancel."""
|
|
237
|
+
result = messageDialog(parent=None,
|
|
238
|
+
message='%s has changed.\n'
|
|
239
|
+
'Would you like to save it first'
|
|
240
|
+
'?' % self.buffer.name,
|
|
241
|
+
title='Save current file?')
|
|
242
|
+
if result.positive:
|
|
243
|
+
cancel = self.bufferSave()
|
|
244
|
+
else:
|
|
245
|
+
cancel = result.text == 'Cancel'
|
|
246
|
+
return cancel
|
|
247
|
+
|
|
248
|
+
def updateNamespace(self):
|
|
249
|
+
"""Update the buffer namespace for autocompletion and calltips."""
|
|
250
|
+
if self.buffer.updateNamespace():
|
|
251
|
+
self.SetStatusText('Namespace updated')
|
|
252
|
+
else:
|
|
253
|
+
self.SetStatusText('Error executing, unable to update namespace')
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class EditorNotebookFrame(EditorFrame):
|
|
257
|
+
"""Frame containing one or more editors in a notebook."""
|
|
258
|
+
|
|
259
|
+
def __init__(self, parent=None, id=-1, title='PyAlaMode',
|
|
260
|
+
pos=wx.DefaultPosition, size=(800, 600),
|
|
261
|
+
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE,
|
|
262
|
+
filename=None):
|
|
263
|
+
"""Create EditorNotebookFrame instance."""
|
|
264
|
+
self.notebook = None
|
|
265
|
+
EditorFrame.__init__(self, parent, id, title, pos,
|
|
266
|
+
size, style, filename)
|
|
267
|
+
if self.notebook:
|
|
268
|
+
dispatcher.connect(receiver=self._editorChange,
|
|
269
|
+
signal='EditorChange', sender=self.notebook)
|
|
270
|
+
|
|
271
|
+
def _setup(self):
|
|
272
|
+
"""Setup prior to first buffer creation.
|
|
273
|
+
|
|
274
|
+
Called automatically by base class during init."""
|
|
275
|
+
self.notebook = EditorNotebook(parent=self)
|
|
276
|
+
intro = 'Py %s' % version.VERSION
|
|
277
|
+
import types
|
|
278
|
+
module = types.ModuleType('__main__')
|
|
279
|
+
module.__dict__['__builtins__'] = __builtins__
|
|
280
|
+
namespace = module.__dict__.copy()
|
|
281
|
+
self.crust = crust.Crust(parent=self.notebook, intro=intro, locals=namespace)
|
|
282
|
+
self.shell = self.crust.shell
|
|
283
|
+
# Override the filling so that status messages go to the status bar.
|
|
284
|
+
self.crust.filling.tree.setStatusText = self.SetStatusText
|
|
285
|
+
# Override the shell so that status messages go to the status bar.
|
|
286
|
+
self.shell.setStatusText = self.SetStatusText
|
|
287
|
+
# Fix a problem with the sash shrinking to nothing.
|
|
288
|
+
self.crust.filling.SetSashPosition(200)
|
|
289
|
+
self.notebook.AddPage(page=self.crust, text='*Shell*', select=True)
|
|
290
|
+
self.setEditor(self.crust.editor)
|
|
291
|
+
self.crust.editor.SetFocus()
|
|
292
|
+
|
|
293
|
+
def _editorChange(self, editor):
|
|
294
|
+
"""Editor change signal receiver."""
|
|
295
|
+
if not self:
|
|
296
|
+
dispatcher.disconnect(receiver=self._editorChange,
|
|
297
|
+
signal='EditorChange', sender=self.notebook)
|
|
298
|
+
return
|
|
299
|
+
self.setEditor(editor)
|
|
300
|
+
|
|
301
|
+
def OnAbout(self, event):
|
|
302
|
+
"""Display an About window."""
|
|
303
|
+
title = 'About PyAlaMode'
|
|
304
|
+
text = 'Another fine, flaky program.'
|
|
305
|
+
dialog = wx.MessageDialog(self, text, title,
|
|
306
|
+
wx.OK | wx.ICON_INFORMATION)
|
|
307
|
+
dialog.ShowModal()
|
|
308
|
+
dialog.Destroy()
|
|
309
|
+
|
|
310
|
+
def _updateTitle(self):
|
|
311
|
+
"""Show current title information."""
|
|
312
|
+
pass
|
|
313
|
+
## title = self.GetTitle()
|
|
314
|
+
## if self.bufferHasChanged():
|
|
315
|
+
## if title.startswith('* '):
|
|
316
|
+
## pass
|
|
317
|
+
## else:
|
|
318
|
+
## self.SetTitle('* ' + title)
|
|
319
|
+
## else:
|
|
320
|
+
## if title.startswith('* '):
|
|
321
|
+
## self.SetTitle(title[2:])
|
|
322
|
+
|
|
323
|
+
def bufferCreate(self, filename=None):
|
|
324
|
+
"""Create new buffer."""
|
|
325
|
+
buffer = Buffer()
|
|
326
|
+
panel = wx.Panel(parent=self.notebook, id=-1)
|
|
327
|
+
panel.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: x)
|
|
328
|
+
editor = Editor(parent=panel)
|
|
329
|
+
panel.editor = editor
|
|
330
|
+
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
331
|
+
sizer.Add(editor.window, 1, wx.EXPAND)
|
|
332
|
+
panel.SetSizer(sizer)
|
|
333
|
+
panel.SetAutoLayout(True)
|
|
334
|
+
sizer.Layout()
|
|
335
|
+
buffer.addEditor(editor)
|
|
336
|
+
buffer.open(filename)
|
|
337
|
+
self.setEditor(editor)
|
|
338
|
+
self.notebook.AddPage(page=panel, text=self.buffer.name, select=True)
|
|
339
|
+
self.editor.setFocus()
|
|
340
|
+
|
|
341
|
+
def bufferDestroy(self):
|
|
342
|
+
"""Destroy the current buffer."""
|
|
343
|
+
selection = self.notebook.GetSelection()
|
|
344
|
+
## print("Destroy Selection:", selection)
|
|
345
|
+
if selection > 0: # Don't destroy the PyCrust tab.
|
|
346
|
+
if self.buffer:
|
|
347
|
+
del self.buffers[self.buffer.id]
|
|
348
|
+
self.buffer = None # Do this before DeletePage().
|
|
349
|
+
self.notebook.DeletePage(selection)
|
|
350
|
+
|
|
351
|
+
def bufferNew(self):
|
|
352
|
+
"""Create new buffer."""
|
|
353
|
+
self.bufferCreate()
|
|
354
|
+
cancel = False
|
|
355
|
+
return cancel
|
|
356
|
+
|
|
357
|
+
def bufferOpen(self):
|
|
358
|
+
"""Open file in buffer."""
|
|
359
|
+
filedir = ''
|
|
360
|
+
if self.buffer and self.buffer.doc.filedir:
|
|
361
|
+
filedir = self.buffer.doc.filedir
|
|
362
|
+
result = openMultiple(directory=filedir)
|
|
363
|
+
for path in result.paths:
|
|
364
|
+
self.bufferCreate(path)
|
|
365
|
+
cancel = False
|
|
366
|
+
return cancel
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class EditorNotebook(wx.Notebook):
|
|
370
|
+
"""A notebook containing a page for each editor."""
|
|
371
|
+
|
|
372
|
+
def __init__(self, parent):
|
|
373
|
+
"""Create EditorNotebook instance."""
|
|
374
|
+
wx.Notebook.__init__(self, parent, id=-1, style=wx.CLIP_CHILDREN)
|
|
375
|
+
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging, id=self.GetId())
|
|
376
|
+
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged, id=self.GetId())
|
|
377
|
+
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
|
378
|
+
|
|
379
|
+
def OnIdle(self, event):
|
|
380
|
+
"""Event handler for idle time."""
|
|
381
|
+
self._updateTabText()
|
|
382
|
+
event.Skip()
|
|
383
|
+
|
|
384
|
+
def _updateTabText(self):
|
|
385
|
+
"""Show current buffer display name on all but first tab."""
|
|
386
|
+
size = 3
|
|
387
|
+
changed = ' **'
|
|
388
|
+
unchanged = ' --'
|
|
389
|
+
selection = self.GetSelection()
|
|
390
|
+
if selection < 1:
|
|
391
|
+
return
|
|
392
|
+
text = self.GetPageText(selection)
|
|
393
|
+
window = self.GetPage(selection)
|
|
394
|
+
if not window.editor:
|
|
395
|
+
return
|
|
396
|
+
if text.endswith(changed) or text.endswith(unchanged):
|
|
397
|
+
name = text[:-size]
|
|
398
|
+
else:
|
|
399
|
+
name = text
|
|
400
|
+
if name != window.editor.buffer.name:
|
|
401
|
+
text = window.editor.buffer.name
|
|
402
|
+
if window.editor.buffer.hasChanged():
|
|
403
|
+
if text.endswith(changed):
|
|
404
|
+
text = None
|
|
405
|
+
elif text.endswith(unchanged):
|
|
406
|
+
text = text[:-size] + changed
|
|
407
|
+
else:
|
|
408
|
+
text += changed
|
|
409
|
+
else:
|
|
410
|
+
if text.endswith(changed):
|
|
411
|
+
text = text[:-size] + unchanged
|
|
412
|
+
elif text.endswith(unchanged):
|
|
413
|
+
text = None
|
|
414
|
+
else:
|
|
415
|
+
text += unchanged
|
|
416
|
+
if text is not None:
|
|
417
|
+
self.SetPageText(selection, text)
|
|
418
|
+
self.Refresh() # Needed on Win98.
|
|
419
|
+
|
|
420
|
+
def OnPageChanging(self, event):
|
|
421
|
+
"""Page changing event handler."""
|
|
422
|
+
event.Skip()
|
|
423
|
+
|
|
424
|
+
def OnPageChanged(self, event):
|
|
425
|
+
"""Page changed event handler."""
|
|
426
|
+
new = event.GetSelection()
|
|
427
|
+
window = self.GetPage(new)
|
|
428
|
+
dispatcher.send(signal='EditorChange', sender=self,
|
|
429
|
+
editor=window.editor)
|
|
430
|
+
window.SetFocus()
|
|
431
|
+
event.Skip()
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
class EditorShellNotebookFrame(EditorNotebookFrame):
|
|
435
|
+
"""Frame containing a notebook containing EditorShellNotebooks."""
|
|
436
|
+
|
|
437
|
+
def __init__(self, parent=None, id=-1, title='PyAlaModeTest',
|
|
438
|
+
pos=wx.DefaultPosition, size=(600, 400),
|
|
439
|
+
style=wx.DEFAULT_FRAME_STYLE,
|
|
440
|
+
filename=None, singlefile=False):
|
|
441
|
+
"""Create EditorShellNotebookFrame instance."""
|
|
442
|
+
self._singlefile = singlefile
|
|
443
|
+
EditorNotebookFrame.__init__(self, parent, id, title, pos,
|
|
444
|
+
size, style, filename)
|
|
445
|
+
|
|
446
|
+
def _setup(self):
|
|
447
|
+
"""Setup prior to first buffer creation.
|
|
448
|
+
|
|
449
|
+
Called automatically by base class during init."""
|
|
450
|
+
if not self._singlefile:
|
|
451
|
+
self.notebook = EditorNotebook(parent=self)
|
|
452
|
+
|
|
453
|
+
def OnAbout(self, event):
|
|
454
|
+
"""Display an About window."""
|
|
455
|
+
title = 'About PyAlaModePlus'
|
|
456
|
+
text = 'Another fine, flaky program.'
|
|
457
|
+
dialog = wx.MessageDialog(self, text, title,
|
|
458
|
+
wx.OK | wx.ICON_INFORMATION)
|
|
459
|
+
dialog.ShowModal()
|
|
460
|
+
dialog.Destroy()
|
|
461
|
+
|
|
462
|
+
def bufferCreate(self, filename=None):
|
|
463
|
+
"""Create new buffer."""
|
|
464
|
+
if self._singlefile:
|
|
465
|
+
self.bufferDestroy()
|
|
466
|
+
notebook = EditorShellNotebook(parent=self,
|
|
467
|
+
filename=filename)
|
|
468
|
+
self.notebook = notebook
|
|
469
|
+
else:
|
|
470
|
+
notebook = EditorShellNotebook(parent=self.notebook,
|
|
471
|
+
filename=filename)
|
|
472
|
+
self.setEditor(notebook.editor)
|
|
473
|
+
if not self._singlefile:
|
|
474
|
+
self.notebook.AddPage(page=notebook, text=self.buffer.name,
|
|
475
|
+
select=True)
|
|
476
|
+
self.editor.setFocus()
|
|
477
|
+
|
|
478
|
+
def bufferDestroy(self):
|
|
479
|
+
"""Destroy the current buffer."""
|
|
480
|
+
if self.buffer:
|
|
481
|
+
self.editor = None
|
|
482
|
+
del self.buffers[self.buffer.id]
|
|
483
|
+
self.buffer = None # Do this before DeletePage().
|
|
484
|
+
if self._singlefile:
|
|
485
|
+
self.notebook.Destroy()
|
|
486
|
+
self.notebook = None
|
|
487
|
+
else:
|
|
488
|
+
selection = self.notebook.GetSelection()
|
|
489
|
+
## print("Destroy Selection:", selection)
|
|
490
|
+
self.notebook.DeletePage(selection)
|
|
491
|
+
|
|
492
|
+
def bufferNew(self):
|
|
493
|
+
"""Create new buffer."""
|
|
494
|
+
if self._singlefile and self.bufferHasChanged():
|
|
495
|
+
cancel = self.bufferSuggestSave()
|
|
496
|
+
if cancel:
|
|
497
|
+
return cancel
|
|
498
|
+
self.bufferCreate()
|
|
499
|
+
cancel = False
|
|
500
|
+
return cancel
|
|
501
|
+
|
|
502
|
+
def bufferOpen(self):
|
|
503
|
+
"""Open file in buffer."""
|
|
504
|
+
if self._singlefile and self.bufferHasChanged():
|
|
505
|
+
cancel = self.bufferSuggestSave()
|
|
506
|
+
if cancel:
|
|
507
|
+
return cancel
|
|
508
|
+
filedir = ''
|
|
509
|
+
if self.buffer and self.buffer.doc.filedir:
|
|
510
|
+
filedir = self.buffer.doc.filedir
|
|
511
|
+
if self._singlefile:
|
|
512
|
+
result = openSingle(directory=filedir)
|
|
513
|
+
if result.path:
|
|
514
|
+
self.bufferCreate(result.path)
|
|
515
|
+
else:
|
|
516
|
+
result = openMultiple(directory=filedir)
|
|
517
|
+
for path in result.paths:
|
|
518
|
+
self.bufferCreate(path)
|
|
519
|
+
cancel = False
|
|
520
|
+
return cancel
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
class EditorShellNotebook(wx.Notebook):
|
|
524
|
+
"""A notebook containing an editor page and a shell page."""
|
|
525
|
+
|
|
526
|
+
def __init__(self, parent, filename=None):
|
|
527
|
+
"""Create EditorShellNotebook instance."""
|
|
528
|
+
wx.Notebook.__init__(self, parent, id=-1)
|
|
529
|
+
usePanels = True
|
|
530
|
+
if usePanels:
|
|
531
|
+
editorparent = editorpanel = wx.Panel(self, -1)
|
|
532
|
+
shellparent = shellpanel = wx.Panel(self, -1)
|
|
533
|
+
else:
|
|
534
|
+
editorparent = self
|
|
535
|
+
shellparent = self
|
|
536
|
+
self.buffer = Buffer()
|
|
537
|
+
self.editor = Editor(parent=editorparent)
|
|
538
|
+
self.buffer.addEditor(self.editor)
|
|
539
|
+
self.buffer.open(filename)
|
|
540
|
+
self.shell = Shell(parent=shellparent, locals=self.buffer.interp.locals,
|
|
541
|
+
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER)
|
|
542
|
+
self.buffer.interp.locals.clear()
|
|
543
|
+
if usePanels:
|
|
544
|
+
self.AddPage(page=editorpanel, text='Editor', select=True)
|
|
545
|
+
self.AddPage(page=shellpanel, text='Shell')
|
|
546
|
+
# Setup sizers
|
|
547
|
+
editorsizer = wx.BoxSizer(wx.VERTICAL)
|
|
548
|
+
editorsizer.Add(self.editor.window, 1, wx.EXPAND)
|
|
549
|
+
editorpanel.SetSizer(editorsizer)
|
|
550
|
+
editorpanel.SetAutoLayout(True)
|
|
551
|
+
shellsizer = wx.BoxSizer(wx.VERTICAL)
|
|
552
|
+
shellsizer.Add(self.shell, 1, wx.EXPAND)
|
|
553
|
+
shellpanel.SetSizer(shellsizer)
|
|
554
|
+
shellpanel.SetAutoLayout(True)
|
|
555
|
+
else:
|
|
556
|
+
self.AddPage(page=self.editor.window, text='Editor', select=True)
|
|
557
|
+
self.AddPage(page=self.shell, text='Shell')
|
|
558
|
+
self.editor.setFocus()
|
|
559
|
+
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged, id=self.GetId())
|
|
560
|
+
|
|
561
|
+
def OnPageChanged(self, event):
|
|
562
|
+
"""Page changed event handler."""
|
|
563
|
+
selection = event.GetSelection()
|
|
564
|
+
if selection == 0:
|
|
565
|
+
self.editor.setFocus()
|
|
566
|
+
else:
|
|
567
|
+
self.shell.SetFocus()
|
|
568
|
+
event.Skip()
|
|
569
|
+
|
|
570
|
+
def SetFocus(self):
|
|
571
|
+
wx.Notebook.SetFocus(self)
|
|
572
|
+
selection = self.GetSelection()
|
|
573
|
+
if selection == 0:
|
|
574
|
+
self.editor.setFocus()
|
|
575
|
+
else:
|
|
576
|
+
self.shell.SetFocus()
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
class Editor:
|
|
580
|
+
"""Editor having an EditWindow."""
|
|
581
|
+
|
|
582
|
+
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
|
|
583
|
+
size=wx.DefaultSize,
|
|
584
|
+
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
|
|
585
|
+
"""Create Editor instance."""
|
|
586
|
+
self.window = EditWindow(self, parent, id, pos, size, style)
|
|
587
|
+
self.id = self.window.GetId()
|
|
588
|
+
self.buffer = None
|
|
589
|
+
# Assign handlers for keyboard events.
|
|
590
|
+
self.window.Bind(wx.EVT_CHAR, self.OnChar)
|
|
591
|
+
self.window.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
|
|
592
|
+
|
|
593
|
+
def _setBuffer(self, buffer, text):
|
|
594
|
+
"""Set the editor to a buffer. Private callback called by buffer."""
|
|
595
|
+
self.buffer = buffer
|
|
596
|
+
self.autoCompleteKeys = buffer.interp.getAutoCompleteKeys()
|
|
597
|
+
self.clearAll()
|
|
598
|
+
self.setText(text)
|
|
599
|
+
self.emptyUndoBuffer()
|
|
600
|
+
self.setSavePoint()
|
|
601
|
+
|
|
602
|
+
def destroy(self):
|
|
603
|
+
"""Destroy all editor objects."""
|
|
604
|
+
self.window.Destroy()
|
|
605
|
+
|
|
606
|
+
def clearAll(self):
|
|
607
|
+
self.window.ClearAll()
|
|
608
|
+
|
|
609
|
+
def emptyUndoBuffer(self):
|
|
610
|
+
self.window.EmptyUndoBuffer()
|
|
611
|
+
|
|
612
|
+
def getStatus(self):
|
|
613
|
+
"""Return (filepath, line, column) status tuple."""
|
|
614
|
+
if self.window:
|
|
615
|
+
pos = self.window.GetCurrentPos()
|
|
616
|
+
line = self.window.LineFromPosition(pos) + 1
|
|
617
|
+
col = self.window.GetColumn(pos)
|
|
618
|
+
if self.buffer:
|
|
619
|
+
name = self.buffer.doc.filepath or self.buffer.name
|
|
620
|
+
else:
|
|
621
|
+
name = ''
|
|
622
|
+
status = (name, line, col)
|
|
623
|
+
return status
|
|
624
|
+
else:
|
|
625
|
+
return ('', 0, 0)
|
|
626
|
+
|
|
627
|
+
def getText(self):
|
|
628
|
+
"""Return contents of editor."""
|
|
629
|
+
return self.window.GetText()
|
|
630
|
+
|
|
631
|
+
def hasChanged(self):
|
|
632
|
+
"""Return True if contents have changed."""
|
|
633
|
+
return self.window.GetModify()
|
|
634
|
+
|
|
635
|
+
def setFocus(self):
|
|
636
|
+
"""Set the input focus to the editor window."""
|
|
637
|
+
self.window.SetFocus()
|
|
638
|
+
|
|
639
|
+
def setSavePoint(self):
|
|
640
|
+
self.window.SetSavePoint()
|
|
641
|
+
|
|
642
|
+
def setText(self, text):
|
|
643
|
+
"""Set contents of editor."""
|
|
644
|
+
self.window.SetText(text)
|
|
645
|
+
|
|
646
|
+
def OnChar(self, event):
|
|
647
|
+
"""Keypress event handler.
|
|
648
|
+
|
|
649
|
+
Only receives an event if OnKeyDown calls event.Skip() for the
|
|
650
|
+
corresponding event."""
|
|
651
|
+
|
|
652
|
+
key = event.GetKeyCode()
|
|
653
|
+
if key in self.autoCompleteKeys:
|
|
654
|
+
# Usually the dot (period) key activates auto completion.
|
|
655
|
+
if self.window.AutoCompActive():
|
|
656
|
+
self.window.AutoCompCancel()
|
|
657
|
+
self.window.ReplaceSelection('')
|
|
658
|
+
self.window.AddText(chr(key))
|
|
659
|
+
text, pos = self.window.GetCurLine()
|
|
660
|
+
text = text[:pos]
|
|
661
|
+
if self.window.autoComplete:
|
|
662
|
+
self.autoCompleteShow(text)
|
|
663
|
+
elif key == ord('('):
|
|
664
|
+
# The left paren activates a call tip and cancels an
|
|
665
|
+
# active auto completion.
|
|
666
|
+
if self.window.AutoCompActive():
|
|
667
|
+
self.window.AutoCompCancel()
|
|
668
|
+
self.window.ReplaceSelection('')
|
|
669
|
+
self.window.AddText('(')
|
|
670
|
+
text, pos = self.window.GetCurLine()
|
|
671
|
+
text = text[:pos]
|
|
672
|
+
self.autoCallTipShow(text)
|
|
673
|
+
else:
|
|
674
|
+
# Allow the normal event handling to take place.
|
|
675
|
+
event.Skip()
|
|
676
|
+
|
|
677
|
+
def OnKeyDown(self, event):
|
|
678
|
+
"""Key down event handler."""
|
|
679
|
+
|
|
680
|
+
key = event.GetKeyCode()
|
|
681
|
+
# If the auto-complete window is up let it do its thing.
|
|
682
|
+
if self.window.AutoCompActive():
|
|
683
|
+
event.Skip()
|
|
684
|
+
return
|
|
685
|
+
controlDown = event.ControlDown()
|
|
686
|
+
altDown = event.AltDown()
|
|
687
|
+
shiftDown = event.ShiftDown()
|
|
688
|
+
# Let Ctrl-Alt-* get handled normally.
|
|
689
|
+
if controlDown and altDown:
|
|
690
|
+
event.Skip()
|
|
691
|
+
# Increase font size.
|
|
692
|
+
elif controlDown and key in (ord(']'),):
|
|
693
|
+
dispatcher.send(signal='FontIncrease')
|
|
694
|
+
# Decrease font size.
|
|
695
|
+
elif controlDown and key in (ord('['),):
|
|
696
|
+
dispatcher.send(signal='FontDecrease')
|
|
697
|
+
# Default font size.
|
|
698
|
+
elif controlDown and key in (ord('='),):
|
|
699
|
+
dispatcher.send(signal='FontDefault')
|
|
700
|
+
else:
|
|
701
|
+
event.Skip()
|
|
702
|
+
|
|
703
|
+
def autoCompleteShow(self, command):
|
|
704
|
+
"""Display auto-completion popup list."""
|
|
705
|
+
list = self.buffer.interp.getAutoCompleteList(command,
|
|
706
|
+
includeMagic=self.window.autoCompleteIncludeMagic,
|
|
707
|
+
includeSingle=self.window.autoCompleteIncludeSingle,
|
|
708
|
+
includeDouble=self.window.autoCompleteIncludeDouble)
|
|
709
|
+
if list:
|
|
710
|
+
options = ' '.join(list)
|
|
711
|
+
offset = 0
|
|
712
|
+
self.window.AutoCompShow(offset, options)
|
|
713
|
+
|
|
714
|
+
def autoCallTipShow(self, command):
|
|
715
|
+
"""Display argument spec and docstring in a popup window."""
|
|
716
|
+
if self.window.CallTipActive():
|
|
717
|
+
self.window.CallTipCancel()
|
|
718
|
+
(name, argspec, tip) = self.buffer.interp.getCallTip(command)
|
|
719
|
+
if tip:
|
|
720
|
+
dispatcher.send(signal='Shell.calltip', sender=self, calltip=tip)
|
|
721
|
+
if not self.window.autoCallTip:
|
|
722
|
+
return
|
|
723
|
+
startpos = self.window.GetCurrentPos()
|
|
724
|
+
if argspec:
|
|
725
|
+
self.window.AddText(argspec + ')')
|
|
726
|
+
endpos = self.window.GetCurrentPos()
|
|
727
|
+
self.window.SetSelection(startpos, endpos)
|
|
728
|
+
if tip:
|
|
729
|
+
tippos = startpos - (len(name) + 1)
|
|
730
|
+
fallback = startpos - self.GetColumn(startpos)
|
|
731
|
+
# In case there isn't enough room, only go back to the
|
|
732
|
+
# fallback.
|
|
733
|
+
tippos = max(tippos, fallback)
|
|
734
|
+
self.CallTipShow(tippos, tip)
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
class EditWindow(editwindow.EditWindow):
|
|
738
|
+
"""EditWindow based on StyledTextCtrl."""
|
|
739
|
+
|
|
740
|
+
def __init__(self, editor, parent, id=-1, pos=wx.DefaultPosition,
|
|
741
|
+
size=wx.DefaultSize,
|
|
742
|
+
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
|
|
743
|
+
"""Create EditWindow instance."""
|
|
744
|
+
editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
|
|
745
|
+
self.editor = editor
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
class DialogResults:
|
|
749
|
+
"""DialogResults class."""
|
|
750
|
+
|
|
751
|
+
def __init__(self, returned):
|
|
752
|
+
"""Create wrapper for results returned by dialog."""
|
|
753
|
+
self.returned = returned
|
|
754
|
+
self.positive = returned in (wx.ID_OK, wx.ID_YES)
|
|
755
|
+
self.text = self._asString()
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
def __repr__(self):
|
|
759
|
+
return str(self.__dict__)
|
|
760
|
+
|
|
761
|
+
def _asString(self):
|
|
762
|
+
returned = self.returned
|
|
763
|
+
if returned == wx.ID_OK:
|
|
764
|
+
return "Ok"
|
|
765
|
+
elif returned == wx.ID_CANCEL:
|
|
766
|
+
return "Cancel"
|
|
767
|
+
elif returned == wx.ID_YES:
|
|
768
|
+
return "Yes"
|
|
769
|
+
elif returned == wx.ID_NO:
|
|
770
|
+
return "No"
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
def fileDialog(parent=None, title='Open', directory='', filename='',
|
|
774
|
+
wildcard='All Files (*.*)|*.*',
|
|
775
|
+
style=wx.FD_OPEN | wx.FD_MULTIPLE):
|
|
776
|
+
"""File dialog wrapper function."""
|
|
777
|
+
dialog = wx.FileDialog(parent, title, directory, filename,
|
|
778
|
+
wildcard, style)
|
|
779
|
+
result = DialogResults(dialog.ShowModal())
|
|
780
|
+
if result.positive:
|
|
781
|
+
result.paths = dialog.GetPaths()
|
|
782
|
+
else:
|
|
783
|
+
result.paths = []
|
|
784
|
+
dialog.Destroy()
|
|
785
|
+
return result
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
def openSingle(parent=None, title='Open', directory='', filename='',
|
|
789
|
+
wildcard='All Files (*.*)|*.*', style=wx.FD_OPEN):
|
|
790
|
+
"""File dialog wrapper function."""
|
|
791
|
+
dialog = wx.FileDialog(parent, title, directory, filename,
|
|
792
|
+
wildcard, style)
|
|
793
|
+
result = DialogResults(dialog.ShowModal())
|
|
794
|
+
if result.positive:
|
|
795
|
+
result.path = dialog.GetPath()
|
|
796
|
+
else:
|
|
797
|
+
result.path = None
|
|
798
|
+
dialog.Destroy()
|
|
799
|
+
return result
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
def openMultiple(parent=None, title='Open', directory='', filename='',
|
|
803
|
+
wildcard='All Files (*.*)|*.*',
|
|
804
|
+
style=wx.FD_OPEN | wx.FD_MULTIPLE):
|
|
805
|
+
"""File dialog wrapper function."""
|
|
806
|
+
return fileDialog(parent, title, directory, filename, wildcard, style)
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
def saveSingle(parent=None, title='Save', directory='', filename='',
|
|
810
|
+
wildcard='All Files (*.*)|*.*',
|
|
811
|
+
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT):
|
|
812
|
+
"""File dialog wrapper function."""
|
|
813
|
+
dialog = wx.FileDialog(parent, title, directory, filename,
|
|
814
|
+
wildcard, style)
|
|
815
|
+
result = DialogResults(dialog.ShowModal())
|
|
816
|
+
if result.positive:
|
|
817
|
+
result.path = dialog.GetPath()
|
|
818
|
+
else:
|
|
819
|
+
result.path = None
|
|
820
|
+
dialog.Destroy()
|
|
821
|
+
return result
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
def directory(parent=None, message='Choose a directory', path='', style=0,
|
|
825
|
+
pos=wx.DefaultPosition, size=wx.DefaultSize):
|
|
826
|
+
"""Dir dialog wrapper function."""
|
|
827
|
+
dialog = wx.DirDialog(parent, message, path, style, pos, size)
|
|
828
|
+
result = DialogResults(dialog.ShowModal())
|
|
829
|
+
if result.positive:
|
|
830
|
+
result.path = dialog.GetPath()
|
|
831
|
+
else:
|
|
832
|
+
result.path = None
|
|
833
|
+
dialog.Destroy()
|
|
834
|
+
return result
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
def messageDialog(parent=None, message='', title='Message box',
|
|
838
|
+
style=wx.YES_NO | wx.CANCEL | wx.CENTRE | wx.ICON_QUESTION,
|
|
839
|
+
pos=wx.DefaultPosition):
|
|
840
|
+
"""Message dialog wrapper function."""
|
|
841
|
+
dialog = wx.MessageDialog(parent, message, title, style, pos)
|
|
842
|
+
result = DialogResults(dialog.ShowModal())
|
|
843
|
+
dialog.Destroy()
|
|
844
|
+
return result
|